我有一个Git存储库,看起来像这样:

A <- B <- C <- D <- HEAD

我希望分支的头部指向A,即,我希望B、C、D和head消失,我希望头部与A同义。

听起来我可以尝试重新设置基础(不适用,因为我已经在两者之间进行了更改),也可以恢复。但如何恢复多次提交?我一次回复一个吗?订单重要吗?


当前回答

为此,您只需使用revert命令,指定要恢复的提交范围。

考虑到您的示例,您必须这样做(假设您在分支“master”上):

git revert master~3..master

或git revert B…D或git return D C B

这将使用B、C和D的反向提交在本地创建一个新的提交(这意味着它将撤消这些提交带来的更改):

A <- B <- C <- D <- BCD' <- HEAD

其他回答

这些都不适用于我,所以我有三次提交要恢复(最后三次提交),所以我做到了:

git revert HEAD
git revert HEAD~2
git revert HEAD~4
git rebase -i HEAD~3 # pick, squash, squash

工作起来很有魅力:)

可能比这里的其他方法不那么优雅,但我一直使用get-reset--hardHEAD~N来撤销多次提交,其中N是您想要返回的提交次数。

或者,如果不确定确切的提交次数,只需多次运行git-reset--hardHEAD^(返回一次提交),直到达到所需的状态。

这是Jakub回答中提供的解决方案之一的扩展。

我面临的情况是,我需要回滚的提交有些复杂,其中几个提交是合并提交,我需要避免重写历史。我无法使用一系列git-restore命令,因为我最终在添加的反转更改之间遇到了冲突。我最终使用了以下步骤。

首先,检查目标提交的内容,同时将HEAD留在分支的顶端:

git checkout -f <target-commit> -- .

(--确保<targetcommit>被解释为提交而不是文件;.指的是当前目录。)

然后,确定在回滚的提交中添加了哪些文件,因此需要删除这些文件:

git diff --name-status --cached <target-commit>

添加的文件应在行的开头显示为“A”,并且不应有其他差异。现在,如果需要删除任何文件,请暂存这些文件以进行删除:

git rm <filespec>[ <filespec> ...]

最后,提交回复:

git commit -m 'revert to <target-commit>'

如果需要,请确保返回到所需状态:

git diff <target-commit> <current-commit>

应该没有区别。

与Jakub的回答类似,这允许您轻松选择要还原的连续提交。

# Revert all commits from and including B to HEAD, inclusively
git revert --no-commit B^..HEAD
git commit -m 'message'

首先确保您的工作副本未被修改。

然后:

git diff --binary HEAD commit_sha_you_want_to_revert_to | git apply

然后就承诺吧。不要忘记记录还原的原因。