git的合并本质上是分支的合并。可以是同一个仓库下分支的合并,也可以是本地仓库的分支和远程仓库分支的合并。一般情况下不指定分支,都是默认操作master
分支。
git合并有两种方式merge
和rebase
。
以如下场景为例:版本1.0
发布后,A在本地开发,提交了版本a1
a2后准备push
。此时B已经将自己提交的版本b1``push
了,因此A需要先pull
,再push
。
pull
有两种操作:pull
和pull --rebase
分布表示两种合并方式:merge
和rebase
.
本文中两种结果的箭头方向可能与网上其他解释中的方向相反。因为本文用箭头表示提交顺序,而非用箭头指向上游仓库。私以为表示提交顺序更容易理解。
这是merge
的结果:
graph LR; A(版本1.0)-->B(版本a1) B-->C(版本a2) A-->M(版本b1) C-->X(版本ab) M-->X
合并之后可以很清晰的看出b1
是基于1.0
改动的,a1
也是基于1.0
改动的,并且基于a1
又产生了a2
改动,最后将两个改动合并。
这是rebase
的结果:
graph LR A(版本1.0)-->M(版本b1) M-->B(版本a1) B-->C(版本a2) C-->X(版本ab)
rebase
直译为变基——意思是改变基于的版本。
在这个场景下的体现是,本来1.0
是base
,a1
是基于1.0
的改动,rebase
后b1
变成了base
,a1
的改动就成了基于b1
的了。相当于有了一个追加的概念。
所以git pull --rebase
的操作实际上是:
1 | git fetch origin |
这样的合并,更像svn的合并。
merge是将第一参数合并进来,而rebase是将第一个参数设置为base
1 | git checkout master |
合并方式的选择
merge后的日志会准确保留发生过的一切,而rebase允许我们将日志修饰成“项目的构建过程”。
rebase适用场景:
- 在同一个分支上与团队其他成员代码的合并
merge适用场景:
- 与修复bug分支的合并
- 与功能分支的合并
- 开源项目与其他贡献者的合并
rebase解决合并冲突
1 | git rebase |