小编典典

如何恢复多个 git 提交?

all

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

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

我想让分支的头指向A,即我想让B、C、D和HEAD消失,我想让head成为A的同义词。

听起来我可以尝试重新设置基准(不适用,因为我已经在两者之间推送了更改),或者恢复。但是我如何恢复多个提交?我要一次恢复一个吗?顺序重要吗?


阅读 255

收藏
2022-02-25

共1个答案

小编典典

扩展我在评论中写的内容

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

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

您有以下情况:

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

(这里的箭头指的是指针的方向:提交情况下的“父”引用,分支头(branch ref)情况下的顶部提交,以及 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 for all of them"

适用于除合并提交之外的所有内容。


另一种解决方案是检查提交 A 的 内容 ,并提交此状态。也适用于合并提交。但是,添加的文件不会被删除。如果您有任何本地更改git stash,请先进行:

$ git checkout -f A -- . # checkout that revision over the top of local files
$ git commit -a

那么你会遇到以下情况:

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

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


Jeff Ferland 的替代[解决方案,由 Charles Bailey修改,基于相同的想法,但使用git
reset
。在这里稍作修改,这种方式适用于一切:

$ git reset --hard A
$ git reset --soft D # (or ORIG_HEAD or @{1} [previous location of HEAD]), all of which are D
$ git commit
2022-02-25