shortest: cache disambiguation revset
This makes it actually useful. In compared the time in my hg repo with
69.6k revisions and with a disambiguation revset of "not public()"
that matches 563 visible revisions. I ran "time hg log -T
'{shortest(node1,)}' -r 0:1000" (no revisions within the revset in
that revision range). Before this patch, it took 57s and after it took
0.7s.
Differential Revision: https://phab.mercurial-scm.org/D4039
--- a/mercurial/scmutil.py Fri Jul 20 14:36:42 2018 -0700
+++ b/mercurial/scmutil.py Tue Apr 17 11:16:59 2018 -0700
@@ -462,8 +462,12 @@
repo.changelog.rev(node) # make sure node isn't filtered
return node
-def shortesthexnodeidprefix(repo, node, minlength=1):
- """Find the shortest unambiguous prefix that matches hexnode."""
+def shortesthexnodeidprefix(repo, node, minlength=1, cache=None):
+ """Find the shortest unambiguous prefix that matches hexnode.
+
+ If "cache" is not None, it must be a dictionary that can be used for
+ caching between calls to this method.
+ """
# _partialmatch() of filtered changelog could take O(len(repo)) time,
# which would be unacceptably slow. so we look for hash collision in
# unfiltered space, which means some hashes may be slightly longer.
@@ -491,7 +495,13 @@
revset = repo.ui.config('experimental', 'revisions.disambiguatewithin')
if revset:
- revs = repo.anyrevs([revset], user=True)
+ revs = None
+ if cache is not None:
+ revs = cache.get('disambiguationrevset')
+ if revs is None:
+ revs = repo.anyrevs([revset], user=True)
+ if cache is not None:
+ cache['disambiguationrevset'] = revs
if cl.rev(node) in revs:
hexnode = hex(node)
for length in range(minlength, len(hexnode) + 1):
--- a/mercurial/templatefuncs.py Fri Jul 20 14:36:42 2018 -0700
+++ b/mercurial/templatefuncs.py Tue Apr 17 11:16:59 2018 -0700
@@ -596,7 +596,7 @@
yield sep
yield argstr
-@templatefunc('shortest(node, minlength=4)', requires={'repo'})
+@templatefunc('shortest(node, minlength=4)', requires={'repo', 'cache'})
def shortest(context, mapping, args):
"""Obtain the shortest representation of
a node."""
@@ -629,8 +629,9 @@
return hexnode
if not node:
return hexnode
+ cache = context.resource(mapping, 'cache')
try:
- return scmutil.shortesthexnodeidprefix(repo, node, minlength)
+ return scmutil.shortesthexnodeidprefix(repo, node, minlength, cache)
except error.RepoLookupError:
return hexnode