sparse-checkout: warn on globs in cone patterns
In cone mode, the sparse-checkout commmand will write patterns that allow faster pattern matching. This matching only works if the patterns in the sparse-checkout file are those written by that command. Users can edit the sparse-checkout file and create patterns that cause the cone mode matching to fail. The cone mode patterns may end in "/*" but otherwise an un-escaped asterisk or other glob character is invalid. Add checks to disable cone mode when seeing these values. A later change will properly handle escaped globs. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
9e6d3e6417
commit
9abc60f801
36
dir.c
36
dir.c
@ -635,6 +635,7 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
|
|||||||
struct pattern_entry *translated;
|
struct pattern_entry *translated;
|
||||||
char *truncated;
|
char *truncated;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
|
const char *prev, *cur, *next;
|
||||||
|
|
||||||
if (!pl->use_cone_patterns)
|
if (!pl->use_cone_patterns)
|
||||||
return;
|
return;
|
||||||
@ -652,12 +653,47 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (given->patternlen <= 2 ||
|
if (given->patternlen <= 2 ||
|
||||||
|
*given->pattern == '*' ||
|
||||||
strstr(given->pattern, "**")) {
|
strstr(given->pattern, "**")) {
|
||||||
/* Not a cone pattern. */
|
/* Not a cone pattern. */
|
||||||
warning(_("unrecognized pattern: '%s'"), given->pattern);
|
warning(_("unrecognized pattern: '%s'"), given->pattern);
|
||||||
goto clear_hashmaps;
|
goto clear_hashmaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev = given->pattern;
|
||||||
|
cur = given->pattern + 1;
|
||||||
|
next = given->pattern + 2;
|
||||||
|
|
||||||
|
while (*cur) {
|
||||||
|
/* Watch for glob characters '*', '\', '[', '?' */
|
||||||
|
if (!is_glob_special(*cur))
|
||||||
|
goto increment;
|
||||||
|
|
||||||
|
/* But only if *prev != '\\' */
|
||||||
|
if (*prev == '\\')
|
||||||
|
goto increment;
|
||||||
|
|
||||||
|
/* But allow the initial '\' */
|
||||||
|
if (*cur == '\\' &&
|
||||||
|
is_glob_special(*next))
|
||||||
|
goto increment;
|
||||||
|
|
||||||
|
/* But a trailing '/' then '*' is fine */
|
||||||
|
if (*prev == '/' &&
|
||||||
|
*cur == '*' &&
|
||||||
|
*next == 0)
|
||||||
|
goto increment;
|
||||||
|
|
||||||
|
/* Not a cone pattern. */
|
||||||
|
warning(_("unrecognized pattern: '%s'"), given->pattern);
|
||||||
|
goto clear_hashmaps;
|
||||||
|
|
||||||
|
increment:
|
||||||
|
prev++;
|
||||||
|
cur++;
|
||||||
|
next++;
|
||||||
|
}
|
||||||
|
|
||||||
if (given->patternlen > 2 &&
|
if (given->patternlen > 2 &&
|
||||||
!strcmp(given->pattern + given->patternlen - 2, "/*")) {
|
!strcmp(given->pattern + given->patternlen - 2, "/*")) {
|
||||||
if (!(given->flags & PATTERN_FLAG_NEGATIVE)) {
|
if (!(given->flags & PATTERN_FLAG_NEGATIVE)) {
|
||||||
|
@ -348,4 +348,43 @@ test_expect_success 'pattern-checks: too short' '
|
|||||||
check_read_tree_errors repo "a" "disabling cone pattern matching"
|
check_read_tree_errors repo "a" "disabling cone pattern matching"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pattern-checks: trailing "*"' '
|
||||||
|
cat >repo/.git/info/sparse-checkout <<-\EOF &&
|
||||||
|
/*
|
||||||
|
!/*/
|
||||||
|
/a*
|
||||||
|
EOF
|
||||||
|
check_read_tree_errors repo "a" "disabling cone pattern matching"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pattern-checks: starting "*"' '
|
||||||
|
cat >repo/.git/info/sparse-checkout <<-\EOF &&
|
||||||
|
/*
|
||||||
|
!/*/
|
||||||
|
*eep/
|
||||||
|
EOF
|
||||||
|
check_read_tree_errors repo "a deep" "disabling cone pattern matching"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pattern-checks: contained glob characters' '
|
||||||
|
for c in "[a]" "\\" "?" "*"
|
||||||
|
do
|
||||||
|
cat >repo/.git/info/sparse-checkout <<-EOF &&
|
||||||
|
/*
|
||||||
|
!/*/
|
||||||
|
something$c-else/
|
||||||
|
EOF
|
||||||
|
check_read_tree_errors repo "a" "disabling cone pattern matching"
|
||||||
|
done
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pattern-checks: escaped "*"' '
|
||||||
|
cat >repo/.git/info/sparse-checkout <<-\EOF &&
|
||||||
|
/*
|
||||||
|
!/*/
|
||||||
|
/does\*not\*exist/
|
||||||
|
EOF
|
||||||
|
check_read_tree_errors repo "a" ""
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Reference in New Issue
Block a user