push: use same rules as git-rev-parse to resolve refspecs

This commit changes the rules for resolving refspecs to match the
rules for resolving refs in rev-parse. git-rev-parse uses clear rules
to resolve a short ref to its full name, which are well documented.
The rules for resolving refspecs documented in git-send-pack were
less strict and harder to understand. This commit replaces them by
the rules of git-rev-parse.

The unified rules are easier to understand and better resolve ambiguous
cases. You can now push from a repository containing several branches
ending on the same short name.

Note, this may break existing setups. For example, "master" will no longer
resolve to "origin/master" even when there is no other "master" elsewhere.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Steffen Prohaska 2007-11-11 15:01:47 +01:00 committed by Junio C Hamano
parent 79803322c1
commit ae36bdcf51
3 changed files with 15 additions and 6 deletions

View File

@ -85,7 +85,9 @@ Each pattern pair consists of the source side (before the colon)
and the destination side (after the colon). The ref to be and the destination side (after the colon). The ref to be
pushed is determined by finding a match that matches the source pushed is determined by finding a match that matches the source
side, and where it is pushed is determined by using the side, and where it is pushed is determined by using the
destination side. destination side. The rules used to match a ref are the same
rules used by gitlink:git-rev-parse[1] to resolve a symbolic ref
name.
- It is an error if <src> does not match exactly one of the - It is an error if <src> does not match exactly one of the
local refs. local refs.

View File

@ -519,10 +519,7 @@ static int count_refspec_match(const char *pattern,
char *name = refs->name; char *name = refs->name;
int namelen = strlen(name); int namelen = strlen(name);
if (namelen < patlen || if (!refname_match(pattern, name, ref_rev_parse_rules))
memcmp(name + namelen - patlen, pattern, patlen))
continue;
if (namelen != patlen && name[namelen - patlen - 1] != '/')
continue; continue;
/* A match is "weak" if it is with refs outside /* A match is "weak" if it is with refs outside

View File

@ -145,11 +145,21 @@ test_expect_success 'push with no ambiguity (1)' '
test_expect_success 'push with no ambiguity (2)' ' test_expect_success 'push with no ambiguity (2)' '
mk_test remotes/origin/master && mk_test remotes/origin/master &&
git push testrepo master:master && git push testrepo master:origin/master &&
check_push_result $the_commit remotes/origin/master check_push_result $the_commit remotes/origin/master
' '
test_expect_success 'push with colon-less refspec, no ambiguity' '
mk_test heads/master heads/t/master &&
git branch -f t/master master &&
git push testrepo master &&
check_push_result $the_commit heads/master &&
check_push_result $the_first_commit heads/t/master
'
test_expect_success 'push with weak ambiguity (1)' ' test_expect_success 'push with weak ambiguity (1)' '
mk_test heads/master remotes/origin/master && mk_test heads/master remotes/origin/master &&