wildmatch + fnmatch compatibility
- Date: Thu, 5 Oct 2017 10:07:16 -0400
- From: Zachary Newman <znewman01@xxxxxxxxx>
- Subject: wildmatch + fnmatch compatibility
I noticed a possible inconsistency in the documentation for
.gitignore; the pertinent bit is:
If the pattern does not contain a slash /, Git treats it as a
shell glob pattern
and checks for a match against the pathname relative to the location of the
Otherwise, Git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in
the pattern will not match a / in the pathname.
$ cd $(mktemp -d)
$ git init
$ touch '['
$ echo -e '.gitignore\n[' > .gitignore
$ git add --dry-run .
$ python -c "import fnmatch; print fnmatch.fnmatchcase('[', '[')"
Specifically, git *does not* match the string '[' while fnmatch
*does*. "Git treats it
as a shell glob pattern" could mean that the globbing is different
but 'test/[' exhibits the same behavior.
I believe this is the result of an inconsistency in between wildmatch
printf("%d\n", fnmatch("[", "[", FNM_PATHNAME); // prints 0,
indicating a match
printf("%d\n", wildmatch("[", "[", WM_PATHNAME); // prints -1,
While the way wildmatch handles this makes sense (it *is* a malformed pattern),
it doesn't square with the documentation for .gitignore .
There are a few ways that I can think of to resolve this:
* update the documentation to reflect that the syntax is similar but
not identical to
* update the behavior of wildmatch to match fnmatch.
* leave the behavior of wildmatch, but fall back to fnmatch if there's an error.
* decide that anybody who comes to depend on this behavior is already in
dangerous territory, and it's not worth addressing.
* decide that I'm wrong.
(As an aside: I trolled through the mailing list a bit but couldn't
find a rationale
for using wildmatch instead of fnmatch---it looks to be related to a desire to
support '**' patterns in .gitignore, maybe?)
 Specifically, I've tested on both a macOS (BSD) implementation and
Ubuntu (GNU) implementation of fnmatch. Additionally, if I'm reading the
specification right, it claims "If an open bracket introduces a
as in XBD RE Bracket Expression...it shall introduce a pattern bracket
expression....Otherwise, '[' shall match the character itself."
 There's one caveat: none of the older versions I tested with
ignore '[' either.
In particular, 220.127.116.11 just prints "ha!" (which seems like it
indicates an error) and
18.104.22.168 includes '['; both of these are before the 1.8.4 release, when
the cut over
to using wildmatch occurred.