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 |