Git合并分支命令参数详解:git merge --ff

今天研究了一下git merge命令经常使用参数,并分别用简单的例子实验了一下,整理以下:git

输入命令git merge -h能够查看相关参数:工具

--ff  快速合并,这个是默认的参数。若是合并过程出现冲突,Git会显示出冲突并等待手动解决spa

--ff-only  只有能快速合并的状况才合并。若是合并过程出现冲突,Git会自动abort这次merge对象

--no-ff  不使用快速合并。会生成一次新的提交记录,这个记录只是标识在这里进行了一次merge操做(目前还没想到应用场景)ip

--squash  压缩合并。将待合并的分支的内容压缩成一个新的提交合并进来it

接下来分别模拟几种应用场景来举例说明,C表明一次提交,合并时都是将dev分支合并到master。ast

第一种状况:master分支切出dev分支后没有新的提交,也就是说只有dev分支有更新,能够快速合并的状况:cli

eg:master:C1 ← C2date

           ↑blob

  dev:       C3 ← C4

  1.执行:git merge --ff dev

  master:C1 ← C2 ← C3 ← C4

  dev:C1 ← C2 ← C3 ←C4

  结果:查看git log时master分支会看到dev分支上的全部提交,此时master和dev是同样的

  2.执行:git merge --ff-only dev

  结果同上。

  3.执行:git merge --no-ff dev

  git会提示让你输入这次合并的信息,而后生成一个特殊的commit。

  master:C1 ← C2 ← C3 ← C4 ← C5 (Merge branch 'dev')

  dev:C1 ← C2 ← C3 ←C4

  结果:master分支会比dev分支多一条提交记录,也就是刚才输入犯人合并信息

  4.执行:git merge --squash dev

  master:C1 ← C2 ← C5 (Merge branch 'dev')

  dev:C1 ← C2 ← C3 ←C4

  结果:这里的C5实际上是C3和C4的合并,若是只想合并dev的内容可是不须要它的提交记录就能够用这个参数

第二种状况,切出后master和dev分支均有更新,这种状况是最多见的。这里为了演示冲突,在C4和C5分别对一个文件进行了修改。

eg:master:C1 ← C2 ← C4

           ↑

  dev:       C3 ← C5

  1.执行:git merge --ff dev

  这时Git会告诉你产生了冲突并列出冲突的文件,查看文件时会列出具体冲突内容,这时要先解决冲突(若是使用Intellij Idea或Eclipse等工具,能够直接选择use ours/theirs,ours表明被合并分支即master,theirs表明合并分支即dev),而后将这些修改的部分提交,再执行merge操做。

  master:C1 ← C2 ← C3 ← C5 ← C4 ← C6 (解决冲突的那次提交)

  dev:C1 ← C2 ← C3 ←C5

  那么问题来了,Git是如何知道两个文件有冲突呢?

  这里先说下结论,有时间再补一篇文章单独说明说明。

  你们都知道在Git里每一个文件都是一个blob对象,这里先无论合并时怎么找到同一个文件在两个分支上的blob(其实若是文件没有更新,在两个分支上是指向同一个blob),假设如今已经到了比较阶段了,Git会拿两个文件来逐行进行对比,可是断定是否修改是经过相邻行来肯定的。也就是说文件a的第三行修改了,Git是经过第2行和第4行的对比来断定的,不信的能够先本身作实验验证。因为篇幅缘由,这里再也不赘述。

  2.执行:git merge --ff-only dev

  这时Git会检测到产生了冲突,因此提示:Not possible to fast-forward, aborting.    即取消此次merge操做。

  3.执行:git merge --no-ff dev

  结果同1,不过这里在解决了冲突执行commit操做后不用再进行merge操做了。若是再执行merge操做,它会提示:Already up-to-date.

  4.执行:git merge --squash dev

  master:C1 ← C2 ← C4 ← C6 (解决冲突的那次提交)

  dev:C1 ← C2 ← C3 ←C5

  这里解决了冲突并提交以后也不用再执行merge操做了。若是再执行merge操做会有两种状况:

  a.刚才解决冲突时选用了master分支的修改,那么仍是会提示有冲突须要解决。

  b.刚才解决冲突时选用了dev分支的修改,那么会提示Already up-to-date。

  对比发现,使用--squash参数时,若是有冲突,解决完冲突后只要两个分支不彻底同样,再执行git merge --squash时仍是会进行merge。但--no-ff就不会。

相关文章
相关标签/搜索