Skip to content

Commit 09dbe1f

Browse files
committed
sparse-checkout: properly match escaped characters
In cone mode, the sparse-checkout feature uses hashset containment queries to match paths. Make this algorithm respect escaped asterisk (*) and backslash (\) characters. Create dup_and_filter_pattern() method to convert a pattern by removing escape characters and dropping an optional "/*" at the end. This method is available in dir.h as we will use it in builtin/sparse-chekcout.c in a later change. Signed-off-by: Derrick Stolee <[email protected]>
1 parent 77a514f commit 09dbe1f

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

dir.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,32 @@ int pl_hashmap_cmp(const void *unused_cmp_data,
630630
return strncmp(ee1->pattern, ee2->pattern, min_len);
631631
}
632632

633+
char *dup_and_filter_pattern(const char *pattern)
634+
{
635+
char *set, *read;
636+
char *result = xstrdup(pattern);
637+
638+
set = result;
639+
read = result;
640+
641+
while (*read) {
642+
/* skip escape characters (once) */
643+
if (*read == '\\')
644+
read++;
645+
646+
*set = *read;
647+
648+
set++;
649+
read++;
650+
}
651+
*set = 0;
652+
653+
if (*(read - 2) == '/' && *(read - 1) == '*')
654+
*(read - 2) = 0;
655+
656+
return result;
657+
}
658+
633659
static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern *given)
634660
{
635661
struct pattern_entry *translated;
@@ -698,8 +724,7 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
698724
goto clear_hashmaps;
699725
}
700726

701-
truncated = xstrdup(given->pattern);
702-
truncated[given->patternlen - 2] = 0;
727+
truncated = dup_and_filter_pattern(given->pattern);
703728

704729
translated = xmalloc(sizeof(struct pattern_entry));
705730
translated->pattern = truncated;
@@ -733,7 +758,7 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
733758

734759
translated = xmalloc(sizeof(struct pattern_entry));
735760

736-
translated->pattern = xstrdup(given->pattern);
761+
translated->pattern = dup_and_filter_pattern(given->pattern);
737762
translated->patternlen = given->patternlen;
738763
hashmap_entry_init(&translated->ent,
739764
ignore_case ?

dir.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ int pl_hashmap_cmp(const void *unused_cmp_data,
304304
const struct hashmap_entry *a,
305305
const struct hashmap_entry *b,
306306
const void *key);
307+
char *dup_and_filter_pattern(const char *pattern);
307308
int hashmap_contains_parent(struct hashmap *map,
308309
const char *path,
309310
struct strbuf *buffer);

t/t1091-sparse-checkout-builtin.sh

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,27 @@ test_expect_success 'pattern-checks: starting "*"' '
366366
check_read_tree_errors repo "a deep" "disabling cone pattern matching"
367367
'
368368

369-
test_expect_success 'pattern-checks: escaped "*"' '
370-
cat >repo/.git/info/sparse-checkout <<-\EOF &&
369+
test_expect_success BSLASHPSPEC 'pattern-checks: escaped "*"' '
370+
git clone repo escaped &&
371+
TREEOID=$(git -C escaped rev-parse HEAD:folder1) &&
372+
NEWTREE=$(git -C escaped mktree <<-EOF
373+
$(git -C escaped ls-tree HEAD)
374+
040000 tree $TREEOID zbad\\dir
375+
040000 tree $TREEOID zdoes*exist
376+
EOF
377+
) &&
378+
COMMIT=$(git -C escaped commit-tree $NEWTREE -p HEAD) &&
379+
git -C escaped reset --hard $COMMIT &&
380+
check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" &&
381+
git -C escaped sparse-checkout init --cone &&
382+
cat >escaped/.git/info/sparse-checkout <<-\EOF &&
371383
/*
372384
!/*/
373-
/does\*not\*exist/
385+
/zbad\\dir/
386+
/zdoes\*not\*exist/
387+
/zdoes\*exist/
374388
EOF
375-
check_read_tree_errors repo "a" ""
389+
check_read_tree_errors escaped "a zbad\\dir zdoes*exist"
376390
'
377391

378392
test_done

0 commit comments

Comments
 (0)