Skip to content

Commit 69bdbdb

Browse files
derrickstoleegitster
authored andcommitted
dir.c: accept a directory as part of cone-mode patterns
When we have sparse directory entries in the index, we want to compare that directory against sparse-checkout patterns. Those pattern matching algorithms are built expecting a file path, not a directory path. This is especially important in the "cone mode" patterns which will match files that exist within the "parent directories" as well as the recursive directory matches. If path_matches_pattern_list() is given a directory, we can add a fake filename ("-") to the directory and get the same results as before, assuming we are in cone mode. Since sparse index requires cone mode patterns, this is an acceptable assumption. Reviewed-by: Elijah Newren <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 523506d commit 69bdbdb

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

dir.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ enum pattern_match_result path_matches_pattern_list(
13761376
struct path_pattern *pattern;
13771377
struct strbuf parent_pathname = STRBUF_INIT;
13781378
int result = NOT_MATCHED;
1379-
const char *slash_pos;
1379+
size_t slash_pos;
13801380

13811381
if (!pl->use_cone_patterns) {
13821382
pattern = last_matching_pattern_from_list(pathname, pathlen, basename,
@@ -1397,21 +1397,35 @@ enum pattern_match_result path_matches_pattern_list(
13971397
strbuf_addch(&parent_pathname, '/');
13981398
strbuf_add(&parent_pathname, pathname, pathlen);
13991399

1400+
/*
1401+
* Directory entries are matched if and only if a file
1402+
* contained immediately within them is matched. For the
1403+
* case of a directory entry, modify the path to create
1404+
* a fake filename within this directory, allowing us to
1405+
* use the file-base matching logic in an equivalent way.
1406+
*/
1407+
if (parent_pathname.len > 0 &&
1408+
parent_pathname.buf[parent_pathname.len - 1] == '/') {
1409+
slash_pos = parent_pathname.len - 1;
1410+
strbuf_add(&parent_pathname, "-", 1);
1411+
} else {
1412+
const char *slash_ptr = strrchr(parent_pathname.buf, '/');
1413+
slash_pos = slash_ptr ? slash_ptr - parent_pathname.buf : 0;
1414+
}
1415+
14001416
if (hashmap_contains_path(&pl->recursive_hashmap,
14011417
&parent_pathname)) {
14021418
result = MATCHED_RECURSIVE;
14031419
goto done;
14041420
}
14051421

1406-
slash_pos = strrchr(parent_pathname.buf, '/');
1407-
1408-
if (slash_pos == parent_pathname.buf) {
1422+
if (!slash_pos) {
14091423
/* include every file in root */
14101424
result = MATCHED;
14111425
goto done;
14121426
}
14131427

1414-
strbuf_setlen(&parent_pathname, slash_pos - parent_pathname.buf);
1428+
strbuf_setlen(&parent_pathname, slash_pos);
14151429

14161430
if (hashmap_contains_path(&pl->parent_hashmap, &parent_pathname)) {
14171431
result = MATCHED;

0 commit comments

Comments
 (0)