From: Kevin Ballard Date: Fri, 23 May 2008 22:44:02 GMT Subject: Re: gitignore: negating path patterns Message-ID: In-Reply-To: On May 23, 2008, at 12:52 AM, Michael J Gruber wrote: > Kevin Ballard venit, vidit, dixit 23.05.2008 02:23: >> On May 21, 2008, at 7:52 AM, Michael J Gruber wrote: >>> Hi there >>> >>> It seems that negating path patterns in gitignore doesn't work, or I >>> don't understand it (or both). With the attached script, git status >>> (1.5.5.1) reports "dir/a" as new and "dir/b" as untracked. I would >>> rather expect it to report "dir/c" as untracked also. >>> >>> It seems that "!b" matches to include "dir/b" (reverting the >>> exclusion >>> "*" as expected), whereas "!dir/" does not match to include "dir/c". >>> >>> What's going on here? >> "dir/" will not match anything, because paths are compared without >> trailing slashes. Try "!dir". > > I am sorry, but this is plain wrong, at least if "man gitignore" is > right (see below). "!dir" would match files whose name (pathname > without leading directory name) matches "dir" (i.e.: is dir) and > exclude those from exclusion (include them). > > Also, replacing "!dir/" by "!dir" in my test script does not change > the result. In fact, for "!dir" the result is as expected and > documented, just for "!dir/" I would expect something else. > > So, thanks for trying to help, although reading the manual or > testing your advice before would be appreciated even more. ;) > > Michael > > From man gitignore: > > If the pattern ends with a slash, it is removed for the purpose of > the following description, but it would only find a match with a > directory. In other words, foo/ will match a directory foo and paths > underneath it, but will not match a regular file or a symbolic link > foo (this is consistent with the way how pathspec works in general > in git). Ahh, the behavior changed in 1.5.5. Pre-1.5.5, if a path ended in a slash, it would never match anything. In any case, the problem is the * pattern. Here's what happens: At /, the * is evaluated and ignores everything. The !dir/ is evaluated and unignores dir. The !b is evaluated and matches nothing. AT /dir, the * is evaluated and ignores everything. The !dir/ is evaluated and matches nothing. The !b is evaluated and unignores b. So the problem is the * is recursively applying to the subdirectories. To fix this, use /* as the pattern. -Kevin Ballard -- Kevin Ballard http://kevin.sb.org kevin@sb.org http://www.tildesoft.com