git的合並策略總共有3種,一種是resovle,一種是recursive,一種是octopus。其中resolve和recursive適用於合並2個branch,octopus適用於合並3個或者3個以上的branch。對於這3中策略,都需要涉及到merge-base commit,ours commit和theirs commit,即3-way mege。
3-way merge
如下圖所示,假設要將branch B合並到branch A,那么branch A的tip commit就是ours commit,branch B的tip commit就是theirs commit,而兩個branch的公共commit(即圖中有陰影的commit)就是merge-base。合並的時候就是將theirs commit相對於merge-base commit的改變應用到ours commit上,並產生一個新的commit。

但是如果在應用theirs commit相對於merge-base commit的改變的時,在同一區域,ours commit相對於merge-base commit也做了改變,就會產生沖突。舉個例子,merge-base commit, ours commit,theirs commit里面都有同一個文件a,如下圖所示:

theirs commit相對於merge-base commit的改變是將1,3之間的2修改為5,而ours commit相對於merge-base commit在1,3之間也做了修改,即插入了8,所以合並的時便會出現沖突:
1
++<<<<<<<<<ours
+2
+8
++=========
+ 5
++>>>>>>>>theirs
3
+4
在出現沖突的同時,git會在index中記錄merge-base commit,ours commit,theris commit的相關文件,並以1,2,3標識,可以通過git ls-files -u命令查看。
merge-base
merge-base是branch之間的best common ancestor。common ancestor A比另一個common ancestor B better的條件是:B是A的ancestor。因此,一個best common ancestor沒有任何better common ancestor。舉個例子,如下圖所示:

branch A和branch B之間有兩個best common ancestor,就是圖中加陰影的commit 1和commit 2。又如下圖:

此時branch A和branch B的best common ancestor是加陰影的commit 3,而不是commit 1和comit 2,因為commit 3是commit 1和commit 2的ancestor。
利用git merge-base --all可以找出所有的best common ancestor。
recursive策略
merge的recursive 策略就是當兩個branch之間有多個best common ancestor的時,git先臨時合並這些best common ancestor,然后將這個臨時產生的commit作為merge-base來合並branch。如果產生了沖突,git仍然會在index中作記錄,也可以通過git ls-files -u命令來查看。
