我最近创建了一个branchA
分支master
来开发一个功能。在开发此功能时,其他提交被推送到master
。我想把这些更改带到分支中,所以在branchA
中,我跑了
git merge master
然后我提交了一个更改(B)。但是,我后来意识到我已经将主服务器合并到了分支中,所以我使用
恢复了提交。git revert [hash of merge of master in branchA] -m 1
然后我重新应用B中的更改,提交它。最后,我将master
重新合并到branchA
。
我对此合并感到满意,因此我想将branchA
的更改带到master
。令我惊讶的是,这些变化已经在master
。当我检查出主人并跑了
git merge branchA
我看到了
已经是最新的。
这里发生了什么?
我来自SVN背景,所以我原本希望将branchA
合并回master
,但似乎似乎已经自动发生了?这种行为与快进有关吗?如果我不希望发生这种行为(即将更改从主服务器转移到分支而不将分支的更改泄漏回主服务器中),该怎么办。
提前致谢!
答案 0 :(得分:1)
从master
和branchA
开始,每个都有一些提交,并且branchA
已签出(显示为*):
m1 - m2 - m3 <--- master
\
a1 - a2 <--- branchA*
[编辑:根据评论更新合并结果,以显示master
无法自动前进到合并提交中 < / p>
然后将master合并到branchA中,显示为merged commit a2m3:
m1 - m2 - m3 <-- master
\ \
a1 - a2 - a2m3 <-- branchA*
恢复合并只会应用&#34;撤消&#34;这些变化并没有撤消实际的合并 - 显示为a2m3&#39;:
m1 - m2 - m3 <-- master
\ \
a1 - a2 - a2m3 - a2m3' <-- branchA*
由于您在branchA
仍然签出后执行此恢复,因此branchA
引用将指向新提交,master
ref仍指向m3提交。< / p>
然后您添加了另一个提交:
m1 - m2 - m3 <-- master
\ \
a1 - a2 - a2m3 - a2m3' - a3 <-- branchA*
最后,当您检出master
并合并到branchA
时,正如您所猜测的那样,它只是一个快进,它转发master
指向与{{相同的提交1}}。这是可能的,因为从m3到a2m3的合并链接仍然存在(恢复没有删除它),因此branchA
被认为是a3的父提交(对a3有一个不间断的链)并且可以快进到它。
master
这是您尝试将m1 - m2 - m3
\ \
a1 - a2 - a2m3 - a2m3' - a3 <-- branchA / master*
合并到branchA
中的一个点,但得到的响应是&#34;已经是最新的&#34;。
现在,在第二次合并尝试之前,如果您已经签出master
并且在合并到master
之前至少提交了一次,或者其他人已经在远程设备上提交了branchA
而你把它拉下来,然后你的分支会再次发散(想想m3右侧的新m4提交)。如果发生这种情况,从master
到branchA
的合并将完全合并,而不仅仅是快进。
我对如何考虑分支的突破是,分支实际上只是对提交的引用 - 在技术上,所有与它相关联的父提交。当您合并两个分支时,您只是创建一个具有两个父项而不是一个父项的提交,并且此时没有两个分支,只有一个 - 甚至是以前分开的一系列提交{{1} }和master
,不再是分开的 - 它们已经真正合并,两个分支现在都引用它们。
根据我的想法,你可以做到这一点:
警告:有可能发生的坏事(tm)&#34;如果您在推送到其他人(tm)可以访问的远程数据后更改历史记录...但至少在这种情况下,它只会重写master
历史记录,而不是branchA
不要将branchA
合并到master
,只需将master
重置为之前的提交branchA
:
branchA
像这样重置会删除对a2m3的所有引用,因此它会从您的仓库中有效删除。它仍然会在你的回购中一段时间,但除非你在某处保存了哈希,否则将无法实现它。 Git跟踪这样的提交一段时间,然后垃圾收集并删除它们,如果它们没有被重复使用足够长的时间。
此时您将拥有:
a2
就像合并之前一样。