前言
在敏捷开发过程中,需要时不时帮人review一下代码,不知道大家在帮人看代码的时候有没有遇到过下图这个情况?
一、merge产生原因
这个提交我们将它简称为任务A吧。由于任务A是自己拉了分支做的,做完要合并到主分支master,由于提交merge前发现合并有冲突(master分支在任务A开发期间又有别的任务B、C等合并进去,导致A合并时有冲突),然后开发者一般就会将master分支的改动merge过来任务A的分支,修改完冲突之后提交到任务A自己的分支,再提交merge request。
二、困惑
这个解决冲突的方案并没有什么问题,但是做codeReview的人会比较痛苦,因为这个任务A的提交不单单只有任务A的代码,还有解决和master分支合并冲突的代码,导致codeReview的人要点击多个提交来对比到底提交者真正做了什么修改,从而浪费比较多的时间去做codeReview。
三、解决方案
相信比较少的人会用到git rebase
,今天就详细讲讲如何用git rebase
去代替git merge
,令任务分支合并到master的merger提交里只包含任务自己本身的代码。
1、git rebase
和git merge
的原理和区别
git rebase
和 git merge
都是 Git 中两种常见的分支整合方式,它两的原理和区别不太一样,我整理了如下
特性 | git merge |
git rebase |
---|---|---|
原理 | 创建一个新的提交(commit),将两个不同的分支的历史合并在一起。 | 将一个分支的修改合并到另一个分支,但不会创建新的合并提交,每个提交都按顺序应用到目标分支上 |
Commit 历史 | 保留原始分支的提交历史 | 改写提交历史,形成一条线性历史 |
合并效果 | 产生新的合并节点 | 形成一条线性提交历史 |
冲突处理 | 可能在合并过程中有冲突,需要手动解决 | 可能会有冲突,通常在每个提交应用阶段解决 |
使用场景 | 适用于合并相对独立的分支,例如在不同的功能上进行开发的两个团队成员 | 适用于整理提交历史,保持整洁的线性历史 |
例如刚刚我说的任务A,如下图
css
commitA1---commitA2 任务A
↗
commitM1 master
开发者在提交任务A的merge request给master时,gitLab上发现冲突,然后把master改动拉到自己的A分支,修改完冲突,再重新提交merge request,会得到如下结果:
css
commitA1---commitA2-----------------commitMerge(解决冲突)----- 任务A
↗ ↘提merge,发现冲突 ↗拉取master去任务A ↘再提merge
commitM1---commitM2---commitM3--------------------------------------- master
这时候做任务A的codeReview的人会发现任务A有3条提交,分别是commitA1,commitA2和解决冲突的commitMerge。但是其实这个做codeReview的人真正想看的只有commitA1和commitA2,这时就可以让开发的人用git rebase
,然后得到如下结果:
css
commitA1-commitA2-发现冲突并修复-----------------------------------任务A
↗ ↗git rebase master ↗git rebase --continue ↘提merge
commitM1--commitM2--commitM3------------------------------------------master
⬇️
commitM1--commitM2--commitM3--commitA1--commitA2 任务A
这时候分支A上,master的改动commitM2和commitM3会设置到分支A之前,从而让分支A提交merge时仍然只有只有commitA1和commitA2的代码,大大减少了做codeReview的人的时间。
2、如何使用git rebase
git rebase master
- 如果有冲突,则去解决冲突
git add .
(解决完冲突执行这句,把变更添加到暂存区)git rebase --continue
(解决完冲突,git add .
后执行这句)- 这时候会弹出要你填写最新一次提交的备注,不修改直接退出按 esc + wq 即可
- git push -f(没有冲突的话,rebase后就可以直接执行这句了)
四、总结
这篇文章只是针对我最近团队在执行敏捷开发上产生的问题选择的解决方案,并不是说 git rebase
一定更好,选择使用 git merge
还是 git rebase
还是要取决于项目的具体需求和开发团队的工作流程。