协慌网

登录 贡献 社区

如何恢复多个 git 提交?

我有一个 git 存储库,如下所示:

A -> B -> C -> D -> HEAD

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

听起来我可以尝试改变(不适用,因为我推动了之间的变化),或者还原。但是如何恢复多个提交?我一次还原一个吗?订单重要吗?

答案

扩展我在评论中写的内容

一般规则是您不应该重写(更改)您已发布的历史记录,因为有人可能已将其工作基于它。如果您重写(更改)历史记录,则会在合并更改和更新时遇到问题。

所以解决方案是创建一个新的提交 ,它可以恢复你想要删除的更改 。您可以使用git revert命令执行此操作。

您有以下情况:

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

(这里的箭头指的是指针的方向:提交时的 “父” 引用,分支头(分支引用)的顶部提交,以及 HEAD 引用的分支名称)。

您需要创建的内容如下:

A <-- B  <-- C <-- D <-- [(BCD)^-1]                   <-- master <-- HEAD

其中 “[(BCD)^ - 1]” 表示恢复提交 B,C,D 中的更改的提交。数学告诉我们(BCD)^ - 1 = D ^ -1 C ^ -1 B ^ -1,所以您可以使用以下命令获取所需的情况:

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message"

替代解决方案是检查提交 A 的内容 ,并提交此状态:

$ git checkout -f A -- .
$ git commit -a

那么你会遇到以下情况:

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

提交 A' 与提交 A 具有相同的内容,但是是不同的提交(提交消息,父项,提交日期)。

由 Charles Bailey 修改的 Jeff Ferland解决方案建立在同样的想法上,但使用git reset

$ git reset --hard A
$ git reset --soft @{1}  # (or ORIG_HEAD), which is D
$ git commit

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

考虑到你的例子,你必须这样做(假设你在分支'master'):

git revert master~3..master

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

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

干净的方式,我发现有用

git revert --no-commit HEAD~3..

此命令仅使用一次提交恢复最后 3 次提交。

也不会重写历史记录。