你可以使用git revert
来撤销合并。但需要注意的是,这样做会使未来的“重新合并”变得更加困难。仔细阅读你提供的链接中的信息,它详细说明了如何让未来的“重新合并”工作,但要注意它谈论的是将develop
合并到master
,而你说你是相反地将master
合并到develop
:
A -- B -- C -- D -- E <-- master
\ \
F - G - H - M <-- develop
在这种情况下(将master
合并到develop
而不是相反),您可以选择许多不同的选项,每个选项都有优点和缺点...
最简单的方法,如果可以的话我更喜欢用这个方法
(0) 什么也不做。如果合并C
和D
不破坏develop
分支,就保持现状。稍后,有人会 git checkout master
然后 git merge --no-ff develop
,然后得到这个结果(比如说,I
这个提交先添加到了develop
):
A -- B -- C -- D -- E -- M2 <-- master
\ \ /
F - G - H - M - I <-- develop
这里的merge
会查找自从从master
分离出来并且在B
上的develop
中所做的更改,它将在合并后放进F
、G
和H
,跳过任何来自master
(可能是全部)的M
的部分,并最终放入I
并生成合并提交M2
(因为提交E
,如果没有使用--no-ff
,也会生成合并提交M2
)。
一些易于实施但明显存在缺陷的方法
(1) 只需"重写历史记录":从分支develop
中删除提交M
。通知所有使用该分支的其他人即将发生的事情:提交M
将消失,他们应该采取适当的措施来处理此事。
(2) 停止使用旧名称develop
,创建一个新的分支名称develop1
或其他名称:
A -- B -- C -- D -- E <-- master
| \
| M <-- develop
\ /
F - G - H <-- develop1
这与选项(1)相同,只是提交 M
仍然存在,并带有分支标签,在其中,您具有指向提交 H
的新/不同的分支标签。您仍然需要通知所有人,但这可能会使他们的工作更轻松。当所有人都满意后,您可以稍后删除 develop
。
还原及其缺点
(3)还原合并。如链接文章中所述,让我们使用W
来表示新的还原提交:
A -- B -- C -- D -- E <-- master
\ \
F - G - H - M - W <-- develop
“W”中有什么?它包括一切必要的内容,以“消除合并效果”。在这种情况下,这意味着撤销了在“C”和“D”中所做的任何更改。到目前为止,情况还不错,develop
中只包含来自 F
, G
和 H
的更改。问题出现在以后——如果或者当有人执行以下操作:
git checkout master
git merge develop
第二个命令将寻找
master
和
develop
分支在哪里分离,也就是提交
B
,因此它会捡起从那时起的所有更改。这些更改包括
W
中的更改,这将撤消
C
和
D
,而这并不是你想要的。这可以在之后进行修复,但是谁合并代码必须知道这个等待他们的“删除
C
和
D
”定时炸弹。
请注意,这与“什么也不做”的选项(0)相同。这里的问题是
W
的
内容。在情况(0)中,您
想要提交
I
的内容,但在这里,您
不想要W
的内容。
另外一个选项:
这可能是最糟糕的选择,鉴于上面展示的情况,但我还是列出来吧:
(4)创建一个全新的分支,其中包含您要保留的提交的
副本,并将其命名为
develop
。(或者命名为其他名称,但那样我们就回到了上面类似于
develop1
的情况,您可能应该只使用那个。)您是选择保留
old-develop
分支还是放弃它(不加标签),取决于您,但我会在图中将其画出来:
F' - G' - H' <-- develop
/
A -- B -- C -- D -- E <-- master
\ \
F - G - H - M <-- old-develop
这在您提供的链接中已经有所描述。它只在更复杂的情况下才真正有用。