On Thu, Mar 10, 2016 at 12:55 AM, Junio C Hamano <gitster@xxxxxxxxx> wrote: > Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> writes: > >> Side note, it's probably a bad idea to use basename matching on a >> negative rule (ie. no slashes in the pattern) because what the pattern >> says is "re-include _any_ directory named 'dir'", not just the directory >> "dir" at right below this directory. > > I am not sure I agree with this comment. When we say '.depend/' in > our .gitignore file, we do want to ignore everything in the > directory with that name anywhere in that tree. Perhaps '!include/' > followed by '*' may be a good way to pick only the header files that > are found in any directory with that name anywhere in the tree in a > similar fashion. It certainly is a disappointing comment if made by > somebody who wants to make 'dir' and '!dir' behave in a more similar > way, I'd have to say. Hmm.. yeah personal view. I'll take this out. >> In both cases, we want to test if the pattern matches a parent >> directory. match_dir_component() is for this purpose. > > I do not follow. I would understand "In all cases, we want to > behave as if we are testing the _full_ path against the pattern", > though. > > IOW, "dir/file1" matches '*' (because 'file1' and '*' matches), > '!dir/' (because the pattern is "everything under dir/ directory), > and nothing else in the pattern list, and the last match > wins---which happens to be negative ignore, hence dir/file1 is not > ignored. Yep, bad phrasing. >> We do want to be careful not to get back too far. Given the file >> foo/bar/.gitignore, we should only check as far back as foo/bar because >> this .gitignore file can never match outside that directory, which is >> "toplevel" in the above paragraphs, to begin with. > > Yes. But isn't that what exclude_stack mechanism already gives us? > That is, when you are not looking at a path inside foo/bar/, entries > stored in foo/bar/.gitignore will not participate the determination > of the fate of the path. > > I am not sure why you have to say this. Puzzled... Naively speaking, in order to fix this without reorganizing a lot of code, when given path 'foo/bar/dir/file1' and the pattern '!dir/', we first still test if the full path "foo/bar/dir/file1" is a directory, then we cut "file1" out (pretend that we are in foo/bar instead of in foo/bar/dir) and test again the full path, which is just foo/bar/dir, if it's a directory. Repeat again and again. This trick does not go through the normal prep_exclude(), so patterns are not popping out when .gitignore should not be used any more. The implementation is a bit different. Instead of going up one level, test, and go up again, I construct the new pattern "foo/bar/**/dir/**" and match it (only once) against the original full path foo/bar/dir/file1. The note was there because I would have just constructed "**/dir/**" instead and matched too much. -- Duy -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html