Git 忽略除特定文件之外的所有文件

Git ignore all files except particular ones

我的目录中有很多文件,我不希望它们被 git 跟踪。所以我想忽略除 .bashrc.gitignore.config/terminator/config 之外的所有文件。

我正尝试在 .git忽略:

中做类似的事情
*
!.gitignore
!.bashrc
!.config/terminator/config

.bashrc.gitignore 文件现在未被忽略,但仍然无法 .config/terminator/config 被忽略。我如何在 git 中执行此操作?

我有一种可能的解决方案,但还有没有指定子目录的更优雅的解决方案吗?

*
!.gitignore
!.bashrc
!.gitconfig

!.config/
!.config/terminator/
!.config/terminator/config

答案的简短版本是,一旦 Git 忽略了一些 目录 ,它就不再费心去查看 内部 [=88] =] 该目录,除非其他东西已经强制它这样做。1 要停止此操作,您必须明确列出您 想要忽略,有 ! 个条目:

*
!/.bashrc
!/.config
!.config/terminator
!.config/terminator/config
!/.gitignore

即:

*

告诉 Git:忽略所有内容,除非被覆盖。那么最终的:

!.bashrc

覆盖 .bashrc 的忽略规则,依此类推。但是 Git 所做的是它首先读取 . 以查找所有条目。假设它按字母顺序找到它们:.bashrc.config.editorthing.gitignore.history,等等;假设我们有您的原始 .gitignore 文件:

  1. 嗯,我看到了.bashrc,让我们检查一下...啊,第1行说忽略但第3行说不要,所以不要忽略。 结果:未被忽略。
  2. 现在我看到了 .config,让我们检查一下。第 1 行说忽略,第 2 行说 .gitignore,第 3 行说 .bashrc,第 4 行说保留 .config/terminator/config。它不是其中任何一个,所以第 1 行适用! 结果:被忽略!
  3. 重复以上步骤。

可以说,第 2 步中的操作是愚蠢的:如果较短的 .config 被忽略,显然不可能应用长规则,因此 .config/<something> 的存在作为未被忽略的应该触发Git 取消忽略 .config。事实上,最新版本的 Git 试图在这方面变得更聪明,但旧版本却没有:你必须明确取消忽略 .config(或 /.config,哪个更好在这里出于我不会进入的原因,但这就是我在上面那样写的原因2).

一个更优雅的技巧,但它会导致Git慢得多,所以你可能不想使用它。诀窍是显式取消忽略 all 目录:

*
!*/
!/.bashrc

等等。但是现在,如果你有一个目录 a,其中有数百万个子目录和文件 a,Git 将扫描所有 a及其所有子目录,而之前,它将跳过它。


1 索引 .config 中有一个文件 强制 Git 扫描 .config.但是,您会 运行 遇到与 .config/terminator 相同的问题,除非索引也包含 .config/terminator 中的文件。

2好的,我稍微讲一下。它不适用于这种特殊情况,但假设您取消忽略 .bashrc,如果 Git 出于某种原因扫描 a/,并且 a/ 包含一个名为.bashrc、Git 不会 忽略 a/.bashrc。不过,我们不需要 .config/terminator 上的前导斜线,因为 包含 一个 嵌入的 斜线(一个不在末尾)。这使得该名称的匹配有根,而 .bashrc 上的匹配没有根,因此匹配 a/.bashrc.