如何从git存储库中追溯删除提交?

时间:2017-06-07 16:34:48

标签: git

我想从git存储库中删除提交。不是最后一个,因此git reset不会工作。

我有这个:A->B->C->D->...

现在我想只有

A->B->D->...

因此,我希望改变过去的方式,好像C从未存在过。

我该怎么做?

远程存储库可能存在的不一致问题(我可以完全控制它们)。如果提交ID也发生变化也不是问题。

2 个答案:

答案 0 :(得分:2)

使用git rebase -i B然后压缩您不想要的提交(但您要保留的更改;如果您不想要更改,请将其删除)(其中B是参考您要删除的提交的父级。)

您将获得以下内容

pick B Good commit
squash C Commit message I don't want, but whose changes I do want
pick D Good commit 

# Rebase B..D onto B
#
# 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

答案 1 :(得分:1)

如果您有一组简单的线性更改要复制到新提交,请使用Alejandro C.'s answer中的git rebase -i。如果没有,请不要将git rebase -igit rebase -p混合:它确实效果不佳。

相反,首先,使用git replace构建备用历史记录:替换要删除的提交之后的提交,其中替换的父级是您希望Git的下一次提交“看”当它使用替换时(默认情况下)。然后,一旦获得了所需的历史记录,就运行一个否则为无操作git filter-branch来复制提交。像Git的其他部分一样,复制的提交将使用替换中的“假装历史记录”,因此他们实际上将其作为真实的历史记录,并且当git filter-branch成为分支时名称指向新复制的分支提示,替换历史记录现在将 实际历史记录。

(然后,与任何git filter-branch操作一样,您必须清除refs/original/个引用。如果您将它放在一个临时备用存储库中,所有这一切也是明智的。:-) )