Mercurial > public > mercurial-scm > hg
comparison mercurial/scmutil.py @ 38842:503f936489dd
lookup: add option to disambiguate prefix within revset
When resolving a nodeid prefix that is not unique within the repo and
the user has configured a revset that they want to disambiguate
within, we now try to look up within that revset before we fail. If
there is a unique match within the revset, we use that.
This is of course most effective at allowing a short prefix if the
revset contains few nodes. For most of our internal users at Google,
"not public()" is sufficiently small that a hex digit or two is
enough.
The implementation is currently pretty slow, but good enough for small
revsets (which is the expected use case). The scan in the revset is
linear. We may want to use a prefix tree if we want to allow users to
use a larger revset.
Credit for the idea goes to Kyle Lippincott.
Differential Revision: https://phab.mercurial-scm.org/D4037
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Wed, 28 Mar 2018 09:36:02 -0700 |
parents | df0873ab5c14 |
children | 6f7c9527030b |
comparison
equal
deleted
inserted
replaced
38841:df0873ab5c14 | 38842:503f936489dd |
---|---|
435 else: | 435 else: |
436 hexfunc = short | 436 hexfunc = short |
437 return '%d:%s' % (rev, hexfunc(node)) | 437 return '%d:%s' % (rev, hexfunc(node)) |
438 | 438 |
439 def resolvehexnodeidprefix(repo, prefix): | 439 def resolvehexnodeidprefix(repo, prefix): |
440 # Uses unfiltered repo because it's faster when prefix is ambiguous/ | 440 try: |
441 # This matches the shortesthexnodeidprefix() function below. | 441 # Uses unfiltered repo because it's faster when prefix is ambiguous/ |
442 node = repo.unfiltered().changelog._partialmatch(prefix) | 442 # This matches the shortesthexnodeidprefix() function below. |
443 node = repo.unfiltered().changelog._partialmatch(prefix) | |
444 except error.AmbiguousPrefixLookupError: | |
445 revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') | |
446 if revset: | |
447 # Clear config to avoid infinite recursion | |
448 configoverrides = {('experimental', | |
449 'revisions.disambiguatewithin'): None} | |
450 with repo.ui.configoverride(configoverrides): | |
451 revs = repo.anyrevs([revset], user=True) | |
452 matches = [] | |
453 for rev in revs: | |
454 node = repo.changelog.node(rev) | |
455 if hex(node).startswith(prefix): | |
456 matches.append(node) | |
457 if len(matches) == 1: | |
458 return matches[0] | |
459 raise | |
443 if node is None: | 460 if node is None: |
444 return | 461 return |
445 repo.changelog.rev(node) # make sure node isn't filtered | 462 repo.changelog.rev(node) # make sure node isn't filtered |
446 return node | 463 return node |
447 | 464 |