如何恢复到多个较旧的提交,包括合并,但在恢复提交的头部顶部有一个提交?

问题描述

我有一个这样的提交列表:

Author: xyz
Date:   Fri Jul 30 11:48:40 2021 -0700

    update tests

commit 76810c2bdf91cd84661fabb06f00f37fc0e6b264
Author: abc
Date:   Thu Jul 29 16:38:33 2021 -0700

    fix for issue

commit b9a1642c3d778524291c98895425aa0248ed5766
Merge: baeb6428 6b722171
Author: abc
Date:   Thu Jul 29 16:36:58 2021 -0700

    Merge branch

commit 6b722171718f7aa70236613c544d8ca9f6cdeea9
Author: abc
Date:   Thu Jul 29 17:15:02 2021 +0000

    Use new type

commit baeb642886c19135c6057fba94849768b5ffc5a3
Author: abc
Date:   Wed Jul 28 16:24:10 2021 -0700

    old commit 

我想回到旧提交,但包含一个提交 76810c2bdf91cd84661fabb06f00f37fc0e6b264。我该怎么做?

我为每个提交手动尝试了 git revert <hash> 并为合并提交尝试了 git revert -m 1 <merge hash> 但它没有按预期工作。此外,我有一长串要执行的恢复操作,手动执行它是一项繁琐的任务。有没有更简单的方法来做到这一点?

解决方法

这种情况有时会发生在我们团队的发布/集成分支上,其中某些功能的发布将被中止/取消,但那些已经在发布/集成分支上提交或合并。

来自your comment

我希望 A

与其尝试使用 git revert 寻找解决方案,我们宁愿这样做:

  1. D 上创建一个新分支
  2. 如果 B 是单个或一小组提交,只需 git cherry-pick 它/他们

按照您的示例中的哈希值,它将是:

# git checkout -b <new-branch-name> <old commit>
$ git checkout -b new-branch baeb642886c19135c6057fba94849768b5ffc5a3

# git cherry-pick <specific commit>
$ git cherry-pick 76810c2bdf91cd84661fabb06f00f37fc0e6b264

# make new branch available to rest of team
$ git push -u origin new-branch

现在我们有了 new-branch,它基于旧提交 + 在它之上的一次提交。如果您挑选的提交取决于 C 中不再包含的更改,则 cherry-pick 上可能会发生冲突。

D -> C -> B -> A [old-branch]
  \
   \-> B [new-branch]

请注意,这里没有真正恢复,因为带有您不再想要的提交的旧分支仍然存在。但至少在这里,人们的本地副本被搞砸的机会更少,因为他们只需要检查这个新分支。 (我们通常会保留old-branch一段时间作为参考,因为有时人们会改变主意......)。

要完成还原操作,我们可以简单地删除 old-branch,这会删除您不再包含在 new-branch 中的所有提交。这与 git revert 具有相同的破坏性影响,因此请注意您真的不再需要任何这些提交,尤其是合并的分支(您可能想要重新创建这些分支) .