a分支合并到b和b合并到a有区别吗

a分支合并到b分支和b合并到a有区别吗

一、背景

研究下关于 a 和 b 两个分支 a合并到b 和 b合并到a 有什么区别。

结论:不用纠结合并代码的时候谁合并谁,只是方向不一样

二、实验

有两个分支,分别是 feat_w8y 和 feat_617,最初都有共同的起始点,都是从c1这个revision(commit id)分叉出来的,feat_w8y分支上修改了代码向前进到c2 revision,而feat_617也修改同一行代码向前进到c3 revision。

由于修改了同一行代码,两个分支合并的时候会出现代码冲突。

现在来研究 “a合并到b” 和 “b合并到a” 有什么不同。

背景:

feat_w8y分支上将方法名由 getProfile 改成 getProfiles_byw8y

feat_617分支上将方法名改成 getProfiles_by617

  • feat_617上合并feat_w8y(即feat_617 <- feat_w8y),看到的冲突是

    在这里插入图片描述

  • 反方向合并(feat_w8y <- feat_617),得到

    在这里插入图片描述

可以看到,其实完全是一样的,只是变更的内容的位置反过来而已

结论:不用纠结合并代码的时候谁合并谁,只是方向不一样

三、额外补充:合并时注意事项

使用命令行合并(或使用IDEA图形界面合并也同样存在如下问题)

git merge abcgit merge origin/abc 是不同的含义的!

  • 一个是将本地的abc分支merge到当前分支,另一个是将origin的abc分支merge到当前分支

    意思是如果abc和origin/abc所处的revision不同,则最终的合并结果是不同的!!!

  • 另外非常非常非常需要注意的是 origin/abc 并不是远程的abc分支,而是本地的!!!

    意思是如果你不先git fetch 将远程的abc分支同步到本地 origin/abc 的话,合并出最终的结果是会有出入的!!!

    比如:如果你本地的origin/abc处于c1,而刚刚别人推送了c2到origin/abc,如果你不git fetch将本地的origin/abc更新到c2,则merge用的也是c1,会出问题的!!

  • 另外还有种写法 git merge remotes/origin/abc,我本以为这个一定能合并到最新的abc分支,可是我错了。它的执行效果跟 git merge origin/abc 是一样的!

以上使用IDEA图形界面操作了一遍,也存在这个问题。所以最终还是要有个好习惯,在merge代码的时候一定要先git fetch更新本地的,当你确认了本地的abc和orgin/abc是一样的时候,则随便用哪种方式merge都没问题。

四、思考

思考1:

有人可能看到这篇文章的时候会觉得做的实验这么少、例子这么少怎么能说明 “a合并b和b合并a相同只是方向相反、像镜子一样”。实际上,在生产中我是实验过的,是经过复杂的代码改变的验证的!!!

思考2

两个分支一定有一个共同的起点,这句话对吗?(共同起点指的是分叉出去之前共同的commit id)

我认为是正确的(但要排除掉这种对我们讨论无意义的情况:两个分支完全一样只是起了不同名字,或者由始到终都是合并后fast-forward这种,如 c1 -> c2 -> c3,a和b分支都在c3上,或者 “a分支在c2,b分支在c3”)

  • 可能存在多个分叉点,存在一个最近的分叉点

    在这里插入图片描述

    看图有两个主线,上面a分支,下面b分支
    
    可以看到分叉点是:c1,c6,c12
    汇聚点是:c6,c10
    结论:最近的分叉点是c12
    
思考3

如何看懂合并后的这些符号?
在这里插入图片描述

  • <<<<<<<======= 夹着的是HEAD的,=======>>>>>>> 夹着的是 feat_w8y 分支的内容

  • 什么是HEAD的?HEAD在这里就是指HEAD所指向的commit,其实就是当前所在的分支。比如截图就是在feat_617上执行merge命令合并feat_w8y,所以HEAD是指feat_617分支

可以看到GitHub自己的编辑器显示的就不是像 HEAD 这么难理解的,直接展示为分支名,如feat_617和feat_w8y
在这里插入图片描述

  • 可以使用 git status 查询有什么文件冲突,也可以搜索 <<<<<<< 定位到文件。

    下面是 git status显示的结果 Unmerged paths 列出的就是冲突的文件

    On branch feat_w8y
    Your branch is up to date with 'origin/feat_w8y'.
    
    You have unmerged paths.
      (fix conflicts and run "git commit")
      (use "git merge --abort" to abort the merge)
    
    Unmerged paths:
      (use "git add <file>..." to mark resolution)
            both modified:   src/main/java/com/wyf/test/test_pr_private/TestController.java
    
    no changes added to commit (use "git add" and/or "git commit -a")
    
  • 使用 <<<<<<< 搜索的时候,注意是7个这样的符号,你如果搜少于一半,可能会误判需要解决的地方数量。

思考4

使用命令的方式合并分支跟使用IDEA图形化的合并,哪个更有优势呢?

  • 比较差异的算法不同,有时候各自都会呈现比较奇葩的比较差异

    • 比如有时只在a行后面追加了新的一行b,硬是显示为删除a行并添加了a、b两行(其实diff算法足够好的话应该展示为新增b行)
  • 使用IDEA图形化一般更加直观,不过熟悉后其实两者差不多

  • 使用IDEA解决代码冲突,分三栏,中间是最终结果,两边分别是两分支的代码

  • 命令行和图形化解决代码冲突的过程比较明显的区别如下

    如果A文件有冲突,IDEA图形化除了将冲突的部分列出来,不冲突的部分也列出来;但是使用命令行合并,直接就帮你把没冲突图的部分解决好了(就是用新版代替旧版)

    什么是 “新版代替旧版”,就是新加的那行注释 “// 默认名字是default” 所在的revision比原来没有这个注释的revision要新,所以而且这个"变化"没有冲突所以就被自动应用了

    在这里插入图片描述

    在这里插入图片描述

补充

补充一个稍微更加复杂一些的合并
a分支合并到b分支,与b分支合并到a分支,看图,确实只是冲突内容调换了一下
在这里插入图片描述
在这里插入图片描述

如果使用IDEA图形化界面处理冲突,我也截了两个图
(其实也可以看到,实际也是调换了一下内容而已)
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值