Re: Oddities in gitignore matching
- From
- Phillip Wood <phillip.wood123@gmail.com>
- Date
- Jun 28, 2022, 09:13 UTC
- Message-ID
- <72a1a225-5d84-56c3-2652-ec7c17c18cbd@gmail.com>
- In-Reply-To
- <DC3C4CED-3781-4380-95E6-97F5CBE1B13C@gmail.com>
Hi John
On 26/06/2022 20:34, John Thorvald Wodder II wrote:
> First: I've found that the pattern "foo**/bar" causes the path "foo/glarch/bar" (as well as "foobie/glarch/bar") to be ignored. However, the gitignore(5) documentation states that "**/" only has special meaning when it's "leading"; in other circumstances, the double star should be treated the same as a single star (and "foo*/bar" does not match "foo/glarch/bar"). Is this behavior of non-leading "**/" deliberate or a bug?
I've no idea if it is deliberate or not but it seems reasonable and I think it matches shells like fish, tcsh and zsh though not bash (I think our documented behavior matches bash).
> Interestingly, checking the pattern with the wildmatch test-tool (`t/helper/test-tool wildmatch wildmatch foo/glarch/bar 'foo**/bar'`) shows that the pattern should not match the path. > > Second: The pattern "[[:space:]]" does not match 0x0B (\v, vertical tab) or 0x0C (\f, form feed) despite the fact that the C isspace() function accepts these characters, and I cannot figure out the cause for this discrepancy. (The pattern does match the other characters that isspace() accepts, though — tab, line feed, carriage return, and space character.) The wildmatch test-tool agrees with this behavior, though.
This is because git defines its own isspace() that does not treat '\v' or '\f' as whitespace (see git-compat-util.h and ctype.c). I'm not sure why we exclude those characters, I think the reason for defining our own isspace() is to avoid the locale dependent behaviour of the standard version.
I'm afraid I don't have anything useful to add for your third point
Best Wishes
Phillip
Show 10 quoted lines
> Third: While the documentation for `git-check-ignore` only states that it works on files, I've found that it also works with directory paths, as well as treating any nonexistent path ending in a slash as a directory. For example, in a fresh repository containing only a .gitignore file with the pattern "foo/", `git-check-ignore` will accept the path "foo/" but not "foo", and if `mkdir foo` is run, it will accept both. > > However, I've found a case in which `git-check-ignore` deviates from the actual .gitignore behavior regarding ignoring directories. If .gitignore contains only the pattern "foo/*", then (regardless of whether a directory named "foo" exists or not), `git-check-ignore` will accept "foo/" but not "foo" — and yet, if you do `mkdir foo; touch foo/bar` and run `git status --ignored=matching --porcelain`, it shows "!! foo/bar", rather than "!! foo/" (which you get with the .gitignore pattern "foo/"), indicating that "foo/*" matches the contents of "foo" but not "foo" itself, in apparent disagreement with `git-check-ignore`. Is this a flaw in `git-check-ignore`, or should it just not be trusted in the first place when it comes to directories? > > These observations were made using Git version 2.36.1, installed via Homebrew on macOS 11.6.6, with test-tool compiled from commit 39c15e4855 of the Git source. > > Thank you for your time reading & responding, > > -- John Wodder >