Patchwork [4,of,6,RFC] destutil: use cached branch information instead of query for efficiency

mail settings
Submitter Katsunori FUJIWARA
Date Feb. 24, 2016, 2:17 p.m.
Message ID <54683cfda6e09c5502ad.1456323432@feefifofum>
Download mbox | patch
Permalink /patch/13341/
State Accepted
Headers show


Katsunori FUJIWARA - Feb. 24, 2016, 2:17 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <>
# Date 1456322433 -32400
#      Wed Feb 24 23:00:33 2016 +0900
# Node ID 54683cfda6e09c5502ad133d5a023929531a6b8b
# Parent  5c1d28233fd5ad7a419a0e4fa6f15e5b3e47a3d2
destutil: use cached branch information instead of query for efficiency

Before this patch, calculation of "the tipmost branch head on current
branch" uses revset query "max(.::(head() and branch(BRANCH)))", but
this isn't efficiency, because:

  - head() predicate lists up heads on all branches, but
  - branch() predicate eliminates heads on other branches

In addition to it, without "literal:" prefix for branch name,
branch(BRANCH) tries to (1) look up BRANCH in "repo.branchmap()" and
(2) look up BRANCH as symbol name again, if there is no branch
matching against BRANCH. The latter looking up is obviously redundant.

This patch uses repo.branchheads(closed=True) to get all branch heads
on specified branch instead of "head() and branch(BRANCH)" revset
query part.

This patch also makes catching RepoLookupError meaningless, because it
is only raised by revset predicate "branch()". But "currentbranch in
repo.branchmap()" can detect whether currentbranch actually exists or

Therefore, this patch replaces try/except for RepoLookupError by
if/else for "currentbranch in repo.branchmap()".


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -92,12 +92,13 @@  def _destupdatebranch(repo, clean, check
     wc = repo[None]
     movemark = node = None
     currentbranch = wc.branch()
-    try:
-        node = repo.revs('max(.::(head() and branch(%s)))'
-                         , currentbranch).first()
+    if currentbranch in repo.branchmap():
+        heads = repo.branchheads(currentbranch, closed=True)
+        if heads:
+            node = repo.revs('max(.::(%ln))', heads).first()
         if bookmarks.isactivewdirparent(repo):
             movemark = repo['.'].node()
-    except error.RepoLookupError:
+    else:
         if currentbranch == 'default': # no default branch!
             node = repo.lookup('tip') # update to tip