Skip to content

Commit

Permalink
dir: fix COLLECT_IGNORED on excluded prefixes
Browse files Browse the repository at this point in the history
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 <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
peff authored and gitster committed Mar 14, 2010
1 parent 0d7c243 commit 29209cb
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,13 +554,29 @@ static int simplify_away(const char *path, int pathlen, const struct path_simpli
return 0;
}

static int in_pathspec(const char *path, int len, const struct path_simplify *simplify)
/*
* This function tells us whether an excluded path matches a
* list of "interesting" pathspecs. That is, whether a path matched
* by any of the pathspecs could possibly be ignored by excluding
* the specified path. This can happen if:
*
* 1. the path is mentioned explicitly in the pathspec
*
* 2. the path is a directory prefix of some element in the
* pathspec
*/
static int exclude_matches_pathspec(const char *path, int len,
const struct path_simplify *simplify)
{
if (simplify) {
for (; simplify->path; simplify++) {
if (len == simplify->len
&& !memcmp(path, simplify->path, len))
return 1;
if (len < simplify->len
&& simplify->path[len] == '/'
&& !memcmp(path, simplify->path, len))
return 1;
}
}
return 0;
Expand Down Expand Up @@ -638,7 +654,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
{
int exclude = excluded(dir, path, &dtype);
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
&& in_pathspec(path, *len, simplify))
&& exclude_matches_pathspec(path, *len, simplify))
dir_add_ignored(dir, path, *len);

/*
Expand Down

0 comments on commit 29209cb

Please sign in to comment.