前言
首先說一下背景,通常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的提交歷史,發現我們是第一種情況導致的。
