2017-09-26 124 views
1

我最近创建了一个分支,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,但似乎似乎自动发生了?这种行为与快进有关吗?如果我不希望发生这种行为(即将更改从主分支引入分支而没有将分支溢出更改回主分支),该怎么办?

在此先感谢!

+1

你推你的分支到远程吗?还是仅限于本地? – 3D1T0R

+0

@ 3D1T0R:我已经将所有内容都推送到了远端。 – Anonymous

+0

在https://www.atlassian.com/git/tutorials/merging-vs-rebasing的教程中,“合并选项”下似乎表明,合并到主分支会自动让这个主点该分支,如果历史符合某一套标准? – Anonymous

回答

1

开始用masterbranchA,都与每个几个提交,branchA被检出(显示为*):

m1 - m2 - m3  <--- master 
\ 
    a1 - a2  <--- branchA* 

[编辑:更新的合并结果,每个评论,表明master不向前移动到合并提交自动]

然后合并成主branchA,示为合并提交a2m3:

m1 - m2 - m3  <-- master 
\   \ 
    a1 - a2 - a2m3 <-- branchA* 

合并的还原只是适用的变化“撤消”,它不会撤消实际的合并 - 显示为a2m3' :

m1 - m2 - m3  <-- master 
\   \  
    a1 - a2 - a2m3 - a2m3' <-- branchA* 

而且因为你这样做是恢复与branchA仍检出,然后branchA引用将指向新的提交,并且master ref仍指向m3提交。

您又添加了承诺:

m1 - m2 - m3  <-- master 
\   \  
    a1 - a2 - a2m3 - a2m3' - a3 <-- branchA* 

最后,当你签出master和合并在branchA,你猜到了,这只是一个快进,其转发master指向同一个commit为branchA。这是可能的,因为从m3到a2m3的合并链接仍然存在(回复没有移除它),所以master被认为是a3的父提交(对于a3有一个不间断的链)并且可以快进到它。

m1 - m2 - m3 
\   \  
    a1 - a2 - a2m3 - a2m3' - a3 <-- branchA/master* 

这是你试图合并branchAmaster,但得到的回应,这是“已经更新了”的地步。

现在,之前第二合流尝试,如果你已经签出masterbranchA合并前承诺至少一次,或其他人已承诺master遥控器上的,你拉下来,然后你的分支将有再次分道扬((想想新的m4承诺为m3的权利)。如果发生了这种情况,从branchAmaster的合并将是一次完全合并,而不仅仅是一个快进。


如何看待分支

关于如何看待分支机构对我的突破,是分支实际上只是一个参考提交 - 和技术上,所有的父母犯下连接到它。当你合并两个分支时,你只是创建了一个有两个父母的提交,而不是一个,此时没有两个分支,有一个 - 即使是分开的一系列提交,它们以前是分开的masterbranchA,不再分开 - 它们已经真正合并,现在两个分支都指代它们全部。


你还能做什么?

基于我认为你想做什么,你可以这样做:

警告:有“不好的事情可能发生(TM)”,如果你推到一个远程后更改的历史,其他人(TM)可以访问......但至少在这种情况下,只会重写branchA历史,不master

  1. 而不是恢复的master合并为branchA,只是重置branchA到事先提交a2

    git reset --hard <hash of a2> 
    

    复位这样的删除所有引用a2m3所以它实际上是从回购删除。它仍然会在您的回购中有一段时间,但除非您将散列保存在某处,否则将无法实现。 Git跟踪此类提交一段时间,然后垃圾收集并删除它们,如果它们不被重用足够长时间。

  2. 此时你会:

    m1 - m2 - m3 <-- master 
    \ 
        a1 - a2  <-- branchA 
    

    就像在合并之前。

+0

惊人的解释!对于“你还能做什么”的选项,是否会使用“重置”,然后是强制推送? 关于如何思考分支,这是否意味着合并BranchA-> master与合并master-> branchA是一回事? – Anonymous

+1

@匿名谢谢!要设置为先前的提交(或整个回购中的任何提交),您可以使用'reset'命令,是的。谷歌在软,复合和硬复位之间的区别。当你准备在遥控器上进行永久变更时,最后需要强制推动 - 你不需要每次在本地改变任何东西时就推动(事实上,当你正在进行改变和避风港的时候)所有的东西都没有经过测试,通常你不会推动,只保留一切地方,除非有人需要访问你的工作)。 – LightCC

+1

@Anonymous对于合并,不 - 如果一个在提交行中领先于另一个,那么只有后面的一个可以快进(即与前一个合并);实际上,我不确定它会在另一个方向上说些什么,但是某种错误或者需要强制标志。在这种情况下,您可能会更好地直接重置为所需的提交以便后退(请记住在推送后对远程用户的影响)。另外,如果没有首先标记主要提交或在那里创建临时分支,就不要倒退,否则可能会失去访问权限。 – LightCC

相关问题