为什么用 ! 仍无法保留被忽略目录里的文件?

父目录仍被排除时,针对文件的例外规则无法生效。添加更多例外之前,先检查目录规则。

1. 识别失败的规则

假设仓库根目录下有两个未跟踪文件:build/keep.txt 和 build/discard.txt。下面的规则排除了 build 目录本身,Git 不会继续遍历并寻找 keep.txt,后面的例外规则因此无法保留这个文件。

/build/
!/build/keep.txt

2. 忽略目录内容,再保留一个文件

将根目录 .gitignore 中上面的两条规则替换为下面的规则。它们允许 Git 遍历 build,忽略其直接内容,再重新纳入 keep.txt。此例只保留 build 中的一个直接子文件;若要保留更深层的文件,每一级父目录都必须允许遍历。

同一优先级内,最后匹配的规则决定结果,因此例外应放在排除规则之后。同时检查其他匹配规则及子目录中的 .gitignore。

/build/*
!/build/keep.txt

3. 验证两个文件的结果

创建上述两个示例文件后,在仓库根目录运行以下命令。详细输出中,keep.txt 应匹配 !/build/keep.txt,discard.txt 应匹配 /build/*。带 ! 的匹配表示重新纳入,不代表文件仍被忽略。

git check-ignore -v -- build/keep.txt build/discard.txt

状态输出应将 build/keep.txt 列为未跟踪文件,并省略 build/discard.txt。如果文件已被跟踪,请参考处理已跟踪文件的文章;忽略规则不会改变已有索引记录。

git status --short --untracked-files=all -- build/

如何忽略已经被 Git 跟踪的文件?

准确行为与更多细节请参阅官方说明: Git 官方文档 · git check-ignore 官方文档