Skip to content

Commit 29209cb

Browse files
peffgitster
authored andcommitted
dir: fix COLLECT_IGNORED on excluded prefixes
As we walk the directory tree, if we see an ignored path, we want to add it to the ignored list only if it matches any pathspec that we were given. We used to check for the pathspec to appear explicitly. E.g., if we see "subdir/file" and it is excluded, we check to see if we have "subdir/file" in our pathspec. However, this interacts badly with the optimization to avoid recursing into ignored subdirectories. If "subdir" as a whole is ignored, then we never recurse, and consider only whether "subdir" itself is in our pathspec. It would not match a pathspec of "subdir/file" explicitly, even though it is the reason that subdir/file would be excluded. This manifests itself to the user as "git add subdir/file" failing to correctly note that the pathspec was ignored. This patch extends the in_pathspec logic to include prefix directory case. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0d7c243 commit 29209cb

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

dir.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,13 +554,29 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
554554
return 0;
555555
}
556556

557-
static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
557+
/*
558+
* This function tells us whether an excluded path matches a
559+
* list of "interesting" pathspecs. That is, whether a path matched
560+
* by any of the pathspecs could possibly be ignored by excluding
561+
* the specified path. This can happen if:
562+
*
563+
* 1. the path is mentioned explicitly in the pathspec
564+
*
565+
* 2. the path is a directory prefix of some element in the
566+
* pathspec
567+
*/
568+
static int exclude_matches_pathspec(const char *path, int len,
569+
const struct path_simplify *simplify)
558570
{
559571
if (simplify) {
560572
for (; simplify->path; simplify++) {
561573
if (len == simplify->len
562574
&& !memcmp(path, simplify->path, len))
563575
return 1;
576+
if (len < simplify->len
577+
&& simplify->path[len] == '/'
578+
&& !memcmp(path, simplify->path, len))
579+
return 1;
564580
}
565581
}
566582
return 0;
@@ -638,7 +654,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
638654
{
639655
int exclude = excluded(dir, path, &dtype);
640656
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
641-
&& in_pathspec(path, *len, simplify))
657+
&& exclude_matches_pathspec(path, *len, simplify))
642658
dir_add_ignored(dir, path, *len);
643659

644660
/*

0 commit comments

Comments
 (0)