在.gitignore路径匹配语法中,前导星号“** /”是多余的吗?

问题描述 投票:3回答:2

是否存在任何不能用没有星号的等效物替换的用法?

Two consecutive asterisks ("**") in patterns matched against full
pathname may have special meaning:

A leading "**" followed by a slash means match in all directories.
For example, "**/foo" matches file or directory "foo" anywhere,
the same as pattern "foo". "**/foo/bar" matches file or directory
"bar" anywhere that is directly under directory "foo".

A trailing "/**" matches everything inside. For example, "abc/**"
matches all files inside directory "abc", relative to the location
of the .gitignore file, with infinite depth.

A slash followed by two consecutive asterisks then a slash matches
zero or more directories. For example, "a/**/b" matches "a/b",
"a/x/b", "a/x/y/b" and so on.

Other consecutive asterisks are considered invalid.

https://git-scm.com/docs/gitignore#_pattern_format

让我指出,我只询问领先的星号/斜线冗余。因为看起来任何**/foo/bar都可以被简单的foo/bar取代

例如,我在.gitignore文件中有以下内容:

# NuGet Packages

# The packages folder can be ignored because of Package Restore
**/packages/*

# except build/, which is used as an MSBuild target.
!**/packages/build/

# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config

我想知道,为什么他们不能简单地写:

# NuGet Packages

# The packages folder can be ignored because of Package Restore
packages/*

# except build/, which is used as an MSBuild target.
!packages/build/

# Uncomment if necessary however generally it will be regenerated when needed
#!packages/repositories.config

https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

git gitignore glob
2个回答
6
投票

不,如果剩余的模式不包含斜杠,那么领先的**/只会过时。

https://git-scm.com/docs/gitignore的文档在我看来有点误导,正如它所述

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).

但实际上只匹配文件或目录的名称,而不是整个路径。

所以**/packages/build在任何深度都匹配packages/buildpackages/build因为它包含斜杠实际上与/packages/build相同,并且只与packages/build匹配与ignore文件相同的级别。

另一方面,build在任何深度匹配build,因此实际上与**/build相同。 而/build只匹配与忽略文件相同级别的build

它总是取决于模式(在删除尾部斜杠后,如果存在)是否包含任何斜杠。


2
投票

在问题中有一个错误的假设(但由于编辑而已经没有了)。为了证明这个问题:

$ 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
$ 

换句话说,为了让Git忽略foo/bar子目录中的文件sub,我们必须在顶级**/foo/bar中编写.gitignore,因为foo/barsub/foo/bar不匹配。

请注意,对于不包含嵌入斜杠的忽略条目,规则是不同的。那是:

$ echo bar > .gitignore
$ git status -uall -s
?? .gitignore
$ 

在这里,我们不需要领先的**/。因此,当要忽略的名称不包含其自己的嵌入式**/时,领先的/是多余的,但当要忽略的名称确实包含其自己的嵌入式/时,这并不是多余的。

有关奇怪的.gitignore规则的更长时间的处理,请参阅gitignore rules (applied to a codeigniter stack)

© www.soinside.com 2019 - 2024. All rights reserved.