gitignore 文件忽略了错误的目录

gitignore file is ignoring the wrong directory

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

gitroot/
└── docker/
    └── critical_dependencies/

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

docker/critical_dependencies/* 

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

只需将它添加到 .gitgnore docker/critical_dependencies/ 它应该可以工作,因为已经添加的文件用 git rm -r --cached docker/critical_dependencies/ 删除它们*

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

cd 到 .gitignore 文件所在的目录。或者您通常的项目根目录。从此处检查关键依赖项 文件夹的路径。

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

docker/critical_dependencies/

应该可以。

Git 不显示空目录 - 所以如果您需要解决方法,请查看第二个答案 here.

发现了类似的问题 here

希望对您有所帮助。

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

gitroot/docker/critical_dependencies/.gitignore

包含两行:

*
!.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 从工作树中复制那个文件,在那里你可以编辑和使用它, 索引。如果之前索引中有副本,则更新副本。如果没有,则将新副本放入索引。无论哪种情况,next commit 现在将拥有文件的最新版本。在您 运行 git commit 之后,索引 仍然拥有所有这些文件 ,其形式与之前相同你 运行 git commit。所以根据定义,所有这些文件都被跟踪:一个文件被跟踪当且仅当它在索引中。)

现在,我们可以看看 .gitignore 到底做了什么。 它不会让Git忽略文件。它所做的是让Git停止抱怨文件,并且如果这些文件不在索引中,请避免将它们复制到索引中。

换句话说,如果文件被跟踪,则不能忽略它。

如果文件未被跟踪,则它不在索引中。如果那个未跟踪的文件 标记为 "ignored",Git 不会抱怨它,也不会将它添加到 索引。 这就是 .gitignore 的大部分内容:.gitignore 中列出的未跟踪文件都变得未跟踪 被忽略,但被跟踪文件不受影响。

最后,这给我们带来了答案:

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

在这种情况下,您可以在 目录中创建一个名为 .gitignore 的文件:

gitroot/docker/critical_dependencies/.gitignore

这个文件的内容可以是:

*

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

*
!.gitignore

这表示 "ignore everything in this directory ... but wait a minute, don't ignore .gitignore though; ignore everything except .gitignore"。

接下来,您需要确保 this 文件 is 在索引中。这样它将在您所做的 next 提交中。我们刚刚放入的内容也是正确的内容,所以让我们git add它:

git add gitroot/docker/critical_dependencies/.gitignore

现在你知道我们为什么说 "don't ignore .gitignore" 了:我们 想要 git add 将它复制到索引中,即使它还不存在,所以我们告诉git add 这个特定的文件 不是 我们希望保留在索引之外的文件。

一旦它实际上 索引中——即使没有 !.gitignore 行,我们也可以强制它发生——即使内容说忽略它也没关系,因为届时它将被 tracked 并且其内容不会对其产生任何影响。但这使得第一次进入索引变得容易。

此外,这意味着如果我们克隆存储库并检查此特定提交,Git 必须写入文件:

gitroot/docker/critical_dependencies/.gitignore

某处,为此,Git 必须创建 目录。这样您就创建了目录。

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

但是等等!,你可能会反对,那不会删除文件吗也来自工作树?

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

您现在可以使用 git rm --cached 避免这种情况。这告诉 Git 在不触及工作树的情况下从索引中删除这些。但是如果你 git checkout 提交 所有这些文件,它们将进入你的索引。您的索引包含您签出的任何内容,因此它将进入您所做的 next 提交,在从这个旧提交开始的新 b运行ch 上。然后,您可以 git checkout 稍后提交 没有 这些文件,并且 Git 将删除它们...... 移除 个。

这就是为什么您要小心不要添加不应该添加的文件的原因。一旦你这样做了,你就会有一些提交永久保存在你的存储库中,如果你签出这些提交,这些文件将被跟踪。从一个这样的提交转到另一个没有文件的提交,它们将再次变得无法跟踪,但它们会那样做,因为 Git 将从索引 工作树。

最后一条捷径(虽然对以后的工作来说同样痛苦)

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

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

and then create the .gitignore file with the two lines and git add and git commit it.