verify_filename(): handle backslashes in "wildcards are pathspecs" rule
Commit28fcc0b71a
(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 in28fcc0b71a
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 <davidburstrom@spotify.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
b6d4d82bd5
commit
39e21c6ef5
23
setup.c
23
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, ":("))
|
||||
|
@ -222,4 +222,18 @@ test_expect_success 'reject Nth ancestor if N is too high' '
|
||||
test_must_fail git rev-parse HEAD~100000000000000000000000000000000
|
||||
'
|
||||
|
||||
test_expect_success 'pathspecs with wildcards are not ambiguous' '
|
||||
echo "*.c" >expect &&
|
||||
git rev-parse "*.c" >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'backslash does not trigger wildcard rule' '
|
||||
test_must_fail git rev-parse "foo\\bar"
|
||||
'
|
||||
|
||||
test_expect_success 'escaped char does not trigger wildcard rule' '
|
||||
test_must_fail git rev-parse "foo\\*bar"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user