前言
首先说一下背景,通常java项目中都会有多套环境,分别用来开发,测试和上线。通常也会有多个分支,今天我把dev的代码合并到master的时候,无意中发现合并完之后,dev和master的application.properties文件同一行竟然存在差异。
排查
刚开始我以为自己操作流程有问题,就又重新merge了一次,结果merge完之后还是存在差异。
然后我就懵逼了,因为在我的小脑袋瓜子里,merge就是根据文件的差异进行合并,如果dev分支merge到master,那么merge完之后,master和dev应该是一个包含关系(master分支包含dev分支)。
但是很显然,结果并不是这样,merge完之后,竟然会存在同一个文件的同一行不同!
在网上搜了一下,有人遇到类似的情况,像: https://segmentfault.com/q/1010000015337810/a-1020000015338262
但是并没有人能给出明确的答案,看起来大家似乎都挺懵。到这里似乎阻断了。
正好一个同事路过,跟他说了一下这个现象,他说了一句颠覆我认知的话:git merge不是根据文件的差异来的,是根据提交来的。
结论
我举个例子来大致解释一下他说的话:
就算master分支和dev分支同一个文件中的同一行存在差异,但是只要在dev分支上你在上一次merge到这一次merge之间没有对这一行做过改动(注意:换行也算改动),那么这一次merge的时候git将不认为它们是冲突。
理论上说这种情况很难出现,因为dev通常是基于master分支新建的,不会存在dev分支和master分支同一个文件同一行存在不同,而且dev分支上还没有对这一行做过改动。
但是仅仅是理论上,我仔细梳理了一下,目前想到的有两种操作会导致这种现象的发生:
-
从master分支上拉出dev分支之后,又对master分支做了改动,且push到了远程仓库,这个时候如果dev分支不做改动,那么从dev合并到master将不会有任何冲突。
-
上一次dev分支merge到master的时候,出现了冲突,但是解决冲突的时候使用了master分支的代码。而且dev分支在上一次merge到这次merge之间没有对该冲突的代码做过改动。
我看了git的提交历史,发现我们是第一种情况导致的。