.gitignore 双星不能从中间目录递归工作?

.gitignore double star not working recursively from intermediate directories?

使用 git 版本 2.34.0.windows.1

我的存储库的根目录下有一个 /.gitignore 文件,其中通常怀疑扩展名被忽略(在这里它并不真正相关)。

树的一半(/a/b/c/.gitignore),我有另一个文件,我想说“递归地在这个目录下,忽略任何名为 devl 的目录,除了一个特定的文件扩展名直接里面”。所以我制定了以下规则:

devl/**
!devl/*.dat

不幸的是,这似乎不起作用 -- git 仍将文件 /a/b/c/d/devl/test/foo.bar 报告为未跟踪,未被忽略。 (它根本不会忽略 devl 目录树中的任何内容。)

我可以通过使用以下规则来解决这个问题,但据我从文档中可以看出,以上内容应该是合法的并且也可以工作:

/**/devl/**
!/**/devl/*.dat

这是为什么?是bug还是误会?

尝试以下操作:

**/devl/*
!**/devl/*.dat

它对我有用,并从 找到了答案。第一行忽略 devl 内的所有内容,第二行排除 .dat 个文件。

这个有效:

**/dev1/**
!**/dev1/*.dat

这个有效而 OP 无效的原因是 .gitignore 规则,如

也许以下两件事可以提供帮助:缓存和排序。

删除所有或特定文件的缓存

git rm -r --cached .
git rm -r --cached <your_file_name.ext>

更改顺序

Each line in a gitignore file specifies a pattern. When deciding whether to ignore a path, Git normally checks gitignore patterns from multiple sources, with the following order of precedence, from highest to lowest (within one level of precedence, the last matching pattern decides the outcome):

这一行很重要:最后的匹配模式决定结果

这似乎是 git 中的错误;我已将 report 发布到他们的问题跟踪器。

在不忽略文件之前,我会确保忽略文件夹。

如果忽略文件夹,则该文件夹内的任何 !myFile 都将不起作用。

因此,对于您的第二个嵌套 .gitignore,尝试:

**/devl/
!**/devl/**/         <=== Important
!**/devl/*.dat

话虽这么说,这应该在 Git for Windows 2.34.1(2021 年 11 月)中进行尝试,其中包括对 2.34.0

的回归修复

参见 commit 33c5d6c (19 Nov 2021) by Derrick Stolee (derrickstolee)
(由 Junio C Hamano -- gitster -- in commit 1bf2673 合并,2021 年 11 月 22 日)

dir: revert "dir: select directories correctly"

Reported-by: Danial Alihosseini
Signed-off-by: Derrick Stolee

This reverts commit f6526728f950cacfd5b5e42bcc65f2c47f3da654.

The change in f652672 ("dir: select directories correctly", 2021-09-24, Git v2.34.0-rc0 -- merge listed in batch #13) caused a regression in directory-based matches with non-cone-mode patterns, especially for .gitignore patterns. A test is included to prevent this regression in the future.

The commit ed495847 ("dir: fix pattern matching on dirs", 2021-09-24, Git v2.34.0-rc0 -- merge listed in batch #13) was reverted in 5ceb663 ("dir: fix directory-matching bug", 2021-11-02, Git v2.34.0-rc1 -- merge) for similar reasons. Neither commit changed tests, and tests added later in the series continue to pass when these commits are reverted.

很遗憾,您没有仔细阅读the documentation...

If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.

你的第一个模式 devl/** 中间有一个 /,所以它是相对于目录 /a/b/c/.

因此,/a/b/c/devl/test/foo.bar应该排除,而/a/b/c/d/devl/test/foo.bar不应该。