繁体   English   中英

将 master 合并到分支后,master 包含来自分支的更改

[英]Master contains changes from branch after merging master into branch

我最近创建了一个分支, branchA off of master来开发一个功能。 在开发此功能时,额外的提交被推送到master 我想将这些更改带入分支,所以在branchA ,我跑了

git merge master 

然后我在此基础上进行了更改 (B)。 但是,我后来意识到我将 master 合并到分支中的效果很差,所以我使用

git revert [hash of merge of master in branchA] -m 1

然后我重新应用了 B 的更改,提交了它。 最后,我将master重新合并到branchA

我对这次合并很满意,所以我想将branchA的更改引入master 令我惊讶的是,更改已经在master 当我检查了主人并跑了

git merge branchA

我看见

已经是最新的了。

这里发生了什么?

我来自 SVN 背景,所以我预计需要将branchA合并回master ,但似乎这似乎是自动发生的? 这种行为与快进有关吗? 如果我不希望发生这种行为(即,将更改从 master 拉入分支,而不会使分支的更改溢出回 master),该怎么办?

提前致谢!

masterbranchA开始,每个都有一些提交,并且branchA被检出(用 * 显示):

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

[编辑:根据评论更新合并结果,以表明master不会自动前进到合并提交]

然后将master合并到branchA中,显示为merge commit 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转发到与branchA相同的提交。 这是可能的,因为从 m3 到 a2m3 的合并链接仍然存在(还原没有删除它),所以master被认为是 a3 的父提交(有一个完整的链到 a3)并且可以快进到它。

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

这就是您尝试将branchA合并到master ,但得到的答复是“已经是最新的”。

现在,在第二次合并尝试之前,如果您在合并到branchA之前检查了master并至少提交了一次,或者其他人已经在远程提交了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

    就像合并之前一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM