Git checkout 删除 gitignore 中的文件

14

我无意中将工作区配置文件追踪到Git仓库中。为了解决这个问题,我使用git rm --cached命令移除了这些文件,并将它们添加到.gitignore文件中。

现在每次我从该仓库中检出一个分支时,这些文件都会被删除。有没有办法避免这种情况发生?


1
你删掉了那些文件。现在你还在抱怨它们被删除了?我不明白。 - Gabriele Petronella
我希望Git忽略它们,而不是在我切换分支时每次都删除它们。 - aitkiar
1
每个分支都提交.gitignore文件吗? - Gabriele Petronella
2
@GabrielePetronella 现在为时已晚,git rm 提交意味着切换到该分支(从仍有版本控制的文件的分支)将导致 git 再次(正确地)删除这些文件。历史记录可能需要被重写。 - Tobias Kienzler
@Tobias 我知道了,很好的答案。 - Gabriele Petronella
1个回答

16
问题在于 git rm 提交存在于某些分支中,而不存在于所有分支中,这意味着当您从仍包含文件的一个分支切换到您已经使用 git rm 的另一个分支时,它将会正确地删除文件。实际上,您想要做的是从git的历史记录中删除文件,就像它们从未存在过一样,遵循此问题。但是请注意,这意味着需要重写存储库历史记录,因此首先您将不得不进行 git push --force ,其次,您将会使其他人感到不满,他们也在与此repo一起工作。 编辑如果无法重写历史记录,请确保在每个现有的分支上提交 git rm --cached 操作。但是请记住,检出该删除操作之前的修订版本(例如通过标记)仍然会导致不愉快的重新删除。 摘要:
  • 如果无法重写历史记录,请对每个分支提交 .gitignore + git rm --cached ,但请记住,检出任何以前的修订版本(例如通过标记)都将a)引发错误,因为 git 想要检出现有的未跟踪文件,并且 b)在切换回 HEAD 时会再次删除这些文件。
  • 如果您经常需要检出以前的修订版本(或者某些意外提交的文件包含敏感数据),则重写历史记录以避免此问题,但请注意,这将破坏其他人的克隆。
实际上,还有第三种可能性:对于每个分支,在新创建的分支中重写历史记录,同时向原始版本添加一个提交,删除所有文件(除了要忽略的文件1),并添加一个高度可见的文件解释混乱,并要求用户从现在开始切换到重写的分支并删除未重新编写的本地副本。

1这是因为您不希望删除其他用户的那些从一开始就不应该进行版本控制的文件版本,而且由于人们不会预期要切换回旧版本,所以这永远不会导致“文件已经存在”的错误。


请澄清一下,这不是关于从历史记录中删除文件的问题,而是关于在分支之间保持.gitignore一致的问题。 - Yuval Adam
@YuvalAdam 这确实涉及到从历史记录中删除文件 - 它们本来就不应该存在,而且跨分支将它们放在.gitignore中不会解决分支更改时的删除问题(尽管在每个分支上进行 git rm+ .gitignore 提交可以解决这个问题,并且如果许多用户访问仓库,则应优先考虑,即使以脏历史为代价…) - Tobias Kienzler
@aitkiar 您还需要在每个分支上进行一个 git rm --cached 提交,否则另一个分支虽然忽略文件,但仍会跟踪它们,当 git 切换到您已经执行了 git rm 的分支时,它将认为 "好的,现在我正在从一个文件仍然存在的分支切换到一个文件不存在的分支,所以我必须删除它们"。正如所说的那样,“更清洁”的解决方案是重写历史记录,以便这些文件似乎从未被跟踪过,但是这是否适用于您取决于谁还访问该存储库。 - Tobias Kienzler
@TobiasKienzler 你的解决方法证明了我的观点,你不需要从历史记录中删除,只需从工作副本中删除并忽略即可。此外,在许多存储库中,重写历史记录是绝对不可接受的。因此,唯一合理的选择是在主分支和所有(相关的)分支上进行前向删除并忽略。 - Yuval Adam
@YuvalAdam 部分同意 - 重写历史是一项严重的修改,应该仔细考虑。但正如所提到的,如果您使用解决方法,检出一个删除前的修订版本将会 a) 导致“此文件已存在”错误,并 b) 在切换回分支头后导致文件被删除。但正如您所说,与完全重写历史相比,这可能是一个较小的恶。 - Tobias Kienzler
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接