首页 > 解决方案 > Git忽略除特定文件以外的所有文件

问题描述

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

我正在尝试在 .gitignore 中做这样的事情:

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

.bashrc.gitignore文件现在被忽略,但仍然不能被.config/terminator/config忽略。我怎么能在 git 中做到这一点?

我有一种可能的解决方案,但是否有更优雅的解决方案而不指定子目录?

*
!.gitignore
!.bashrc
!.gitconfig

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

标签: gitgitignore

解决方案


答案的简短版本是,一旦 Git 忽略了某个目录,它就不再费心查看该目录,除非其他东西已经迫使它这样做。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 行是 about .gitignore,第 3 行是 about .bashrc,第 4 行表示保留.config/terminator/config。这不是其中的任何一个,所以第 1 行适用! 结果:忽略!
  3. 如上重复。

可以说,第 2 步中的操作是愚蠢的:如果忽略较短的规则,显然不可能应用长规则.config,因此.config/<something>as un-ignored 的存在应该触发 Git 到 un-ignore .config。事实上,最新版本的 Git 试图对此更加聪明,但旧版本却没有:你必须明确地取消忽略.config(或者/.config,这里更好,因为我不会进入,但这就是为什么我上面是这样写的2)。

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

*
!*/
!/.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是无根的,因此 match a/.bashrc


推荐阅读