• git merge的recursive策略和merge-base


     https://www.cnblogs.com/chaoguo1234/archive/2004/01/13/5351497.html

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

    cherry-pick,revert和rebase使用的3-way合并策略

     

      git中的cherry-pick,revert和rebase都使用的是3-way合并策略,下面就来看看这3个方法使用的merge-base,ours和theirs分别是什么。

    cherry-pick

      假如有如下的提交历史,使用命令git cherry-pick alt(当前branch是master),那么merge-base就是加阴影的commit 1,ours就是加阴影的commit 3,theirs就是加阴影的commit 2。

    revert

      假如有如下提交历史,使用命令git revert master~2,那么merge-base就是加阴影的commit 1,ours就是加阴影的commit 3,theirs就是加阴影的commit 2.

    rebase

      假如有如下提交历史,每一个提交都向一个文件a里面增加一行,比如commit 1向文件a里面写入1,commit 2向文件a里面写入2,依次类推。使用命令git rebase --onto master alt1 alt2时,merge-base,ours,theirs分别是什么呢?

    当使用rebase命令时,git如做如下3件事:

    1 确定要rebase的commit是什么,这里要rebase的commit就是alt1..alt2。alt1..alt2表示从alt2可reachable的commit当中减去从alt1同样可以reachable的commit,这里就是commit 10,commit11,commit12;

    2 使用一个匿名branch指向alt2

    3 将alt2 reset到新的base,即master

    如下图所示:

    接下来git会依次将commit 10,commit 11, commit 12 rebase到新的alt2上。如果在rebase commit 10发生了冲突,那么merge-base就是commit 6,ours就是alt2指向的commit 5,theirs就是commit 10。如果commit 10 rebase成功后的commit记为commt 10’(此时alt2会指向commit 10'),接下来rebase commit 11如果也发生了冲突,那么merge-base同样是commit 6,ours是commit 10',theirs是commit 11。当rebase完成之后如果所示:

    由于rebase之后commit 10,commit 11,commit 12没有被任何分支引用,它们最后会被git移除。

    rebase有一个特殊的情况如下图所示:

    如果运行命令git rebase --onto master alt1 alt2,要被rebase的commit应该是alt2上的commit 7,commit 8, commit 10,但是由于alt1(在git rebase --help中,alt1被称为upstream),上面也有commit 7和commit 8,它们对文件a所做的修改时一样的,这时,git只会rebase alt2上的commit 10,相应merge-base也会成为alt1上的commit 8,最后的结果如下图,rebase完成之后,虚线框中的commit 7,commit 8, commit 10同样会被git移除。

  • 相关阅读:
    任意数字 保留 两位 小数 PHP
    在JavaScript中处理JSON数据 jquery js 定义 json 格式
    相对定位 绝对定位 relative absolute position 图片定位a标签
    oracle: listener.ora 、sqlnet.ora 、tnsnames.ora的配置及例子
    python
    python
    python-判断alter是否存在
    python-IE浏览器调用
    Python语言编写脚本时,对日期控件的处理方式
    python报错UnicodeDecodeError:
  • 原文地址:https://www.cnblogs.com/bigben0123/p/13754302.html
Copyright © 2020-2023  润新知