从Git历史记录中删除和完全移除提交

8

我在 Git 历史记录中有一些提交

1.commit 4930da17d8dd23d650ed38435d8b421816a0c451
  Date:   Sat Dec 5 14:34:18 2015 +0530

2.commit e1ebbbb599ee20ebec3ca92c26266d9fd16e7ccc
  Date:   Sat Dec 5 13:22:20 2015 +0530

3.commit 1c4a11a80eb054d24dafec2efed0b0282188e687
  Date:   Sat Dec 5 12:11:50 2015 +0530

4.commit b4ab3c164a3a8d93e0a71a94b5c561cb5e20ebf6
  Date:   Sat Dec 5 12:09:56 2015 +0530

5.commit 167b1d10258381f09663ce61fa88ce3bbcd404c4
  Date:   Sat Dec 5 12:09:21 2015 +0530

6.commit c61bcadac673e1c83f4c14b66d56e23b12fa3198
  Date:   Sat Dec 5 12:07:58 2015 +0530

第三和第四个提交包含错误的代码,但我不知情地进行了提交和推送。

3.commit 1c4a11a80eb054d24dafec2efed0b0282188e687
  Date:   Sat Dec 5 12:11:50 2015 +0530

4.commit b4ab3c164a3a8d93e0a71a94b5c561cb5e20ebf6
  Date:   Sat Dec 5 12:09:56 2015 +0530

但第5和第6次提交包含正确的代码。我需要这个提交来工作。
5.commit 167b1d10258381f09663ce61fa88ce3bbcd404c4
  Date:   Sat Dec 5 12:09:21 2015 +0530

6.commit c61bcadac673e1c83f4c14b66d56e23b12fa3198
  Date:   Sat Dec 5 12:07:58 2015 +0530

现在我希望彻底删除并撤销第3和第4次提交所做出的所有更改。
我想要从git记录中删除第3和第4次提交,但不删除第5和第6次。
这样我的分支将是安全的。

如果你修复了它,就不必删除那些提交记录了。 - MCSI
完全不同。我确定。我想要删除。我不想要那两个提交。因为这个原因,我无法继续前进。 - vijay
2个回答

12
您可以使用“交互式变基”来回溯您的提交历史并以不同方式完成操作。要使用交互式变基,只需执行以下操作:
git rebase -i <commit_id>

<commit_id>是您想要编辑的最后提交的父级。执行此命令后,只需在您要删除的提交前面放置ddrop,甚至可以删除与该提交对应的行。

运行此命令会在您的文本编辑器中给出一个提交列表,其外观类似于:

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

交互式变基会给你一个脚本,它将从命令行上指定的提交开始,并从上到下重放每个提交引入的更改。它将以最古老的提交为首,而不是最新的提交,因为那是它要重播的第一个提交。
但是,由于你已经将分支推送到上游库,因此请向可能的同事通知这个历史记录重写,正如git文档所说:

再次记住,这是一个变基命令 - 包括在范围内的每个提交都将被重写,无论您是否更改了提交信息。不要包括您已经推送到中央服务器的任何提交-这样做会通过提供同一更改的替代版本来困惑其他开发人员。


在我看来,这是最好的选择。只需运行 git rebase -i HEAD~6 并将要删除的提交前的 pick 替换为 d。然后保存并关闭编辑器。 - Ali Dehghani
为什么要使用drop命令?drop命令在rebase -i的帮助文档中并没有被列为有效命令,但帮助文档明确表示删除或注释掉一行会将其从历史记录中移除。 - driusan
dropd 都可以,但你说得对,删除该行更自然~ - Ali Dehghani

7
你可以使用git rebase -i与历史记录进行交互式重写:
git rebase HEAD~6 -i 

打开你的编辑器,可以将多个提交压缩为一个,或者通过在编辑器中删除这些提交的行来完全删除它们。 ~6 表示重写最近的 6 个提交,-i 表示以交互方式进行操作。在你的情况下,你需要删除那些包含“pick 1c4a11a”和“pick b4ab3c”的行。
请注意,启动的编辑器中最近的提交是最后一行而不是第一行,由于你正在重写历史并且已经推送了,因此你还需要使用“git push --force”,而不仅仅是“git push”才能将你的更改发送到上游。

3
我正寻找的确切命令-四年后仍在挽救生命 :) - Town
1
同意!一定要使用 git push --force。 - ttemple

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