hgext/mq.py
branchstable
changeset 19067 292cd385856d
parent 19064 743daa601445
child 19212 d0ba7022c13b
equal deleted inserted replaced
18875:e9662c24f946 19067:292cd385856d
   280         if repo.ui.configbool('mq', 'secret', False):
   280         if repo.ui.configbool('mq', 'secret', False):
   281             phase = phases.secret
   281             phase = phases.secret
   282     if phase is not None:
   282     if phase is not None:
   283         backup = repo.ui.backupconfig('phases', 'new-commit')
   283         backup = repo.ui.backupconfig('phases', 'new-commit')
   284     # Marking the repository as committing an mq patch can be used
   284     # Marking the repository as committing an mq patch can be used
   285     # to optimize operations like _branchtags().
   285     # to optimize operations like branchtags().
   286     repo._committingpatch = True
   286     repo._committingpatch = True
   287     try:
   287     try:
   288         if phase is not None:
   288         if phase is not None:
   289             repo.ui.setconfig('phases', 'new-commit', phase)
   289             repo.ui.setconfig('phases', 'new-commit', phase)
   290         return repo.commit(*args, **kwargs)
   290         return repo.commit(*args, **kwargs)
   295 
   295 
   296 class AbortNoCleanup(error.Abort):
   296 class AbortNoCleanup(error.Abort):
   297     pass
   297     pass
   298 
   298 
   299 class queue(object):
   299 class queue(object):
   300     def __init__(self, ui, path, patchdir=None):
   300     def __init__(self, ui, baseui, path, patchdir=None):
   301         self.basepath = path
   301         self.basepath = path
   302         try:
   302         try:
   303             fh = open(os.path.join(path, 'patches.queue'))
   303             fh = open(os.path.join(path, 'patches.queue'))
   304             cur = fh.read().rstrip()
   304             cur = fh.read().rstrip()
   305             fh.close()
   305             fh.close()
   310         except IOError:
   310         except IOError:
   311             curpath = os.path.join(path, 'patches')
   311             curpath = os.path.join(path, 'patches')
   312         self.path = patchdir or curpath
   312         self.path = patchdir or curpath
   313         self.opener = scmutil.opener(self.path)
   313         self.opener = scmutil.opener(self.path)
   314         self.ui = ui
   314         self.ui = ui
       
   315         self.baseui = baseui
   315         self.applieddirty = False
   316         self.applieddirty = False
   316         self.seriesdirty = False
   317         self.seriesdirty = False
   317         self.added = []
   318         self.added = []
   318         self.seriespath = "series"
   319         self.seriespath = "series"
   319         self.statuspath = "status"
   320         self.statuspath = "status"
  1569 
  1570 
  1570             m = list(mm)
  1571             m = list(mm)
  1571             r = list(dd)
  1572             r = list(dd)
  1572             a = list(aa)
  1573             a = list(aa)
  1573 
  1574 
  1574             # create 'match' that includes the files to be recommited.
  1575             # create 'match' that includes the files to be recommitted.
  1575             # apply matchfn via repo.status to ensure correct case handling.
  1576             # apply matchfn via repo.status to ensure correct case handling.
  1576             cm, ca, cr, cd = repo.status(patchparent, match=matchfn)[:4]
  1577             cm, ca, cr, cd = repo.status(patchparent, match=matchfn)[:4]
  1577             allmatches = set(cm + ca + cr + cd)
  1578             allmatches = set(cm + ca + cr + cd)
  1578             refreshchanges = [x.intersection(allmatches) for x in (mm, aa, dd)]
  1579             refreshchanges = [x.intersection(allmatches) for x in (mm, aa, dd)]
  1579 
  1580 
  1772     def issaveline(self, l):
  1773     def issaveline(self, l):
  1773         if l.name == '.hg.patches.save.line':
  1774         if l.name == '.hg.patches.save.line':
  1774             return True
  1775             return True
  1775 
  1776 
  1776     def qrepo(self, create=False):
  1777     def qrepo(self, create=False):
  1777         ui = self.ui.copy()
  1778         ui = self.baseui.copy()
  1778         ui.setconfig('paths', 'default', '', overlay=False)
       
  1779         ui.setconfig('paths', 'default-push', '', overlay=False)
       
  1780         if create or os.path.isdir(self.join(".hg")):
  1779         if create or os.path.isdir(self.join(".hg")):
  1781             return hg.repository(ui, path=self.path, create=create)
  1780             return hg.repository(ui, path=self.path, create=create)
  1782 
  1781 
  1783     def restore(self, repo, rev, delete=None, qupdate=None):
  1782     def restore(self, repo, rev, delete=None, qupdate=None):
  1784         desc = repo[rev].description().strip()
  1783         desc = repo[rev].description().strip()
  2759         else:
  2758         else:
  2760             newpath, i = lastsavename(q.path)
  2759             newpath, i = lastsavename(q.path)
  2761         if not newpath:
  2760         if not newpath:
  2762             ui.warn(_("no saved queues found, please use -n\n"))
  2761             ui.warn(_("no saved queues found, please use -n\n"))
  2763             return 1
  2762             return 1
  2764         mergeq = queue(ui, repo.path, newpath)
  2763         mergeq = queue(ui, repo.baseui, repo.path, newpath)
  2765         ui.warn(_("merging with queue at: %s\n") % mergeq.path)
  2764         ui.warn(_("merging with queue at: %s\n") % mergeq.path)
  2766     ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
  2765     ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
  2767                  mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
  2766                  mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
  2768                  exact=opts.get('exact'), nobackup=opts.get('no_backup'),
  2767                  exact=opts.get('exact'), nobackup=opts.get('no_backup'),
  2769                  keepchanges=opts.get('keep_changes'))
  2768                  keepchanges=opts.get('keep_changes'))
  2793     Return 0 on success.
  2792     Return 0 on success.
  2794     """
  2793     """
  2795     opts = fixkeepchangesopts(ui, opts)
  2794     opts = fixkeepchangesopts(ui, opts)
  2796     localupdate = True
  2795     localupdate = True
  2797     if opts.get('name'):
  2796     if opts.get('name'):
  2798         q = queue(ui, repo.path, repo.join(opts.get('name')))
  2797         q = queue(ui, repo.baseui, repo.path, repo.join(opts.get('name')))
  2799         ui.warn(_('using patch queue: %s\n') % q.path)
  2798         ui.warn(_('using patch queue: %s\n') % q.path)
  2800         localupdate = False
  2799         localupdate = False
  2801     else:
  2800     else:
  2802         q = repo.mq
  2801         q = repo.mq
  2803     ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
  2802     ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
  3035     revs = sorted(rootnodes)
  3034     revs = sorted(rootnodes)
  3036     if update and opts.get('keep'):
  3035     if update and opts.get('keep'):
  3037         wlock = repo.wlock()
  3036         wlock = repo.wlock()
  3038         try:
  3037         try:
  3039             urev = repo.mq.qparents(repo, revs[0])
  3038             urev = repo.mq.qparents(repo, revs[0])
  3040             repo.dirstate.rebuild(urev, repo[urev].manifest())
  3039             uctx = repo[urev]
       
  3040 
       
  3041             # only reset the dirstate for files that would actually change
       
  3042             # between the working context and uctx
       
  3043             descendantrevs = repo.revs("%s::." % uctx.rev())
       
  3044             changedfiles = []
       
  3045             for rev in descendantrevs:
       
  3046                 # blindly reset the files, regardless of what actually changed
       
  3047                 changedfiles.extend(repo[rev].files())
       
  3048 
       
  3049             # reset files that only changed in the dirstate too
       
  3050             dirstate = repo.dirstate
       
  3051             dirchanges = [f for f in dirstate if dirstate[f] != 'n']
       
  3052             changedfiles.extend(dirchanges)
       
  3053 
       
  3054             repo.dirstate.rebuild(urev, uctx.manifest(), changedfiles)
  3041             repo.dirstate.write()
  3055             repo.dirstate.write()
  3042             update = False
  3056             update = False
  3043         finally:
  3057         finally:
  3044             wlock.release()
  3058             wlock.release()
  3045 
  3059 
  3396 
  3410 
  3397 def reposetup(ui, repo):
  3411 def reposetup(ui, repo):
  3398     class mqrepo(repo.__class__):
  3412     class mqrepo(repo.__class__):
  3399         @util.propertycache
  3413         @util.propertycache
  3400         def mq(self):
  3414         def mq(self):
  3401             return queue(self.ui, self.path)
  3415             return queue(self.ui, self.baseui, self.path)
  3402 
  3416 
  3403         def abortifwdirpatched(self, errmsg, force=False):
  3417         def abortifwdirpatched(self, errmsg, force=False):
  3404             if self.mq.applied and not force:
  3418             if self.mq.applied and not force:
  3405                 parents = self.dirstate.parents()
  3419                 parents = self.dirstate.parents()
  3406                 patches = [s.node for s in self.mq.applied]
  3420                 patches = [s.node for s in self.mq.applied]
  3452             except error.LookupError:
  3466             except error.LookupError:
  3453                 self.ui.warn(_('mq status file refers to unknown node %s\n')
  3467                 self.ui.warn(_('mq status file refers to unknown node %s\n')
  3454                              % short(mqtags[-1][0]))
  3468                              % short(mqtags[-1][0]))
  3455                 return result
  3469                 return result
  3456 
  3470 
       
  3471             # do not add fake tags for filtered revisions
       
  3472             included = self.changelog.hasnode
       
  3473             mqtags = [mqt for mqt in mqtags if included(mqt[0])]
       
  3474             if not mqtags:
       
  3475                 return result
       
  3476 
  3457             mqtags.append((mqtags[-1][0], 'qtip'))
  3477             mqtags.append((mqtags[-1][0], 'qtip'))
  3458             mqtags.append((mqtags[0][0], 'qbase'))
  3478             mqtags.append((mqtags[0][0], 'qbase'))
  3459             mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
  3479             mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
  3460             tags = result[0]
  3480             tags = result[0]
  3461             for patch in mqtags:
  3481             for patch in mqtags: