diff hgext/mq.py @ 16102:50682c07a8d0

merge with stable
author Matt Mackall <mpm@selenic.com>
date Fri, 10 Feb 2012 13:47:57 -0600
parents 8af9e08a094f 20ad8f0512a2
children 004982e5d782
line wrap: on
line diff
--- a/hgext/mq.py	Wed Feb 08 17:45:10 2012 +0100
+++ b/hgext/mq.py	Fri Feb 10 13:47:57 2012 -0600
@@ -257,22 +257,28 @@
                 ci += 1
             del self.comments[ci]
 
-def newcommit(repo, *args, **kwargs):
+def newcommit(repo, phase, *args, **kwargs):
     """helper dedicated to ensure a commit respect mq.secret setting
 
     It should be used instead of repo.commit inside the mq source for operation
     creating new changeset.
     """
-    if not repo.ui.configbool('mq', 'secret', False):
-        return repo.commit(*args, **kwargs)
-
-    backup = repo.ui.backupconfig('phases', 'new-commit')
+    if phase is None:
+        if repo.ui.configbool('mq', 'secret', False):
+            phase = phases.secret
+    if phase is not None:
+        backup = repo.ui.backupconfig('phases', 'new-commit')
+    # Marking the repository as committing an mq patch can be used
+    # to optimize operations like _branchtags().
+    repo._committingpatch = True
     try:
-        # ensure we create a secret changeset
-        repo.ui.setconfig('phases', 'new-commit', phases.secret)
+        if phase is not None:
+            repo.ui.setconfig('phases', 'new-commit', phase)
         return repo.commit(*args, **kwargs)
     finally:
-        repo.ui.restoreconfig(backup)
+        repo._committingpatch = False
+        if phase is not None:
+            repo.ui.restoreconfig(backup)
 
 class queue(object):
     def __init__(self, ui, path, patchdir=None):
@@ -576,7 +582,7 @@
         ret = hg.merge(repo, rev)
         if ret:
             raise util.Abort(_("update returned %d") % ret)
-        n = newcommit(repo, ctx.description(), ctx.user(), force=True)
+        n = newcommit(repo, None, ctx.description(), ctx.user(), force=True)
         if n is None:
             raise util.Abort(_("repo commit failed"))
         try:
@@ -616,7 +622,7 @@
             # the first patch in the queue is never a merge patch
             #
             pname = ".hg.patches.merge.marker"
-            n = repo.commit('[mq]: merge marker', force=True)
+            n = newcommit(repo, None, '[mq]: merge marker', force=True)
             self.removeundo(repo)
             self.applied.append(statusentry(n, pname))
             self.applieddirty = True
@@ -747,8 +753,8 @@
 
             match = scmutil.matchfiles(repo, files or [])
             oldtip = repo['tip']
-            n = newcommit(repo, message, ph.user, ph.date, match=match,
-                             force=True)
+            n = newcommit(repo, None, message, ph.user, ph.date, match=match,
+                          force=True)
             if repo['tip'] == oldtip:
                 raise util.Abort(_("qpush exactly duplicates child changeset"))
             if n is None:
@@ -988,8 +994,8 @@
                 if util.safehasattr(msg, '__call__'):
                     msg = msg()
                 commitmsg = msg and msg or ("[mq]: %s" % patchfn)
-                n = newcommit(repo, commitmsg, user, date, match=match,
-                                 force=True)
+                n = newcommit(repo, None, commitmsg, user, date, match=match,
+                              force=True)
                 if n is None:
                     raise util.Abort(_("repo commit failed"))
                 try:
@@ -1540,15 +1546,11 @@
 
             try:
                 # might be nice to attempt to roll back strip after this
-                backup = repo.ui.backupconfig('phases', 'new-commit')
-                try:
-                    # Ensure we create a new changeset in the same phase than
-                    # the old one.
-                    repo.ui.setconfig('phases', 'new-commit', oldphase)
-                    n = repo.commit(message, user, ph.date, match=match,
-                                    force=True)
-                finally:
-                    repo.ui.restoreconfig(backup)
+
+                # Ensure we create a new changeset in the same phase than
+                # the old one.
+                n = newcommit(repo, oldphase, message, user, ph.date,
+                              match=match, force=True)
                 # only write patch after a successful commit
                 patchf.close()
                 self.applied.append(statusentry(n, patchfn))
@@ -3257,16 +3259,20 @@
 
         def _branchtags(self, partial, lrev):
             q = self.mq
+            cl = self.changelog
+            qbase = None
             if not q.applied:
-                return super(mqrepo, self)._branchtags(partial, lrev)
-
-            cl = self.changelog
-            qbasenode = q.applied[0].node
-            try:
-                qbase = cl.rev(qbasenode)
-            except error.LookupError:
-                self.ui.warn(_('mq status file refers to unknown node %s\n')
-                             % short(qbasenode))
+                if getattr(self, '_committingpatch', False):
+                    # Committing a new patch, must be tip
+                    qbase = len(cl) - 1
+            else:
+                qbasenode = q.applied[0].node
+                try:
+                    qbase = cl.rev(qbasenode)
+                except error.LookupError:
+                    self.ui.warn(_('mq status file refers to unknown node %s\n')
+                                 % short(qbasenode))
+            if qbase is None:
                 return super(mqrepo, self)._branchtags(partial, lrev)
 
             start = lrev + 1