X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_name.c;h=bf8f0f0e1feef55ba6be764f60815d15036efa4e;hb=ee34518d629331dadd58b1a75294369d679eda8b;hp=be1755a70b2c53fc102db41a62e6099fa0adac1b;hpb=3eeb419968c1f8f0a762a7127db770e9d9c8037d;p=git.git diff --git a/sha1_name.c b/sha1_name.c index be1755a7..bf8f0f0e 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -203,11 +203,12 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len) return NULL; } -static int ambiguous_path(const char *path) +static int ambiguous_path(const char *path, int len) { int slash = 1; + int cnt; - for (;;) { + for (cnt = 0; cnt < len; cnt++) { switch (*path++) { case '\0': break; @@ -224,6 +225,7 @@ static int ambiguous_path(const char *path) } return slash; } + return slash; } static int get_sha1_basic(const char *str, int len, unsigned char *sha1) @@ -236,21 +238,47 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) NULL }; const char **p; + int found = 0; if (len == 40 && !get_sha1_hex(str, sha1)) return 0; /* Accept only unambiguous ref paths. */ - if (ambiguous_path(str)) + if (ambiguous_path(str, len)) return -1; for (p = prefix; *p; p++) { char *pathname = git_path("%s/%.*s", *p, len, str); - if (!read_ref(pathname, sha1)) - return 0; - } - return -1; + if (!read_ref(pathname, sha1)) { + /* Must be unique; i.e. when heads/foo and + * tags/foo are both present, reject "foo". + */ + if (1 < found++) + return -1; + } + + /* We want to allow .git/description file and + * "description" branch to exist at the same time. + * "git-rev-parse description" should silently skip + * .git/description file as a candidate for + * get_sha1(). However, having garbage file anywhere + * under refs/ is not OK, and we would not have caught + * ambiguous heads and tags with the above test. + */ + else if (**p && !access(pathname, F_OK)) { + /* Garbage exists under .git/refs */ + return error("garbage ref found '%s'", pathname); + } + } + switch (found) { + case 0: + return -1; + case 1: + return 0; + default: + return error("ambiguous refname '%.*s'", len, str); + } } static int get_sha1_1(const char *name, int len, unsigned char *sha1);