关于git:gitignore文件忽略了错误的目录

gitignore file is ignoring the wrong directory

我有一个简单的目录结构:

1
2
3
gitroot/
└── docker/
    └── critical_dependencies/

我只想忽略critical_dependencies/目录的全部内容。我的.gitignore文件有以下条目:

1
docker/critical_dependencies/*

它似乎没有忽略该目录中的任何文件夹。要求.gitignore文件忽略子目录中的所有内容的正确方法是什么?


首先,确保.gitignore文件在工作目录中。如果你把它放在.git(存储库)目录中,它就不起作用。

cd到.gitignore文件所在的目录。或者项目的常规根目录。从这里检查关键依赖项文件夹的路径。

然后执行一个cat .gitignore并将您的确切路径添加到文件中,如下所示:

1
docker/critical_dependencies/

它应该起作用。

Git不显示空目录-因此如果需要解决方法,请查看这里的第二个答案。

这里也发现了类似的问题。

希望这有帮助。


只需将它添加到.gitgnore docker/critical_dependencies/it就可以了,因为已经添加的文件会使用git rm-r——缓存docker/critical_dependencies删除它们。/*


您必须删除(使用git rm --cached文件)任何现有的跟踪文件,然后您的.gitignore对您有任何好处。之后,您可以创建一个文件:好的。

1
gitroot/docker/critical_dependencies/.gitignore

包含两行:好的。

1
2
*
!.gitignore

按照这个顺序,然后添加并提交它。原因见下文。好的。

(我假设当你说gitroot时,你的意思是你有一个名为gitroot的目录。如果没有,就把gitroot/从这条路上移开。)好的。描述

在使用.gitignore文件做任何明智的事情之前,您需要了解一些关于git的信息。好的。

首先,Git根本不跟踪目录。Git只存储文件。如果文件的路径名是d1/d2/file.ext,那么git会创建目录d1d1/d2,如果必须的话,这样file.ext可以在其中生存;但是git完全不记得d1d1/d2,它只知道它们必须在那里,这样file.ext可以在那里生存。好的。

第二,文件在git中被跟踪,如果并且仅当它现在在索引中。但是你至少看不到索引,不是用普通的命令。如果您想查看索引中的内容,可以使用git ls-files(使用--stage)查看更多内容。请注意,git ls-files从当前目录开始,不管它是什么,所以最好是位于您当时关心的任何内容的顶层目录中(例如,您的项目的根目录可以看到所有内容)。但是这个命令通常不是很有用:将索引中的内容与其他内容进行比较通常更有趣。当你遇到一个顽固的、棘手的案例,并且想看看索引中到底是什么的时候,它主要是有用的。好的。

(附带说明:索引包含下一次提交时要提交的文件。当您运行git add d1/d2/file.ext时,您告诉Git从工作树中复制该文件,在工作树中您可以编辑并使用该文件,将其复制到索引中。如果索引中以前有副本,则会更新副本。如果没有,这会在索引中放入一个新的。在这两种情况下,下一次提交都将拥有该文件的最新版本。运行git commit之后,索引仍然拥有所有这些文件,其格式与运行git commit时相同。因此,根据定义,所有这些文件都是被跟踪的:如果并且仅当文件在索引中时,才会对其进行跟踪。)好的。

现在,我们可以看看.gitignore真正做了什么。它不会使git忽略文件。它所做的就是让Git停止抱怨文件,并避免将那些文件复制到索引中,如果它们还没有在索引中的话。好的。

换句话说,如果一个文件被跟踪,它就不能被忽略。好的。

如果文件未被跟踪,则它不在索引中。如果未跟踪的文件也被标记为"忽略",Git不会抱怨它,也不会将它添加到索引中。这就是.gitignore的主要内容:.gitignore中列出的未跟踪文件既未跟踪又被忽略,但跟踪文件不受影响。好的。

最后,我们找到了答案:好的。

I would like to just ignore the entire contents of the critical_dependencies directory.

Ok.

在这种情况下,可以在该目录中创建名为.gitignore的文件:好的。

1
gitroot/docker/critical_dependencies/.gitignore

此文件的内容可以是:好的。

1
*

(一行由一个星号组成),但由于以下几个原因,这样做要好一些:好的。

1
2
*
!.gitignore

这表示"忽略此目录中的所有内容…但是等一下,不要忽略.gitignore;忽略除.gitignore以外的一切。好的。

接下来,您需要确保这个文件在索引中。这样的话,你下一次的承诺就是这样。我们刚刚放进去的内容也是正确的,所以我们来看看git add吧:好的。

1
git add gitroot/docker/critical_dependencies/.gitignore

现在你知道我们为什么说"不要忽略.gitignore":我们希望git add将它复制到索引中,即使它还没有到索引中,所以我们告诉git add这个特定的文件不是我们希望从索引中保留的文件。好的。

一旦它在索引中,即使没有!.gitignore行,我们也可以强制它发生,不管内容是否说要忽略它,因为它将在那时被跟踪,其内容不会对它产生影响。但这使得它很容易第一次进入索引。好的。

此外,这意味着如果我们克隆存储库并签出这个特定的提交,那么git必须编写文件:好的。

1
gitroot/docker/critical_dependencies/.gitignore

要做到这一点,Git必须创建目录。这样就可以创建目录了。好的。

不幸的是,我们还需要确保索引中没有该目录或该目录的任何子目录中的其他文件。所以现在我们需要慢慢地,痛苦地,在你在那个目录中的时候,每一个这样的文件,如git ls-files所列。好的。

但是等等!,您可能会反对,这是否也会从工作树中删除文件?好的。

是的,会的。糟透了,不是吗?-)好的。

现在可以使用git rm --cached来避免这种情况。这告诉Git在不接触工作树的情况下从索引中删除这些内容。但是,如果您使用cx1(11)提交所有这些文件,它们将进入您的索引。您的索引保存您签出的任何内容,以便它将进入您所做的下一次提交,在一个新的分支上,从这个旧的提交开始。你可以稍后提交没有这些文件的git checkout,而git将删除它们…这样,好吧,就把它们移走了。好的。

这就是为什么您要小心不要添加不应该添加的文件。一旦您这样做了,您的存储库中会永久保存一些提交,如果您签出这些提交,这些提交将使这些文件被跟踪。从一个这样的提交转到另一个没有文件的提交,它们将再次变为未跟踪的,但它们将以这种方式获得,因为Git将从索引树和工作树中删除它们。好的。最后一条捷径(尽管对未来的工作来说同样痛苦)

不需要在每个文件上手动运行git rm --cached,我们可以切换创建和添加.gitignore文件的顺序:好的。

1
2
$ cd gitroot/docker/critical_dependencies/
$ git rm -r --cached .

然后用两行和git addgit commit创建.gitignore文件。好的。好啊。