# HG changeset patch # User Sietse Brouwer # Date 1475741474 -7200 # Node ID a128b9a53b5a0fc0b3275d4865c50801bd529f14 # Parent ff663d2214dba1fd0816c928c803fc19ca948b24 revset_gitnode: allow abbreviated hashes The previous implementation only allowed passing 40-hexdigit hashes or 12-hexdigit abbreviations to `gitnode(hash)`. Shorter or longer hashes were accepted, but failed silently. With this fix, any unambiguous abbreviation is accepted. `gitnode(a5b)` selects the revision whose Git hash starts with `a5b`, if there is one, and aborts if there are several. diff -r ff663d2214db -r a128b9a53b5a hggit/__init__.py --- a/hggit/__init__.py Mon Sep 12 07:40:42 2016 -0700 +++ b/hggit/__init__.py Thu Oct 06 10:11:14 2016 +0200 @@ -30,6 +30,7 @@ from bisect import insort from git_handler import GitHandler from mercurial.node import hex +from mercurial.error import LookupError from mercurial.i18n import _ from mercurial import ( bundlerepo, @@ -382,7 +383,9 @@ def revset_gitnode(repo, subset, x): '''``gitnode(hash)`` - Select changesets that originate in the given Git revision. + Select the changeset that originates in the given Git revision. The hash + may be abbreviated: `gitnode(a5b)` selects the revision whose Git hash + starts with `a5b`. Aborts if multiple changesets match the abbreviation. ''' args = revset.getargs(x, 1, 1, "gitnode takes one argument") rev = revset.getstring(args[0], @@ -394,8 +397,11 @@ gitnode = git.map_git_get(hex(node(r))) if gitnode is None: return False - return rev in [gitnode, gitnode[:12]] - return baseset(r for r in subset if matches(r)) + return gitnode.startswith(rev) + result = baseset(r for r in subset if matches(r)) + if 0 <= len(result) < 2: + return result + raise LookupError(rev, git.map_file, _('ambiguous identifier')) def gitnodekw(**args): """:gitnode: String. The Git changeset identification hash, as a 40 hexadecimal digit string.""" diff -r ff663d2214db -r a128b9a53b5a tests/test-keywords.t --- a/tests/test-keywords.t Mon Sep 12 07:40:42 2016 -0700 +++ b/tests/test-keywords.t Thu Oct 06 10:11:14 2016 +0200 @@ -11,25 +11,37 @@ $ git add beta $ fn_git_commit -m 'add beta' +This commit is called gamma10 so that its hash will have the same initial digit +as commit alpha. This lets us test ambiguous abbreviated identifiers. + + $ echo gamma10 > gamma10 + $ git add gamma10 + $ fn_git_commit -m 'add gamma10' + $ cd .. $ hg clone gitrepo hgrepo | grep -v '^updating' importing git objects into hg - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd hgrepo $ echo gamma > gamma $ hg add gamma $ hg commit -m 'add gamma' $ hg log --template "{rev} {node} {node|short} {gitnode} {gitnode|short}\n" - 2 168eb1ee8b3c04e6723c9330327b0eec1e36577f 168eb1ee8b3c + 3 965bf7d08d3ac847dd8eb9e72ee0bf547d1a65d9 965bf7d08d3a + 2 8e3f0ecc9aefd4ea2fdf8e2d5299cac548762a1c 8e3f0ecc9aef 7e2a5465ff4e3b992c429bb87a392620a0ac97b7 7e2a5465ff4e 1 7fe02317c63d9ee324d4b5df7c9296085162da1b 7fe02317c63d 9497a4ee62e16ee641860d7677cdb2589ea15554 9497a4ee62e1 0 ff7a2f2d8d7099694ae1e8b03838d40575bebb63 ff7a2f2d8d70 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 7eeab2ea75ec $ hg log --template "fromgit {rev}\n" --rev "fromgit()" fromgit 0 fromgit 1 + fromgit 2 $ hg log --template "gitnode_existsA {rev}\n" --rev "gitnode(9497a4ee62e16ee641860d7677cdb2589ea15554)" gitnode_existsA 1 - $ hg log --template "gitnode_existsB {rev}\n" --rev "gitnode(7eeab2ea75ec)" + $ hg log --template "gitnode_existsB {rev}\n" --rev "gitnode(7eeab)" gitnode_existsB 0 + $ hg log --rev "gitnode(7e)" + abort: git-mapfile@7e: ambiguous identifier! + [255] $ hg log --template "gitnode_notexists {rev}\n" --rev "gitnode(1234567890ab)"