Re: 'git add' regression in git-1.7?
- From
Jeff King <peff@peff.net>
- Date
- Mar 9, 2010, 23:09 UTC
- Message-ID
- <20100309230931.GC25265@sigill.intra.peff.net>
- In-Reply-To
- <20100309223729.GA25265@sigill.intra.peff.net>
On Tue, Mar 09, 2010 at 05:37:30PM -0500, Jeff King wrote:
Show 15 quoted lines
> No, we would still be correct if we recurse into the ignored directory > _only_ to collect the ignored bits (so we don't even bother if > COLLECT_IGNORED isn't set). But what I don't like is that you take a > performance hit, because in most cases you won't ever care what's inside > those directories. You need to recurse only when: > > - you actually care about all files. git-add does. git-status does not > (unless you explicitly told it to show directories). So that would > probably need a flag passed to fill_directory. > > - you have a pathspec that means the contents of the directory might > be interesting. Right now we check in_pathspec in treat_one_path. > But I think we would need to recognize that "subdir/file" is > means "subdir" is in our pathspec (and that "sub*" means the same > thing).
Actually, if we accept that the message simply mentions the excluded path, i.e.:
$ git add subdir/file The following paths are ignored by one of your .gitignore files: subdir Use -f if you really want to add them.
then we don't really need to recurse. We just need to fix in_pathspec to flag files that are _relevant_ to a pathspec.
And something like this seems to fix the OP's problem:
diff --git a/dir.c b/dir.c index 00d698d..5091bfd 100644 --- a/dir.c +++ b/dir.c @@ -554,13 +554,17 @@ 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) +static int relevant_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; @@ -638,7 +642,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)) + && relevant_pathspec(path, *len, simplify)) dir_add_ignored(dir, path, *len); /* Which is similar to your fix, but hoisted into the ignore-collection phase. Like the original code and your patch, it suffers from using a straight memcmp. I think it should actually be checking the pathspec expansion to catch things like 'sub*/file' being relevant to 'subdir'. -Peff