如何恢复到包括合并在内的几个旧提交,但在恢复提交的头部之上有一个提交?

How to revert to several older commits including merge but have one commit on top of the head of reverted commit?

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

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> 合并提交,但它没有按预期工作。此外,我有一长串要执行的还原操作,手动执行它是一项繁琐的任务。有更简单的方法吗?

这种情况有时会发生在我们团队的 release/integration 分支上,其中某些功能将 aborted/canceled 发布,但这些功能已经在 release/integration 分支上提交或合并.

来自 :

I want A <- B <- C <- D to be like B <- D

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

  1. D 上创建一个新分支
    • How do I create a new Git branch from an old commit?
  2. 如果 B 是单个或一小组提交,只需 git cherry-pick it/them

根据您示例中的散列,它将是:

# 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 与您不再想要的提交仍然存在。但至少在这里,人们的本地副本被搞砸的可能性较小,因为他们只需要检查这个 new-branch。 (我们通常会保留old-branch一段时间作为参考,因为有时候人们会改变主意...)。

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