Update :/abc ambiguity check

:/abc may mean two things: - as a revision, it means the revision that has "abc" in commit message. - as a pathpec, it means "abc" from root. Currently we see ":/abc" as a rev (most of the time), but never see it as a pathspec even if "abc" exists and "git log :/abc" will gladly take ":/abc" as rev even it's ambiguous. This patch makes it: - ambiguous when "abc" exists on worktree - a rev if abc does not exist on worktree - a path if abc is not found in any commits (although better use "--" to avoid ambiguation because searching through commit DAG is expensive) A plus from this patch is, because ":/" never matches anything as a rev, it is never considered a valid rev and because root directory always exists, ":/" is always unambiguously seen as a pathspec. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Jan 21, 2013 at 20:00 UTC 4db86e8b6e8002b3113341ad742bf2fd94d4df50
2 files changed +23 -3
setup.c
+8 -1
@@ -66,7 +66,14 @@ int check_filename(const char *prefix, const char *arg)
66 const char *name;
67 struct stat st;
68
69 - name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
69 + if (!prefixcmp(arg, ":/")) {
70 + if (arg[2] == '\0') /* ":/" is root dir, always exists */
71 + return 1;
72 + name = arg + 2;
73 + } else if (prefix)
74 + name = prefix_filename(prefix, strlen(prefix), arg);
75 + else
76 + name = arg;
77 if (!lstat(name, &st))
78 return 1; /* file exists */
79 if (errno == ENOENT || errno == ENOTDIR)
t/t4208-log-magic-pathspec.sh
+15 -2
@@ -11,11 +11,24 @@ test_expect_success 'setup' '
11 mkdir sub
12 '
13
14 -test_expect_success '"git log :/" should be ambiguous' '
15 - test_must_fail git log :/ 2>error &&
14 +test_expect_success '"git log :/" should not be ambiguous' '
15 + git log :/
16 +'
17 +
18 +test_expect_success '"git log :/a" should be ambiguous (applied both rev and worktree)' '
19 + : >a &&
20 + test_must_fail git log :/a 2>error &&
21 grep ambiguous error
22 '
23
24 +test_expect_success '"git log :/a -- " should not be ambiguous' '
25 + git log :/a --
26 +'
27 +
28 +test_expect_success '"git log -- :/a" should not be ambiguous' '
29 + git log -- :/a
30 +'
31 +
32 test_expect_success '"git log :" should be ambiguous' '
33 test_must_fail git log : 2>error &&
34 grep ambiguous error