如何撤消两个功能分支之间的合并?
How to undo a merge between two feature branches?
好的,情况是这样的:我的两个同事开发了两个新功能(feature_1
和 feature_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_1
到 feature_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
这基本上会获取范围 master
到 feature_2
的 HEAD
范围内的所有合并提交,并在 "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
好的,情况是这样的:我的两个同事开发了两个新功能(feature_1
和 feature_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_1
到 feature_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
这基本上会获取范围 master
到 feature_2
的 HEAD
范围内的所有合并提交,并在 "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