Are there any usages that can\'t be replaced by equivalents without asterisks?
Two consecutive asterisks (\"**\") in patterns matched against full
pathname m
There was (but isn't any more, thanks to editing) a faulty assumption in the question. To demonstrate the issue:
$ mkdir tignore
$ cd tignore
$ git init
Initialized empty Git repository in .../tignore/.git
$ git status -uall --short
$ mkdir sub sub/foo; touch sub/foo/bar; echo foo/bar > .gitignore; git status -uall -s
?? .gitignore
?? sub/foo/bar
$ echo '**/foo/bar' > .gitignore; git status -uall -s
?? .gitignore
$
In other words, to get Git to ignore the file foo/bar
within subdirectory sub
, we had to write **/foo/bar
in the top level .gitignore
, because foo/bar
does not match sub/foo/bar
.
Note that the rules are different for ignore entries that do not contain an embedded slash. That is:
$ echo bar > .gitignore
$ git status -uall -s
?? .gitignore
$
Here we do not need the leading **/
. So leading **/
is redundant when the name to be ignored does not contain its own embedded /
, but is not redundant when the name to be ignored does contain its own embedded /
.
For a longer treatment of the somewhat odd .gitignore
rules, see gitignore rules (applied to a codeigniter stack).
No, the leading **/
is only obsolete if the remaining pattern does not contain a slash except for a trailing one.
The documentation at https://git-scm.com/docs/gitignore is a bit misleading in my opinion, as it states
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).
but actually matches only against the name of a file or directory, not the whole path.
So **/packages/build
matches packages/build
in any depth.
packages/build
as it contains a slash is effectively the same as /packages/build
and only matches packages/build
on the same level as the ignore file.
On the other hand build
matches build
in any depth so is effectively the same as **/build
.
Whereas /build
only matches build
on the same level as the ignore file.
It always depends on whether the pattern (after removing a trailing slash if present) contains any slashes or not.