diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -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): diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -450,8 +450,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()