Git 的 .gitignore 不适用于一个或多个星号限定符 +

Git's .gitignore does not work with one or more asterisk qualifier +

$ git version
git version 2.9.3.windows.1

我似乎在使用 .gitignore 中的 +(一个或多个)模式匹配器时遇到了问题。这是一个使用 +* 作为文件名中嵌入的数字的模式限定符的测试。我想在源代码管理中保留 Test.txt 并忽略 Test[0-9]+.txt 文件。

目录:

$ ll | grep Test
-rw-r--r-- 1 asdf 1049089      0 Apr  5 15:55 Test.txt
-rw-r--r-- 1 asdf 1049089      0 Apr  5 15:55 Test123.txt
-rw-r--r-- 1 asdf 1049089      0 Apr  5 15:55 Test1235.txt
-rw-r--r-- 1 asdf 1049089      0 Apr  5 15:55 Test124.txt

Git 忽略文件内容测试 1:

Test[0-9]+.txt

测试 1:

$ git status | grep Test
    Test.txt
    Test123.txt
    Test1235.txt
    Test124.txt

这应该已经过滤掉了第 2 到第 4 个文件。

Git 忽略文件内容测试 2:

Test[0-9]*.txt

测试 2:

$ git status | grep Test
    Test.txt

这应该已经过滤掉了所有文件。

为什么会这样?

.gitignore 仅支持 Glob 模式而不支持正则表达式。

这就是gitignore man page提到的:

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.
For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".

有关更多信息,请搜索 Glob 模式与正则表达式以查看差异。

.gitignore 文件使用的是 globbing,不是 正则表达式。所以使用 + 是无效的。

所以你的第二次尝试实际上更接近你想要的。

Test*.txt

这将过滤掉以 Test 开头和以 .txt 结尾以及介于两者之间的任何文件。但它也会捕获 Test.txt 本身,因为 glob 中的 * 可以是零宽度。

您拥有的可能是最简单的选择。

Test[0-9]*.txt

这将匹配 Test 后跟任何数字,然后是任何内容(包括无),然后是 .txt

所以它是不完美的,因为它也会匹配

Test1foo.txt

数字后面有非数字文本。但是您的要求有多具体将决定这一点。你也可以只添加一些模式,比如

Test[0-9].txt
Test[0-9][0-9].txt
Test[0-9][0-9][0-9].txt
Test[0-9][0-9][0-9][0-9].txt
Test[0-9][0-9][0-9][0-9][0-9].txt

如果您真的必须确定它是所有数字,那么只需选择多少个数字,并使用类似的多个条目使其成为一个非常具体的匹配项。