【git命令】git merge

fast-forward

如果待合并的分支在当前分支的下游,也就是说没有分叉时,会发生快速合并,从dev分支切换到master分支,然后合并dev分支。

git checkout master
git merge dev

注意:而我们平常什么都不加的时候,则使用默认的 --ff , 即 fast-forward 方式。

 

 

 

 no-ff

如果我们不想要快速合并,那么我们可以强制指定为非快速合并,只需加上--no-ff参数

git checkout master
git merge –no-ff dev

这种合并方法会在master分支上新建一个提交节点,从而完成合并。

 

当要合并两个分叉的分支时,此种merge的方式是将待合入分支和当前分支不同的部分,在当前分支新建节点,如下图所示:

 

 

执行合并时,如果设定了non fast-forward选项,即使在能够fast-forward合并的情况下也会生成新的提交并合并。

non fast-forward合并

执行non fast-forward后,分支会维持原状。那么要查明在这个分支里的操作就很容易了。

squash

svn的在合并分支时采用的就是这种方式,squash会在当前分支新建一个提交节点。squash和no-ff非常类似,区别只有一点不会保留对合入分支的引用。

git checkout master
git merge –squash test

 

 

 假设在master分支的B点拉出一个新的分支dev,经过一段时间开发后:

  • master分支上有两个新的提交M1和M2。
  • dev分支上有三个提交D1,D2,和D3。

 

 

根据字面意思,这个操作完成的是压缩的提交;解决的是什么问题呢,由于在dev分支上执行的是开发工作,有一些很小的提交,或者是纠正前面的错误的提交,对于这类提交对整个工程来说不需要单独显示出来一次提交,不然导致项目的提交历史过于复杂;所以基于这种原因,我们可以把dev上的所有提交都合并成一个提交;然后提交到主干。
git checkout master
git merge --squash dev

 

在这个例子中,我们把D1,D2和D3的改动合并成了一个D。

注意,squash merge并不会替你产生提交,它只是把所有的改动合并,然后放在本地文件,需要你再次手动执行git commit操作;此时又要注意了,因为你要你手动commit,也就是说这个commit是你产生的,不是有原来dev分支上的开发人员产生的,提交者本身发生了变化。也可以这么理解,就是你把dev分支上的所有代码改动一次性porting到master分支上而已。

 

合并冲突

接下来,假设,存在3个分支issue2issue3main分支,现需要合并到主分支,首先,切换到main,并使用快进合并,来合并issue2

$ git checkout main
Switched to branch 'main'
$ git merge issue2
Updating b2b23c4..8f7aa27
Fast-forward
myfile.txt |    2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)

现在的历史记录如下:

接下来,尝试将issue3合并到main中:

$ git merge issue3
Auto-merging myfile.txt
CONFLICT (content): Merge conflict in myfile.txt
Automatic merge failed; fix conflicts and then commit the result.

在这种情况下,git已识别出冲突,因为myfile.txt文件在每个分支上的同一行中具有不同的内容,并且无法自动将issue3main合并。

myfile.txt文件现在看起来像这样:

Anyone can learn Git with this tutorial and Backlog
add: Register a change in an index
<<<<<<< HEAD
commit: Save the status of an index
=======
pull: Obtain the content of a remote repository
>>>>>>> issue3

您会发现 Git 添加到myfile.txt文件的标记,以及有关冲突的信息。我们必须手动修复冲突,如下所示。

Anyone can learn Git with this tutorial and Backlog
add: Register a change in an index
commit: Save the status of an index
pull: Obtain the content of a remote repository

解决冲突后,提交更改:

$ git add myfile.txt
$ git commit -m "merge issue3 branch"
# On branch main
nothing to commit (working directory clean)

历史记录将如下所示:

您可以看到,由于冲突的解决,一个新的合并提交已经被创建。主分支现在指向最新的合并提交。这是一个非快进合并。

参考资料

1. git merge的三种操作merge, squash merge, 和rebase merge

2. 图解4种git合并分支方法

3. 解决合并的冲突

 

posted @ 2021-06-21 21:45  苏格拉底的落泪  阅读(436)  评论(0编辑  收藏  举报