Thread (12 messages) flat view 12 messages, 4 authors, 2016-06-15

Re: [PROPOSAL] .gitignore syntax modification

From: Kevin Ballard <hidden>
Date: 2016-06-15 22:49:47

On Oct 13, 2010, at 5:15 AM, Nguyen Thai Ngoc Duy wrote:
On Tue, Oct 12, 2010 at 07:32:54PM -0700, Kevin Ballard wrote:
quoted
As soon as I find the time, I'll be working on a patch for this. I
only wrote up the proposal because I want to make sure that what I
end up implementing is actually something that will be accepted. At
this point I'm actually in favor of simply assuming all paths that
don't start with / can be matched at any level but I recognize that
this is a change to existing functionality, though I personally
think that all patterns that are meant to match only at the current
level should be prefixed with / anyway. Would such a change to
existing behavior be rejected out-of-hand?
Yes, patterns that only match current level should be prefixed with a
slash. There are also other cases apart from "current level only" and
"any level": foo/a* will match only second level, not any level.
Sure, "foo/a*" will match second level only, but that's identical to "/foo/a*". I would have preferred the semantics of .gitignore to behave as if all patterns are prefixed with "**/" unless the pattern starts with "/", but that ship sailed a long time ago and I agree that it would be a bad idea to introduce that behavior now.
I was thinking of doing like this. It's not complete (not even build)
but it shows the idea. I don't think this way it will change existing
behaviors. Performance is something I haven't thought through.

Anyway, what do you think? I'm afraid I don't have time to work on
this. The pathspec unification work still needs to be done.
Got around to glancing at your patch. Looks pretty good, and it does build if you simply define EXC_FLAG_STARSTAR, though there are a few changes that are definitely necessary (a path of "*" will cause this to run off the end of the string while trying to detect "**/"). I'll have some more time next week to take a much closer look though. As for performance, I'm not particularly worried. The only performance change is if EXC_FLAG_STARSTAR is checked, in the worst-case it'll try to apply the pattern once per level of directory nesting. As this is just string twiddling, it's bound to be pretty fast, and I don't think there's any viable alternative to doing this kind of loop anyway. That said, I'd still like to support putting **/ anywhere in the pattern instead of just at the beginning, and 
 possibly even support ** (without the trailing /).

If we do support ** by itself, I wonder if we should special-case having ** as the last path component of the pattern. The possible behavior change we could have is making this only match files and not directories. The use-case here is putting something like "foo/**" in the top-level .gitignore and then a few levels into foo we could put another .gitignore with an inverse pattern in order to un-ignore some deep file (or just "!foo/*/*/bar.c" inside that top-level .gitignore as well). The only way I can think of to achieve this behavior with the current gitignore is something along the lines of

foo/*
!foo/bar/
foo/bar/*
!foo/bar/baz/
foo/bar/baz/*
!foo/bar/baz/bar.c

And even this will only work if you know all the intermediate directories. I cannot think of any way at all right now to ignore everything in a single directory except for one file at least 1 level of nesting deeper if you don't know the names of the intermediate directories. With the proposed special-case we can say

foo/**
!foo/*/*/bar.c

and it will behave exactly as specified.

It occurs to me that we could actually tweak this slightly, to say that if a ** is encountered and there are zero slashes in the pattern after it, then it will only match files (with zero or more leading directories). This way you can have a pattern "foo/**.d" which only ignores files with the extension ".d" but will still avoid ignoring directories that end in ".d".

This turned out a bit longer than intended, and slightly more rambling as well, and I apologize for that. I will revisit this again next week.

-Kevin Ballard
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help