Skip to content

Commit f9e96bf

Browse files
derrickstoleegitster
authored andcommitted
sparse-checkout: sanitize for nested folders
If a user provides folders A/ and A/B/ for inclusion in a cone-mode sparse-checkout file, the parsing logic will notice that A/ appears both as a "parent" type pattern and as a "recursive" type pattern. This is unexpected and hence will complain via a warning and revert to the old logic for checking sparse-checkout patterns. Prevent this from happening accidentally by sanitizing the folders for this type of inclusion in the 'git sparse-checkout' builtin. This happens in two ways: 1. Do not include any parent patterns that also appear as recursive patterns. 2. Do not include any recursive patterns deeper than other recursive patterns. In order to minimize duplicate code for scanning parents, create hashmap_contains_parent() method. It takes a strbuf buffer to avoid reallocating a buffer when calling in a tight loop. Helped-by: Eric Wong <[email protected]> Helped-by: Johannes Schindelin <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4326bc1 commit f9e96bf

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

builtin/sparse-checkout.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,17 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl)
212212
struct pattern_entry *pe;
213213
struct hashmap_iter iter;
214214
struct string_list sl = STRING_LIST_INIT_DUP;
215+
struct strbuf parent_pattern = STRBUF_INIT;
215216

216-
hashmap_for_each_entry(&pl->parent_hashmap, &iter, pe, ent)
217-
string_list_insert(&sl, pe->pattern);
217+
hashmap_for_each_entry(&pl->parent_hashmap, &iter, pe, ent) {
218+
if (hashmap_get_entry(&pl->recursive_hashmap, pe, ent, NULL))
219+
continue;
220+
221+
if (!hashmap_contains_parent(&pl->recursive_hashmap,
222+
pe->pattern,
223+
&parent_pattern))
224+
string_list_insert(&sl, pe->pattern);
225+
}
218226

219227
string_list_sort(&sl);
220228
string_list_remove_duplicates(&sl, 0);
@@ -230,8 +238,14 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl)
230238

231239
string_list_clear(&sl, 0);
232240

233-
hashmap_for_each_entry(&pl->recursive_hashmap, &iter, pe, ent)
234-
string_list_insert(&sl, pe->pattern);
241+
hashmap_for_each_entry(&pl->recursive_hashmap, &iter, pe, ent) {
242+
if (!hashmap_contains_parent(&pl->recursive_hashmap,
243+
pe->pattern,
244+
&parent_pattern))
245+
string_list_insert(&sl, pe->pattern);
246+
}
247+
248+
strbuf_release(&parent_pattern);
235249

236250
string_list_sort(&sl);
237251
string_list_remove_duplicates(&sl, 0);

t/t1091-sparse-checkout-builtin.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,15 @@ test_expect_success 'cone mode: init and set' '
237237
test_cmp expect dir
238238
'
239239

240+
test_expect_success 'cone mode: set with nested folders' '
241+
git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err &&
242+
test_line_count = 0 err &&
243+
cat >expect <<-EOF &&
244+
/*
245+
!/*/
246+
/deep/
247+
EOF
248+
test_cmp repo/.git/info/sparse-checkout expect
249+
'
250+
240251
test_done

0 commit comments

Comments
 (0)