Skip to content

Commit 5842710

Browse files
williams-unitygitster
authored andcommitted
dir: check for single file cone patterns
The sparse checkout documentation states that the cone mode pattern set is limited to patterns that either recursively include directories or patterns that match all files in a directory. In the sparse checkout file, the former manifest in the form: /A/B/C/ while the latter become a pair of patterns either in the form: /A/B/ !/A/B/*/ or in the special case of matching the toplevel files: /* !/*/ The 'add_pattern_to_hashsets()' function contains checks which serve to disable cone-mode when non-cone patterns are encountered. However, these do not catch when the pattern list attempts to match a single file or directory, e.g. a pattern in the form: /A/B/C This causes sparse-checkout to exhibit unexpected behaviour when such a pattern is in the sparse-checkout file and cone mode is enabled. Concretely, with the pattern like the above, sparse-checkout, in non-cone mode, will only include the directory or file located at '/A/B/C'. However, with cone mode enabled, sparse-checkout will instead just manifest the toplevel files but not any file located at '/A/B/C'. Relatedly, issues occur when supplying the same kind of filter when partial cloning with '--filter=sparse:oid=<oid>'. 'upload-pack' will correctly just include the objects that match the non-cone pattern matching. Which means that checking out the newly cloned repo with the same filter, but with cone mode enabled, fails due to missing objects. To fix these issues, add a cone mode pattern check that asserts that every pattern is either a directory match or the pattern '/*'. Add a test to verify the new pattern check and modify another to reflect that non-directory patterns are caught earlier. Signed-off-by: William Sprent <[email protected]> Acked-by: Victoria Dye <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c48035d commit 5842710

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

dir.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,13 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
732732
goto clear_hashmaps;
733733
}
734734

735+
if (!(given->flags & PATTERN_FLAG_MUSTBEDIR) &&
736+
strcmp(given->pattern, "/*")) {
737+
/* Not a cone pattern. */
738+
warning(_("unrecognized pattern: '%s'"), given->pattern);
739+
goto clear_hashmaps;
740+
}
741+
735742
prev = given->pattern;
736743
cur = given->pattern + 1;
737744
next = given->pattern + 2;

t/t1091-sparse-checkout-builtin.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ test_expect_success 'cone mode: match patterns' '
238238
test_expect_success 'cone mode: warn on bad pattern' '
239239
test_when_finished mv sparse-checkout repo/.git/info/ &&
240240
cp repo/.git/info/sparse-checkout . &&
241-
echo "!/deep/deeper/*" >>repo/.git/info/sparse-checkout &&
241+
echo "!/deep/deeper/*/" >>repo/.git/info/sparse-checkout &&
242242
git -C repo read-tree -mu HEAD 2>err &&
243243
test_i18ngrep "unrecognized negative pattern" err
244244
'
@@ -667,6 +667,15 @@ test_expect_success 'pattern-checks: starting "*"' '
667667
check_read_tree_errors repo "a deep" "disabling cone pattern matching"
668668
'
669669

670+
test_expect_success 'pattern-checks: non directory pattern' '
671+
cat >repo/.git/info/sparse-checkout <<-\EOF &&
672+
/deep/deeper1/a
673+
EOF
674+
check_read_tree_errors repo deep "disabling cone pattern matching" &&
675+
check_files repo/deep deeper1 &&
676+
check_files repo/deep/deeper1 a
677+
'
678+
670679
test_expect_success 'pattern-checks: contained glob characters' '
671680
for c in "[a]" "\\" "?" "*"
672681
do

0 commit comments

Comments
 (0)