Today I was asked why pattern
/folder/**/*.abc doesn’t work. The goal is pretty clear here – to ignore every file with
abc extension in the
folder and its subfolders.
Countless tries lead to nothing. Nevertheless here and there I’ve found several mentioning of the double-star pattern, so I thought there should be some way to get it working. Then I encountered this blog post. Mentioning slash in the pattern remembered me something and I rechecked gitignore(5) manual page:
- 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 .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file).
- 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.
Turns out git uses two different approaches to handling ignore pattern depending on slash symbol presence in the pattern! It was a surprise. After checking fnmatch(3) desctiption and sources I assured that double-star pattern is unsupported by
.gitignore. At least directly.
What git DOES support is hierarchical
.gitignore files, i.e. having several
.gitignores at different locations in the folder structure. So the equivalent solution to using
/folder/**/*.abc pattern would be placing another
.gitignore file into
/folder/ and having pattern
Well, I’d still prefer single
.gitignore if it is possible because it is easier to manage single file… but several of them also solve the problem well. And so be it.
UPDATE: Since git 1.8.4 according to the announce by JC Hamano (last point):
Use of platform fnmatch(3) function (many places like pathspec matching, .gitignore and .gitattributes) have been replaced with wildmatch, allowing “foo/**/bar” to match “foo/bar”, “foo/a/bar”, etc.
UPDATE2: msysgit (git on windows) supports this feature since version 1.8.2 according to RelNotes.