尽管git merge
是Git版本控制系统中最常用的命令之一,但它也存在一些缺陷:
- 非线性提交历史记录:
git merge
会在目标分支上创建一个新的合并提交(merge commit),该提交包含了所有待合并分支的提交。这样产生的提交历史记录通常呈现出一个分支图,有时比较复杂,不容易理解 - 无法控制合并方式:当两个分支有同样的修改时,
git merge
会自动进行三方合并,如果结果不如预期,需要手动解决冲突。虽然可以通过git merge --no-ff
禁止快进模式,强制生成合并提交,但是很难控制候选父提交和合并的方式,导致合并历史记录缺乏可读性和可控性 - 提交历史记录复杂:在更新代码库时使用
git merge
,可能会导致提交历史记录变得复杂。当两个或更多分支拥有不同的提交时,Git会创建一个新的合并提交,这会导致提交历史记录中出现大量的嵌套认证信息
总而言之,git merge
很可能会造成你的提交记录混乱不堪,无法理解,你的git log
可能会“不忍直视”,重点和非重点完全分不清楚。因此为了解决这个头疼的问题,就需要用到git rebase
操作了
下图是git merge
和git rebase
在完成合并时的效果对比
一:简介
git rebase
其中文名为“变基”,所谓“变基”指的就是改变基地。如下图,有两个分支master
和feature
,其中feautre
是从提交点B处从master
上拉出的新分支,之后,master
上有一个新提交M,而feature
上有两个新提交C和D
feature
分支是基于master
分支的B拉出来的新分支,所以feature
的基底是B。而master
在B之后有新的提交,rebase
变基就相当于此时要用master
上新的提交来作为feature
分支的新基底。如下图所示
如果再说简单点,rebase
的功能就是可以提取我们在A分支上的改动,然后应用在B分支的代码上,完成类似于补丁的功能
例如下图,C1是线上的版本,在C1的代码上线了以后我们发现了一个bug,于是checkout了一个叫做bugFix
的分支,与此同时还有新的功能在开发,新功能提交到了master
之后形成了C2。
这个时候我们在bugFix
分支除了可以git merge master
外,还可以git rebase master
,如果执行rebase
后那么Git
树会变成下面这样
因此,这个结果就好像是我们先到了C2然后checkout出了bugFix
分支,然后在bugFiX
分支上将之前的代码重新写了一遍,这样的操作就是变基。当我们rebase
后再提交合并请求,这样我们的提交记录就会变得十分干净,没有多余的merge
信息
二:应用场景
(1)应用场景1
场景:git rebase
的一个常见应用就是整合提交记录。其中git rebase -i HEAD~n
表示从当前最新提交记录开始向上合并n
条记录,具体用法下面演示
- 注意:合并时建议不要合并那些已经推送到远程仓库的记录
如下图,新建一个仓库用作演示
新建4个文件,生成4份提交记录
现在,我需要合并最新的3条记录为1条,于是执行git rebase -i HEAD~3
,然后会弹出下方界面
接着,将v3
和v4
前面的"pick"修改为"s",表示合并至前一条记录(修改后按wq
保存)
保存后又弹出一个界面,这是让你输入合并后的提交信息
输入后,保存即可
合并完成,查看提交记录
(2)应用场景2
场景:多分支开发在合并时往往会使得提交记录或者分支线过于复杂,所以git rebase
可以使开发线变得比较干净,但这样做也有缺陷,就是会使你的提交记录变得不那么清晰,所以这个还是要看具体场景
如下图,创建一个dev
分支然后切换过去
然后在dev
分支上创建一个dev.py
文件并提交
然后切换回master
分支,并在该分支上添加提交master.py
文件
按照我们之前学习的git merge
,现在就可以进行合并,然后也会产生一条记录,如下
为了展示后面的git rebase
,这里我们切换回dev
分支,然后把master
分支和合并过来
然后在dev
分支和master
分支上分别创建并提交文件dev1.py
和master1.py
现在我们尝试用git rebase
合并,首先需要切回dev
分支
接着执行git rebase master
,这便是变基操作
然后切换回master
分支,然后进行merge
现在查看提交记录,你会发现,相比于之前的分叉记录,现在的记录会处于一条线
三:注意事项
- 慎用
git rebase
:因为git rebase
会改变提交历史,因此在与他人合作或者公共分支上使用时需要格外小心 - 在
git rebase
过程中解决冲突:当在使用git rebase
合并分支时,可能会出现冲突。此时需要手动解决冲突并提交更改,然后使用git rebase --continue
继续进行rebase
操作 - 了解
rebase
和merge
的区别:git rebase
和git merge
都可以将一个分支合并到另一个分支上,但它们的处理方式不同。使用git rebase
可以将一个分支上的提交历史“移动”到另一个分支上,使得提交历史更加线性化,而git merge
则会保留原来的提交历史 - 确保备份数据:在使用
git rebase
进行分支合并时,最好先备份分支数据以防万一 - 小心使用交互式
rebase
:git rebase -i
可以进行交互式 rebase,可以更加精细地控制合并过程。但是,这种方法也更加容易出错,因此需要特别小心 - 遵循开发流程:在使用
git rebase
进行分支合并时,需要遵循团队的开发流程。例如,需要确保合并到主分支的代码经过了代码审查和测试,以确保代码的质量和稳定性 - 注意分支命名:为了避免混淆和错误,在使用
git rebase
时,需要给分支取一个具有描述性的名称,以便更好地跟踪和管理代码的历史记录