git merge的recursive策略和merge-base

Posted chaoguo1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了git merge的recursive策略和merge-base相关的知识,希望对你有一定的参考价值。

    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命令来查看。

 

以上是关于git merge的recursive策略和merge-base的主要内容,如果未能解决你的问题,请参考以下文章

git merge和rebase的区别

Laravel JsonResource:array_merge_recursive():参数 #2 不是数组

array_merge_recursive — 递归地合并一个或多个数组

array_merge_recursive — 递归地合并一个或多个数组

Git分支管理策略

为什么会使用“git merge -s ours”?