Be more careful about reference parsing
This does two things:
- we don't allow "." and ".." as components of a refname. Thus get_sha1()
will not accept "./refname" as being the same as "refname" any more.
- git-rev-parse stops doing revision translation after seeing a pathname,
to match the brhaviour of all the tools (once we see a pathname,
everything else will also be parsed as a pathname).
Basically, if you did
git log *
and "gitk" was somewhere in the "*", we don't want to replace the filename
"gitk" with the SHA1 of the branch with the same name.
Of course, if there is any change of ambiguity, you should always use "--"
to make it explicit what are filenames and what are revisions, but this
makes the normal cases sane. The refname rule also means that instead of
the "--", you can do the same thing we're used to doing with filenames
that start with a slash: use "./filename" instead, and now it's a
filename, not an option (and not a revision).
So "git log ./*.c" is now actually a perfectly valid thing to do, even if
the first C-file might have the same name as a branch.
Trivial test:
git-rev-parse gitk ./gitk gitk
should output something like
9843c3074d
./gitk
gitk
where the "./gitk" isn't seen as a revision, and the second "gitk" is a
filename simply because we've seen filenames already, and thus stopped
doing revision parsing.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
41f222e87a
commit
af13cdf298
@ -292,6 +292,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
if (verify)
|
||||
die("Needed a single revision");
|
||||
as_is = 1;
|
||||
show_file(arg);
|
||||
}
|
||||
show_default();
|
||||
|
27
sha1_name.c
27
sha1_name.c
@ -203,6 +203,29 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ambiguous_path(const char *path)
|
||||
{
|
||||
int slash = 1;
|
||||
|
||||
for (;;) {
|
||||
switch (*path++) {
|
||||
case '\0':
|
||||
break;
|
||||
case '/':
|
||||
if (slash)
|
||||
break;
|
||||
slash = 1;
|
||||
continue;
|
||||
case '.':
|
||||
continue;
|
||||
default:
|
||||
slash = 0;
|
||||
continue;
|
||||
}
|
||||
return slash;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
{
|
||||
static const char *prefix[] = {
|
||||
@ -217,6 +240,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
|
||||
if (len == 40 && !get_sha1_hex(str, sha1))
|
||||
return 0;
|
||||
|
||||
/* Accept only unambiguous ref paths. */
|
||||
if (ambiguous_path(str))
|
||||
return -1;
|
||||
|
||||
for (p = prefix; *p; p++) {
|
||||
char *pathname = git_path("%s/%.*s", *p, len, str);
|
||||
if (!read_ref(pathname, sha1))
|
||||
|
Loading…
Reference in New Issue
Block a user