# HG changeset patch # User Patrick Mezard # Date 2012-02-07 17:47:16 # Node ID 20ad8f0512a2ea61a019a02c1ffd05a8f6e770f7 # Parent 24df9338aa01e6eab2ec9e729e80985f65436a42 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 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 @@ def secretcommit(repo, phase, *args, **k 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 reposetup(ui, repo): 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 @@ Copy and show added kwfiles Commit and show expansion in original and copy $ hg --debug commit -ma2c -d '1 0' -u 'User Name ' - 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 @@ mq patch on an empty repo $ 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 @@ add some mq patches 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 @@ add some mq patches $ 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 @@ detect an invalid cache now at: p2 $ show_branch_cache tip: 3 - 3fe2e3b237359b5c55cec6ed172ac41d3850fade 1 - 3fe2e3b237359b5c55cec6ed172ac41d3850fade foo + dc25e3827021582e979f600811852e36cbe57341 0 + dc25e3827021582e979f600811852e36cbe57341 foo