如何撤消两个功能分支之间的合并?

How to undo a merge between two feature branches?

好的,情况是这样的:我的两个同事开发了两个新功能(feature_1feature_2)。现在一个分支 feature_1 中有一些更改,另一位开发人员希望在他的分支 feature_2 中看到。于是他将分支【=14=】合并到他的分支【=15=】中。可以这样表示:

合并前:

P--o--o--o    master
\     
 \B--C--D    feature_1
  \
   \A--E      feature_2

合并后:

P--o--o--o    master
\     
 \B--C--D    feature_1
  \       \
   \A--E---M  feature_2

他推动合并提交,两位开发人员将继续在他们的分支上工作。

P--o--o--o--o--o--o    master
\     
 \B--C--D--o--o--o    feature_1
  \       \
   \A--E---M---o--o    feature_2

现在是时候将 feature_2 合并回 master 了。但是,如果我们这样做,所有来自 feature_1 的更改(至少来自上次从 feature_1 合并到 feature_2 的更改)将被合并回 master。但是由于 feature_1 还没有准备好,所以这不应该发生。

那么我们怎样才能从feature_2"unmerge"feature_1,让feature_1的提交不会被合并到master.

我尝试在 feature_2 上执行 git rebase master,但这只会删除合并提交 M,但会保留提交 B、C 和 D(或更详细的 B'、C'和 D') feature_2.

关于如何从 feature_2 中获取来自 feature_1 的提交有什么想法吗?我们不介意变基并强制推送或创建一个仅包含来自 feature_2.

的提交的新分支

更新(我的解决方案):

感谢@kan,他为我的合并问题提供了一个很好的解决方案。在我们还讨论的评论中,当发生从 feature_1feature_2 的多个合并时如何解决它。我在一个命令中找到了一个解决方案,这将达到目的。所以让我们假设,我们有以下场景:

P--o--o--o--o--o--o--o    master
\     
 \B--C--D--o--o--o--o    feature_1
  \       \     \
   \A--E---M--o--M2--o    feature_2

所以我们合并了两次。没有变基也必须做两次。第一个 - --onto M2^ M2,第二个 --onto M^ M。这可以用这个单一的命令来完成:

git rev-list --ancestry-path master..HEAD --merges | xargs -I % git rebase --onto %^ % feature_2

这基本上会获取范围 masterfeature_2HEAD 范围内的所有合并提交,并在 "from right to left" 上运行 rebase。所以它将首先使用 M2,而不是在 rebase 中使用 M。如果只有一个合并提交,也可以使用此命令,但是您可以简单地使用更短的 git rebase --onto M^ M 命令。

最明显的方法 - 执行 rebase -i 并手动删除 feature_1 的提交。如果提交太多无法手动过滤,请告诉我,我会更加努力地思考...

好的。更努力地思考... ;)

我建议,只有一个合并点 M。在这种情况下,您应该将合并提交之后的所有提交重新设置为合并点之前的提交。使用 git rebase --onto E M feature_2.

由于此特定合并已被推送,您将需要 revert the merge commit

git revert -m 1 <SHA-of-M>

如果您想再次重新引入来自 feature_1 的任何更改,您将不得不 还原 还原 ,但这是最安全的选择,因为它保留了你提交的历史。

澄清一下 "revert the revert":假设您已将此分支合并到 master。

P--o--o--o--o--o--o---F2 master
\                    /
 \B--C--D--o--o--o  /   feature_1
  \       \         /
   \A--E---M---o--R/     feature_2

如果你想将 feature_1 合并到 master,你必须首先恢复合并到 master 时的恢复提交(所以,你必须恢复 R提交)。

P--o--o--o--o--o--o---F2--R'-F1   master
\                    /     /
 \                  /     /
  \                /     /
   \A--E---M---o--R/     /        feature_2
    \       \           /
     \B--C---D--o--o--o/          feature_1