git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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
Previous: Jeff KingNext: Junio C Hamano
Message 12 of 17 in “'git add' regression in git-1.7?”
  1. SungHyun NamFeb 19, 2010
  2. Avery PennarunFeb 19, 2010
  3. SungHyun NamFeb 19, 2010
  4. Avery PennarunFeb 19, 2010
  5. Jeff KingFeb 19, 2010
  6. Jeff KingFeb 19, 2010
  7. Jeff KingFeb 19, 2010
  8. Junio C HamanoMar 1, 2010
  9. add: fail "git add ignored-dir/file" without -fJunio C Hamano, Mar 1, 2010
  10. 1/3 t0050: mark non-working test as suchJunio C Hamano, Mar 1, 2010
  11. Jeff KingMar 9, 2010
  12. Jeff KingMar 9, 2010
  13. Junio C HamanoMar 10, 2010
  14. Jeff KingMar 11, 2010
  15. Junio C HamanoMar 14, 2010
  16. Jeff KingMar 14, 2010
  17. Junio C HamanoMar 15, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.