递归地忽略特定目录内的所有文件,除了 .json 文件

Recursively ignore all files inside a specific directory except .json files

我有一个类似于下面的文件结构:

foo/bar.foo
node_modules/foo/bar.json
node_modules/foo/bar/foo.bar

我想要做的是忽略 node_modules 文件夹中除 json 文件之外的所有文件,这样我的存储库中就会有以下文件结构:

foo/bar.foo
node_modules/foo/bar.json

我试图找到一种简单的方法来做到这一点,但我还没有完全做到。

这是我在 .gitignore 中得出的结论:

# ignore everything inside node_modules
node_modules/*

# But descend into directories
!node_modules/**/*.json

达到预期结果的最优雅的方法是什么?

P.S。我不知道我在做什么。

gitignore 文档中,他们声明:

It is not possible to re-include a file if a parent directory of that file is excluded.

这提供了您的规则失败原因的直觉。您可以使用一些 xargs 魔法手动添加缺少的 json 文件。每当添加新包时,您都必须 运行 这样做,但是一旦它们被跟踪,一切都会正常工作。

 find node_modules/* -name *.json -print |xargs git add -f

我用 Git 2.18.0 进行了测试,并确认您忽略的目录中的文件在以这种方式添加后可以正常工作。对于被您的 .gitignore 规则排除的更深层次的路径,上面的 -f 参数是必需的。

您必须首先而不是忽略(排除)您忽略的目录的子文件夹。

# ignore everything inside node_modules
node_modules/**

# exclude or whitelist subfolders: note the trailing /

!node_modules/**/

# But descend into directories
!node_modules/**/*.json

请使用 git check-ignore -v -- afile 检查哪个规则仍将忽略您的文件。
并确保这些文件未添加到索引中 (git rm --cached -r node_modules)

好的,所以我终于找到了解决方案。诀窍是这样的:

# Ignore all the files inside the node_modules folder
node_modules/**/*.*

# Allow only json files inside the node_modules folder
!node_modules/**/*.json

问题是,通过 node_modules/*,它不仅会忽略文件,还会忽略文件夹。

正如 git 文档所说:

It is not possible to re-include a file if a parent directory of that file is excluded.

所以我 node_modules/**/*.* 只排除文件而不排除文件夹。

这样,!node_modules/**/*.json 实际上能够将 json 文件列入白名单。