本文将通过一系列步骤来研究merge与rebase并分析二者区别
步骤一:初始化提交
初始化git仓库 -> master分支首次提交A -> master分支提交B -> 新增并切换到dev分支 -> dev分支提交C -> 切换到master分支 -> master分支提交D
得到结果:
注意此时分支停留在master !!
步骤二:merge
将dev分支合并到master
git merge dev
得到结果:
此时dev分支的提交在分支切出来的地方合并到了master分支,并在master分支产生了新的提交E
步骤三:回退
- 回退代码到B
git reset B --hard
- 删除dev分支
git branch -d dev
得到结果:
步骤四:再来一遍
使提交走到D
注意此时分支还是停留在master !!
步骤五:rebase
将master分支变基到dev分支
git rebase dev
得到结果:
之前master分支的基是AB,由于进行了变基操作,现在基变成了dev分支的ABC,D仍然是master的最新提交。个人理解基是地基、基础的意思,指的是分支切出来之前的提交,进行变基操作相当于把地基换了,或者说偷家。变基并不会修改commit id,提交还是那个变基之前的提交。
结论
- merge是打补丁,将目标分支的差异提交( C )在切出分支的地方(B)向后插入,基不变(AB)
- rebase是挪地基,将目标分支的所有提交(ABC,基)替换掉切出分支前的提交,基改变(ABC)
- rebase其达到的效果跟merge一样是将两个分支的提交合并在一起,是变相的合并
- rebase跟merge不同的是rebase并没有产生新的提交E
补充:冲突时的处理
rebase和merge解决冲突的方式不一样,假设C和D冲突了:
- rebase方式合并代码由于基变了,ABC变成自己人,传入的更改指的是D,当前更改指的是C,merge则相反,传入的更改指的是C,当前更改指的是D。
- rebase对于有冲突的提交需要你一次一次的解决,每次解决时执行
git add .
以及git rebase --continue
直到没有任何提交与最新代码有冲突,而merge不一样,你只需要解决一次,这就是为什么需要多一个提交E的原因,方便你处理冲突 - 如果中途想要放弃解决冲突,rebase使用
git rebase --abort
,merge使用git merge --abort
或使用git reset B --hard
清空工作区