path: root/setup.c
diff options
authorJeff King <>2020-01-25 00:00:51 (GMT)
committerJunio C Hamano <>2020-01-27 18:46:35 (GMT)
commit39e21c6ef5221a1dcb8a241f60d7e91d59bd6627 (patch)
tree514e8845ffbbe2c2764a86d3197e1e187f86fc05 /setup.c
parentb6d4d82bd5a49197d5d2f4f81c08da0d461cfcf1 (diff)
verify_filename(): handle backslashes in "wildcards are pathspecs" rule
Commit 28fcc0b71a (pathspec: avoid the need of "--" when wildcard is used, 2015-05-02) allowed: git rev-parse '*.c' without the double-dash. But the rule it uses to check for wildcards actually looks for any glob special. This is overly liberal, as it means that a pattern that doesn't actually do any wildcard matching, like "a\b", will be considered a pathspec. If you do have such a file on disk, that's presumably what you wanted. But if you don't, the results are confusing: rather than say "there's no such path a\b", we'll quietly accept it as a pathspec which very likely matches nothing (or at least not what you intended). Likewise, looking for path "a\*b" doesn't expand the search at all; it would only find a single entry, "a*b". This commit switches the rule to trigger only when glob metacharacters would expand the search, meaning both of those cases will now report an error (you can still disambiguate using "--", of course; we're just tightening the DWIM heuristic). Note that we didn't test the original feature in 28fcc0b71a at all. So this patch not only tests for these corner cases, but also adds a regression test for the existing behavior. Reported-by: David Burström <> Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'setup.c')
1 files changed, 20 insertions, 3 deletions
diff --git a/setup.c b/setup.c
index e2a479a..12228c0 100644
--- a/setup.c
+++ b/setup.c
@@ -197,9 +197,26 @@ static void NORETURN die_verify_filename(struct repository *r,
static int looks_like_pathspec(const char *arg)
- /* anything with a wildcard character */
- if (!no_wildcard(arg))
- return 1;
+ const char *p;
+ int escaped = 0;
+ /*
+ * Wildcard characters imply the user is looking to match pathspecs
+ * that aren't in the filesystem. Note that this doesn't include
+ * backslash even though it's a glob special; by itself it doesn't
+ * cause any increase in the match. Likewise ignore backslash-escaped
+ * wildcard characters.
+ */
+ for (p = arg; *p; p++) {
+ if (escaped) {
+ escaped = 0;
+ } else if (is_glob_special(*p)) {
+ if (*p == '\\')
+ escaped = 1;
+ else
+ return 1;
+ }
+ }
/* long-form pathspec magic */
if (starts_with(arg, ":("))