On Sun, Mar 10, 2013 at 5:58 PM, Junio C Hamano <gitster@xxxxxxxxx> wrote: > Junio C Hamano <gitster@xxxxxxxxx> writes: > >> Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> writes: >> >>> A non-basename pattern that does not contain /**/ can't match anything >>> outside the attached directory. Record its directory level and avoid >>> matching unless the pathname is also at the same directory level. >> >> Without defining what a "directory level" is, the above is a bit >> hard to grok, but I think you mean an entry "b/c/*.c" that appears >> in "a/.gitignore" file will want to match a path that is directly >> in "a/b/c" directory (and not in its subdirectories), >> "a/b/x.c" at the two levels deep subdirectory or "a/b/c/d/x.c" that is >> four levels deep will never match the pattern. >> >> The logic feels sound. > > Actually, I think you may be able to do a lot more with a simpler > change. If your top-level .gitignore has "a/b/c/*.c" in it, you > certainly want to mark it not to be applied when you are looking at > paths directly in directory a/b/ because they will never match, but > you also know that nothing will match when you are inside a/b/d/, > even though the pattern and the path you are checking are at the > same levels. Your dirlen approach will fail for that case, no? > > The idea behind prep_exclude() that organizes the exclode patterns > into a stack structure and update the groups near the leaves by > popping those for the old directory we were in and pushing those for > the new directory we are going into is to give us a place to tweak > the elements on the whole stack for optimization when we notice that > we are looking at paths in different directories. Instead of giving > a "dirlen" member to each element, you could give a "do not look at > me" flag to it, and when you notice that you were in a/b/c/ and now > you are going to look at paths in a/b/d/, you can look at the group > that was read from the .gitignore from the top-level, and mark > entries that cannot be relevant (e.g. "a/b/c/*.c") as such. > > The mark does not have to be a boolean. "a/b/*.c" when you are in > "a/b/c/" can be marked as "This never matches, and I do not have to > re-check until I pop one level". When digging deeper to "a/b/c/d", > you add one to that. When switching to "a/b/e", you would first pop > twice ("d" and then "c"), each time decrementing the "I do not have > to re-check" counter by one, and then when pushing "e" down, you > notice that you need to re-check, and mark it again as "no need to > re-check for one pop". So it is not like you have to re-scan all > entries textually every time you switch directories. Most entries > that are level-limited you would increment or decrement its counter > and only the ones at the level boundary need to be re-checked. A bit confused by "dirlen" (what is it?). I think what you're trying to say is "mark whether a pattern is applicable for entries in this directory in prep_exclude, update the marks as we push and pop directories". It does not sound simpler (and it's actually more powerful, as you said it could avoid checking "a/b/c/*.c" when standing in a/b/d). I'll give it a try. -- 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