diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -587,6 +587,9 @@ coreconfigitem('experimental', 'revlogv2', default=None, ) +coreconfigitem('experimental', 'revisions.disambiguatewithin', + default=None, +) coreconfigitem('experimental', 'single-head-per-branch', default=False, ) diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -437,9 +437,26 @@ return '%d:%s' % (rev, hexfunc(node)) def resolvehexnodeidprefix(repo, prefix): - # Uses unfiltered repo because it's faster when prefix is ambiguous/ - # This matches the shortesthexnodeidprefix() function below. - node = repo.unfiltered().changelog._partialmatch(prefix) + try: + # Uses unfiltered repo because it's faster when prefix is ambiguous/ + # This matches the shortesthexnodeidprefix() function below. + node = repo.unfiltered().changelog._partialmatch(prefix) + except error.AmbiguousPrefixLookupError: + revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') + if revset: + # Clear config to avoid infinite recursion + configoverrides = {('experimental', + 'revisions.disambiguatewithin'): None} + with repo.ui.configoverride(configoverrides): + revs = repo.anyrevs([revset], user=True) + matches = [] + for rev in revs: + node = repo.changelog.node(rev) + if hex(node).startswith(prefix): + matches.append(node) + if len(matches) == 1: + return matches[0] + raise if node is None: return repo.changelog.rev(node) # make sure node isn't filtered diff --git a/tests/test-revisions.t b/tests/test-revisions.t new file mode 100644 --- /dev/null +++ b/tests/test-revisions.t @@ -0,0 +1,37 @@ + $ hg init repo + $ cd repo + + $ echo 0 > a + $ hg ci -qAm 0 + $ for i in 5 8 14 43; do + > hg up -q 0 + > echo $i > a + > hg ci -qm $i + > done + $ cat <> .hg/hgrc + > [alias] + > l = log -T '{rev}:{shortest(node,1)}\n' + > EOF + + $ hg l + 4:7ba5d + 3:7ba57 + 2:72 + 1:9 + 0:b + $ cat <> .hg/hgrc + > [experimental] + > revisions.disambiguatewithin=:3 + > EOF +9 was unambiguous and still is + $ hg l -r 9 + 1:9 +7 was ambiguous and still is + $ hg l -r 7 + abort: 00changelog.i@7: ambiguous identifier! + [255] +7b is no longer ambiguous + $ hg l -r 7b + 3:7ba57 + + $ cd ..