shortest: move revnum-disambiguation out of revlog
I want to be able to change how we disambiguate and I think having
revlog.shortest() worry only about finding a prefix that's unambiguous
among nodeids makes more sense.
This slows down `hg log -T '{shortest(node,1)}\n'` from 4.0s to 4.1s.
Differential Revision: https://phab.mercurial-scm.org/D3502
--- a/mercurial/revlog.py Thu May 03 15:25:16 2018 -0700
+++ b/mercurial/revlog.py Thu May 03 15:57:12 2018 -0700
@@ -1502,18 +1502,6 @@
def shortest(self, node, minlength=1):
"""Find the shortest unambiguous prefix that matches node."""
- def isrev(prefix):
- try:
- i = int(prefix)
- # if we are a pure int, then starting with zero will not be
- # confused as a rev; or, obviously, if the int is larger
- # than the value of the tip rev
- if prefix[0] == '0' or i > len(self):
- return False
- return True
- except ValueError:
- return False
-
def isvalid(prefix):
try:
node = self._partialmatch(prefix)
@@ -1532,9 +1520,10 @@
hexnode = hex(node)
def disambiguate(hexnode, minlength):
+ """Disambiguate against wdirid."""
for length in range(minlength, 41):
prefix = hexnode[:length]
- if not isrev(prefix) and not maybewdir(prefix):
+ if not maybewdir(prefix):
return prefix
if not getattr(self, 'filteredrevs', None):
--- a/mercurial/scmutil.py Thu May 03 15:25:16 2018 -0700
+++ b/mercurial/scmutil.py Thu May 03 15:57:12 2018 -0700
@@ -449,8 +449,30 @@
# _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.
+ cl = repo.unfiltered().changelog
+
+ def isrev(prefix):
+ try:
+ i = int(prefix)
+ # if we are a pure int, then starting with zero will not be
+ # confused as a rev; or, obviously, if the int is larger
+ # than the value of the tip rev
+ if prefix[0] == '0' or i > len(cl):
+ return False
+ return True
+ except ValueError:
+ return False
+
+ def disambiguate(prefix):
+ """Disambiguate against revnums."""
+ hexnode = hex(node)
+ for length in range(len(prefix), 41):
+ prefix = hexnode[:length]
+ if not isrev(prefix):
+ return prefix
+
try:
- return repo.unfiltered().changelog.shortest(node, minlength)
+ return disambiguate(cl.shortest(node, minlength))
except error.LookupError:
raise error.RepoLookupError()