Skip to content

Commit 41de0c6

Browse files
derrickstoleegitster
authored andcommitted
sparse-checkout: cone mode does not recognize "**"
When core.sparseCheckoutCone is enabled, the 'git sparse-checkout set' command creates a restricted set of possible patterns that are used by a custom algorithm to quickly match those patterns. If a user manually edits the sparse-checkout file, then they could create patterns that do not match these expectations. The cone-mode matching algorithm can return incorrect results. The solution is to detect these incorrect patterns, warn that we do not recognize them, and revert to the standard algorithm. Check each pattern for the "**" substring, and revert to the old logic if seen. While technically a "/<dir>/**" pattern matches the meaning of "/<dir>/", it is not one that would be written by the sparse-checkout builtin in cone mode. Attempting to accept that pattern change complicates the logic and instead we punt and do not accept any instance of "**". Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7aa9ef2 commit 41de0c6

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

dir.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,11 +651,16 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
651651
return;
652652
}
653653

654+
if (strstr(given->pattern, "**")) {
655+
/* Not a cone pattern. */
656+
warning(_("unrecognized pattern: '%s'"), given->pattern);
657+
goto clear_hashmaps;
658+
}
659+
654660
if (given->patternlen > 2 &&
655661
!strcmp(given->pattern + given->patternlen - 2, "/*")) {
656662
if (!(given->flags & PATTERN_FLAG_NEGATIVE)) {
657663
/* Not a cone pattern. */
658-
pl->use_cone_patterns = 0;
659664
warning(_("unrecognized pattern: '%s'"), given->pattern);
660665
goto clear_hashmaps;
661666
}

t/t1091-sparse-checkout-builtin.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,38 @@ test_expect_success 'different sparse-checkouts with worktrees' '
305305
check_files worktree a deep
306306
'
307307

308+
check_read_tree_errors () {
309+
REPO=$1
310+
FILES=$2
311+
ERRORS=$3
312+
git -C $REPO read-tree -mu HEAD 2>err &&
313+
if test -z "$ERRORS"
314+
then
315+
test_must_be_empty err
316+
else
317+
test_i18ngrep "$ERRORS" err
318+
fi &&
319+
check_files $REPO $FILES
320+
}
321+
322+
test_expect_success 'pattern-checks: /A/**' '
323+
cat >repo/.git/info/sparse-checkout <<-\EOF &&
324+
/*
325+
!/*/
326+
/folder1/**
327+
EOF
328+
check_read_tree_errors repo "a folder1" "disabling cone pattern matching"
329+
'
330+
331+
test_expect_success 'pattern-checks: /A/**/B/' '
332+
cat >repo/.git/info/sparse-checkout <<-\EOF &&
333+
/*
334+
!/*/
335+
/deep/**/deepest
336+
EOF
337+
check_read_tree_errors repo "a deep" "disabling cone pattern matching" &&
338+
check_files repo/deep "deeper1" &&
339+
check_files repo/deep/deeper1 "deepest"
340+
'
341+
308342
test_done

0 commit comments

Comments
 (0)