【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后,分支会维持原状。那么要查明在这个分支里的操作就很容易了。
squash
svn的在合并分支时采用的就是这种方式,squash会在当前分支新建一个提交节点。squash和no-ff非常类似,区别只有一点不会保留对合入分支的引用。
git checkout master
git merge –squash test
假设在master分支的B点拉出一个新的分支dev,经过一段时间开发后:
- master分支上有两个新的提交M1和M2。
- dev分支上有三个提交D1,D2,和D3。
git checkout master
git merge --squash dev
在这个例子中,我们把D1,D2和D3的改动合并成了一个D。
注意,squash merge并不会替你产生提交,它只是把所有的改动合并,然后放在本地文件,需要你再次手动执行git commit操作;此时又要注意了,因为你要你手动commit,也就是说这个commit是你产生的,不是有原来dev分支上的开发人员产生的,提交者本身发生了变化。也可以这么理解,就是你把dev分支上的所有代码改动一次性porting到master分支上而已。
合并冲突
接下来,假设,存在3个分支issue2
和issue3
、main
分支,现需要合并到主分支,首先,切换到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
文件在每个分支上的同一行中具有不同的内容,并且无法自动将issue3
与main
合并。
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