diff hgext/mq.py @ 16101:20ad8f0512a2 stable

mq: restore _branchtags() fast path (issue3223) Since a5917346c72e, mq saves the nodeid of the first applied patch to cache/branchheads, which breaks the optimized cache handling introduced in fbf8320f25c8. The problem is the revision being committed is appended to mqrepo.applied after the commit succeeds, which means mqrepo._branchtags() performs a regular update and write the first applied patch to the branch cache. One solution is to set a context variable _committingpatch on the mqrepo while it is committing a patch and to take it in account when deciding to fast-path mqrepo._branchtags(). Not really elegant but it works. The changes to test-mq-caches.t reverse changes introduced by a5917346c72e. The cache should not have been updated with mq records. The changes to test-keyword.t are indirectly caused by a5917346c72e. Reported and analyzed by Yuya Nishihara <yuya@tcha.org> Notes: - qpush still makes a slow path _branchtags() call when checking heads. Maybe this can be optimized. - be careful when merging this patch in default as secretcommit() was renamed newcommit() right after the end of the code freeze.
author Patrick Mezard <patrick@mezard.eu>
date Tue, 07 Feb 2012 18:47:16 +0100
parents 24df9338aa01
children 50682c07a8d0 5de83d9ca79c
line wrap: on
line diff
--- a/hgext/mq.py	Tue Feb 07 18:47:13 2012 +0100
+++ b/hgext/mq.py	Tue Feb 07 18:47:16 2012 +0100
@@ -267,11 +267,15 @@
             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:
         if phase is not None:
             repo.ui.setconfig('phases', 'new-commit', phase)
         return repo.commit(*args, **kwargs)
     finally:
+        repo._committingpatch = False
         if phase is not None:
             repo.ui.restoreconfig(backup)
 
@@ -3254,16 +3258,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