[PATCH 2 of 2 STABLE] mq: restore _branchtags() fast path (issue3223)

Patrick Mezard patrick at mezard.eu
Tue Feb 7 11:54:13 CST 2012


# HG changeset patch
# User Patrick Mezard <patrick at mezard.eu>
# Date 1328636836 -3600
# Branch stable
# Node ID d29fd9d06a8e4c2ebadabd9c5c5c715b90957980
# Parent  196141af90f59bdf05681481e2c5bc6439129708
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 at 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.

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -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
diff --git a/tests/test-keyword.t b/tests/test-keyword.t
--- a/tests/test-keyword.t
+++ b/tests/test-keyword.t
@@ -556,7 +556,6 @@
 Commit and show expansion in original and copy
 
   $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user at example.com>'
-  invalidating branch cache (tip differs)
   c
    c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
   overwriting c expanding keywords
diff --git a/tests/test-mq-caches.t b/tests/test-mq-caches.t
--- a/tests/test-mq-caches.t
+++ b/tests/test-mq-caches.t
@@ -29,16 +29,14 @@
   $ hg qnew -d '0 0' p1
   $ show_branch_cache
   tip: 0
-  d986d5caac23a7d44a46efc0ddaf5eb9665844cf 0
-  d986d5caac23a7d44a46efc0ddaf5eb9665844cf default
+  No branch cache
 
   $ echo > pfile
   $ hg add pfile
   $ hg qrefresh -m 'patch 1'
   $ show_branch_cache
   tip: 0
-  a7977e38ed2c2942fa6c278030badfef3d180979 0
-  a7977e38ed2c2942fa6c278030badfef3d180979 default
+  No branch cache
 
 some regular revisions
 
@@ -67,8 +65,8 @@
   now at: p1
   $ show_branch_cache
   tip: 2
-  982611f6955f9c48d3365decea203217c945ef0d 2
-  982611f6955f9c48d3365decea203217c945ef0d bar
+  c229711f16da3d7591f89b1b8d963b79bda22714 1
+  c229711f16da3d7591f89b1b8d963b79bda22714 bar
   dc25e3827021582e979f600811852e36cbe57341 foo
 
   $ hg qnew -d '0 0' p2
@@ -77,8 +75,8 @@
   $ hg qrefresh -m 'patch 2'
   $ show_branch_cache 1
   tip: 3
-  982611f6955f9c48d3365decea203217c945ef0d 2
-  982611f6955f9c48d3365decea203217c945ef0d bar
+  c229711f16da3d7591f89b1b8d963b79bda22714 1
+  c229711f16da3d7591f89b1b8d963b79bda22714 bar
   dc25e3827021582e979f600811852e36cbe57341 foo
   branch foo: 3
   branch bar: 2
@@ -121,6 +119,6 @@
   now at: p2
   $ show_branch_cache
   tip: 3
-  3fe2e3b237359b5c55cec6ed172ac41d3850fade 1
-  3fe2e3b237359b5c55cec6ed172ac41d3850fade foo
+  dc25e3827021582e979f600811852e36cbe57341 0
+  dc25e3827021582e979f600811852e36cbe57341 foo
 


More information about the Mercurial-devel mailing list