hgext/mq.py
changeset 2874 3d6efcbbd1c9
parent 2873 4ec58b157265
child 2882 c2932ad5476a
equal deleted inserted replaced
2873:4ec58b157265 2874:3d6efcbbd1c9
   531             pp = repo.dirstate.parents()
   531             pp = repo.dirstate.parents()
   532             if top not in pp:
   532             if top not in pp:
   533                 raise util.Abort(_("queue top not at same revision as working directory"))
   533                 raise util.Abort(_("queue top not at same revision as working directory"))
   534             return top
   534             return top
   535         return None
   535         return None
   536     def check_localchanges(self, repo):
   536     def check_localchanges(self, repo, force=False, refresh=True):
   537         (c, a, r, d, u) = repo.changes(None, None)
   537         m, a, r, d = repo.status()[:4]
   538         if c or a or d or r:
   538         if m or a or r or d:
   539             raise util.Abort(_("local changes found, refresh first"))
   539             if not force:
       
   540                 if refresh:
       
   541                     raise util.Abort(_("local changes found, refresh first"))
       
   542                 else:
       
   543                     raise util.Abort(_("local changes found"))
       
   544         return m, a, r, d
   540     def new(self, repo, patch, msg=None, force=None):
   545     def new(self, repo, patch, msg=None, force=None):
   541         if os.path.exists(self.join(patch)):
   546         if os.path.exists(self.join(patch)):
   542             raise util.Abort(_('patch "%s" already exists') % patch)
   547             raise util.Abort(_('patch "%s" already exists') % patch)
   543         commitfiles = []
   548         m, a, r, d = self.check_localchanges(repo, force)
   544         (c, a, r, d, u) = repo.changes(None, None)
   549         commitfiles = m + a + r
   545         if c or a or d or r:
       
   546             if not force:
       
   547                 raise util.Abort(_("local changes found, refresh first"))
       
   548             commitfiles = c + a + r
       
   549         self.check_toppatch(repo)
   550         self.check_toppatch(repo)
   550         wlock = repo.wlock()
   551         wlock = repo.wlock()
   551         insert = self.full_series_end()
   552         insert = self.full_series_end()
   552         if msg:
   553         if msg:
   553             n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True,
   554             n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True,
   657         # TODO delete the undo files, and handle undo of merge sets
   658         # TODO delete the undo files, and handle undo of merge sets
   658         pp = chlog.parents(rev)
   659         pp = chlog.parents(rev)
   659         revnum = chlog.rev(rev)
   660         revnum = chlog.rev(rev)
   660 
   661 
   661         if update:
   662         if update:
   662             (c, a, r, d, u) = repo.changes(None, None)
   663             self.check_localchanges(repo, refresh=False)
   663             if c or a or d or r:
       
   664                 raise util.Abort(_("local changes found"))
       
   665             urev = self.qparents(repo, rev)
   664             urev = self.qparents(repo, rev)
   666             hg.clean(repo, urev, wlock=wlock)
   665             hg.clean(repo, urev, wlock=wlock)
   667             repo.dirstate.write()
   666             repo.dirstate.write()
   668 
   667 
   669         # save is a list of all the branches we are truncating away
   668         # save is a list of all the branches we are truncating away
   897         if update:
   896         if update:
   898             top = self.check_toppatch(repo)
   897             top = self.check_toppatch(repo)
   899             qp = self.qparents(repo, rev)
   898             qp = self.qparents(repo, rev)
   900             changes = repo.changelog.read(qp)
   899             changes = repo.changelog.read(qp)
   901             mmap = repo.manifest.read(changes[0])
   900             mmap = repo.manifest.read(changes[0])
   902             (c, a, r, d, u) = repo.changes(qp, top)
   901             m, a, r, d, u = repo.status(qp, top)[:5]
   903             if d:
   902             if d:
   904                 raise util.Abort("deletions found between repo revs")
   903                 raise util.Abort("deletions found between repo revs")
   905             for f in c:
   904             for f in m:
   906                 getfile(f, mmap[f])
   905                 getfile(f, mmap[f])
   907             for f in r:
   906             for f in r:
   908                 getfile(f, mmap[f])
   907                 getfile(f, mmap[f])
   909                 util.set_exec(repo.wjoin(f), mmap.execf(f))
   908                 util.set_exec(repo.wjoin(f), mmap.execf(f))
   910             repo.dirstate.update(c + r, 'n')
   909             repo.dirstate.update(m + r, 'n')
   911             for f in a:
   910             for f in a:
   912                 try: os.unlink(repo.wjoin(f))
   911                 try: os.unlink(repo.wjoin(f))
   913                 except: raise
   912                 except: raise
   914                 try: os.removedirs(os.path.dirname(repo.wjoin(f)))
   913                 try: os.removedirs(os.path.dirname(repo.wjoin(f)))
   915                 except: pass
   914                 except: pass
   968             #
   967             #
   969             # in short mode, we only diff the files included in the
   968             # in short mode, we only diff the files included in the
   970             # patch already
   969             # patch already
   971             #
   970             #
   972             # this should really read:
   971             # this should really read:
   973             #(cc, dd, aa, aa2, uu) = repo.changes(tip, patchparent)
   972             #   mm, dd, aa, aa2, uu = repo.status(tip, patchparent)[:5]
   974             # but we do it backwards to take advantage of manifest/chlog
   973             # but we do it backwards to take advantage of manifest/chlog
   975             # caching against the next repo.changes call
   974             # caching against the next repo.status call
   976             #
   975             #
   977             (cc, aa, dd, aa2, uu) = repo.changes(patchparent, tip)
   976             mm, aa, dd, aa2, uu = repo.status(patchparent, tip)[:5]
   978             if short:
   977             if short:
   979                 filelist = cc + aa + dd
   978                 filelist = mm + aa + dd
   980             else:
   979             else:
   981                 filelist = None
   980                 filelist = None
   982             (c, a, r, d, u) = repo.changes(None, None, filelist)
   981             m, a, r, d, u = repo.status(files=filelist)[:5]
   983 
   982 
   984             # we might end up with files that were added between tip and
   983             # we might end up with files that were added between tip and
   985             # the dirstate parent, but then changed in the local dirstate.
   984             # the dirstate parent, but then changed in the local dirstate.
   986             # in this case, we want them to only show up in the added section
   985             # in this case, we want them to only show up in the added section
   987             for x in c:
   986             for x in m:
   988                 if x not in aa:
   987                 if x not in aa:
   989                     cc.append(x)
   988                     mm.append(x)
   990             # we might end up with files added by the local dirstate that
   989             # we might end up with files added by the local dirstate that
   991             # were deleted by the patch.  In this case, they should only
   990             # were deleted by the patch.  In this case, they should only
   992             # show up in the changed section.
   991             # show up in the changed section.
   993             for x in a:
   992             for x in a:
   994                 if x in dd:
   993                 if x in dd:
   995                     del dd[dd.index(x)]
   994                     del dd[dd.index(x)]
   996                     cc.append(x)
   995                     mm.append(x)
   997                 else:
   996                 else:
   998                     aa.append(x)
   997                     aa.append(x)
   999             # make sure any files deleted in the local dirstate
   998             # make sure any files deleted in the local dirstate
  1000             # are not in the add or change column of the patch
   999             # are not in the add or change column of the patch
  1001             forget = []
  1000             forget = []
  1002             for x in d + r:
  1001             for x in d + r:
  1003                 if x in aa:
  1002                 if x in aa:
  1004                     del aa[aa.index(x)]
  1003                     del aa[aa.index(x)]
  1005                     forget.append(x)
  1004                     forget.append(x)
  1006                     continue
  1005                     continue
  1007                 elif x in cc:
  1006                 elif x in mm:
  1008                     del cc[cc.index(x)]
  1007                     del mm[mm.index(x)]
  1009                 dd.append(x)
  1008                 dd.append(x)
  1010 
  1009 
  1011             c = list(util.unique(cc))
  1010             m = list(util.unique(mm))
  1012             r = list(util.unique(dd))
  1011             r = list(util.unique(dd))
  1013             a = list(util.unique(aa))
  1012             a = list(util.unique(aa))
  1014             filelist = list(util.unique(c + r + a ))
  1013             filelist = list(util.unique(m + r + a))
  1015             self.printdiff(repo, patchparent, files=filelist,
  1014             self.printdiff(repo, patchparent, files=filelist,
  1016                            changes=(c, a, r, [], u), fp=patchf)
  1015                            changes=(m, a, r, [], u), fp=patchf)
  1017             patchf.close()
  1016             patchf.close()
  1018 
  1017 
  1019             changes = repo.changelog.read(tip)
  1018             changes = repo.changelog.read(tip)
  1020             repo.dirstate.setparents(*cparents)
  1019             repo.dirstate.setparents(*cparents)
  1021             repo.dirstate.update(a, 'a')
  1020             repo.dirstate.update(a, 'a')
  1022             repo.dirstate.update(r, 'r')
  1021             repo.dirstate.update(r, 'r')
  1023             repo.dirstate.update(c, 'n')
  1022             repo.dirstate.update(m, 'n')
  1024             repo.dirstate.forget(forget)
  1023             repo.dirstate.forget(forget)
  1025 
  1024 
  1026             if not msg:
  1025             if not msg:
  1027                 if not message:
  1026                 if not message:
  1028                     message = "patch queue: %s\n" % patch
  1027                     message = "patch queue: %s\n" % patch