从历史记录中删除提交

226

我在我的代码中输入了一个脏话并将代码推到主分支。之后我又推送了几次,以便人们不会拉取到那些坏的东西,但是我仍然可以在提交历史记录中找到那个脏话。

我不想将该文件添加到.gitignore中,因为我们需要它。

有没有办法从历史记录中删除该提交记录?


3
所以这里有一个重要的建议:在推送之前,始终逐个检查您的提交。一定要做到这一点。 - ckruczek
可能是 从 Git 历史中移除敏感文件和它们的提交 的重复问题。 - Andrew C
7
很有趣,因为这实际上也发生在我身上,但我没有注意到,直到太晚了。提交两周后,团队领导来找我谈话。 xD - Ariel
在这个答案中找到步骤。 - Suresh
4个回答

228

当你推送提交到代码库后,你真的不想去改变历史记录。但是,如果你绝对确定没有人在你提交问题之后从代码库中拉取或获取过任何内容,你有两个选项。

如果你想完全删除这个“坏”的提交(以及之后的每一个提交),请执行git reset --hard ABC命令(假设ABC是“坏”提交的前一个兄弟提交的哈希值-你希望将其作为该分支的新头部提交)。然后执行git push --force(或 git push -f)命令。

如果你只想编辑该提交,同时保留之后的提交,请执行git rebase -i ABC~命令。这将启动你的编辑器并显示包含有关提交列表的信息,从有问题的提交开始显示。将标志从“pick”更改为“e”,保存文件并关闭编辑器,然后对文件进行必要的更改,并执行git commit -a --amend 命令,接着执行git rebase --continue命令。最后运行git push -f 命令。

我要重申,只有在没有任何人使用包含你有问题的提交的拉取或获取操作时,才能使用这些选项。如果有人已经执行了这样的操作,执行这些步骤只会使情况更加恶化。


2
刚刚不小心在新创建的代码库中暴露了我的私人电子邮件。幸好,这让我松了一口气,谢谢。 - Liebster Kamerad
3
如果 git rebase --continue 或者 git push -f 给出了错误提示,请查看以下链接: https://dev59.com/qV0a5IYBdhLWcg3wVHMm#30471627 此外,以下链接也可能会有帮助: https://www.clock.co.uk/insight/deleting-a-git-commit - Sagar Patel
这对我有用,但需要注意的是所有已提交/未提交的更改也将在本地丢失。 - zyy
1
你也可以使用--force-with-lease标志代替--force,这样你就可以确保不会覆盖其他人的工作。 - K D

103
如果仅限于您的本地PC(或者没有人检查过您的更改):
  1. 使用:
git log

查找您要删除的提交。复制哈希值(长序列,例如:e8348ebe553102018c...)。

  1. 使用:
git rebase -i [hash]~

: for example
git rebase -i e8348~

只需要删除不需要的提交并保存文件即可。

互动式git rebase还可以让您修复损坏的提交-无需删除它。

如果您已将更改推送到服务器或其他人已获取了您的更改-请勿更改历史记录-这会给您的团队带来严重问题。


7
你能详细说明会引起什么严重问题吗?这是否肯定会发生? - Steven Zhou
2
抱歉,但“从不”并不正确。我们的大型组织必须使用filter-branch来修剪臃肿的代码库。 - Sridhar Sarnobat
强制推送到共享分支可能会删除其他人的工作。即使没有删除,如果有人从中分支出来,他将需要处理多个版本的历史记录,确保选择正确的版本,并小心不要集成两个副本。我认为这并不像很多人认为的那样严重,但是在强制推送时,请确保它只是一个短期的分支,只有您自己写入,并确保人们不太可能已经检出旧的历史记录或知道如何处理此问题。 - Fictional
4
我想对答案进行一处更正。您不应复制要移除的哈希值,而是应该复制要移除的哈希值的上一级哈希值,只有这样才能删除您想要移除的哈希值。 - Vijender Kumar
如果使用TortoiseGit,这里的答案很有帮助:https://dev59.com/dWcs5IYBdhLWcg3w1nhq - Venryx
这个答案只有在你还没有推送的情况下才有效,如果是这种情况,那我想更明确一些。再次克隆仓库,并使用您选择的手动合并程序(winmerge)将本地副本合并到新克隆的副本中。用一个提交将所有内容提交,不要使用脏话,并推送。 - NDEthos

99
这对我有效:
  1. git log 查找要删除的提交并复制其哈希值
  2. git rebase -i <commit_hash>~ 打开文本编辑器
  3. 在文本编辑器中,将特定提交从 pick 切换到 drop

16
使用明确的drop命令比仅仅删除行要更安全...这使它比被接受的回答更好。https://dev59.com/OVsV5IYBdhLWcg3wuxCM - Ray Foss
4
仅适用于本地提交而无需推送的情况。 - Timo
3
请问您能详细说明一下尾部波浪符的意义吗? - lfender6445
2
@Timo 就命令执行而言,即使本地提交已经被推送,这个解决方案也是正确的,需要强制推送(push -f)。然而,团队的工作流可能会阻止这种操作,因为它可能会给团队带来麻烦。 - thanos.a
2
我必须回到一个提交哈希之前的提交,才能在vim编辑器中查看该提交。 - apinanyogaratnam
显示剩余2条评论

5

这是要求的内容,请谢谢。 - PythoNic
1
你可以提供一个实例来说明如何操作,而不是只提供文档链接。文档链接并不足够面面俱到,如果有一个清晰的解释,则更容易理解。 - vicegax

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