Git 里的 branch、merge、rebase 到底怎么理解
很多人把 Git 的日常提交流程跑顺之后,下一步最容易卡住的,就是这 3 个词:
branchmergerebase
它们看起来都和“合代码”有关,但又不像一回事。
于是新手很容易出现这种状态:
- 知道分支很重要,但不敢开;
- 知道 merge 能合并,但不知道它和 rebase 差在哪;
- 看到别人说“别乱 rebase”,就更不敢碰了。
其实这 3 个概念并没有那么神秘。
如果只用一句话先概括它们:
branch:开一条独立开发线;merge:把两条开发线合到一起;rebase:把一条开发线“换个起点重新排一下”。
这篇文章就专门把这 3 件事拆清楚。
一、为什么需要 branch
如果一个项目只有一条主线,所有人都直接在主分支上改代码,那么很快就会出现很多问题:
- 你想试一个新功能,但怕把主线改坏;
- 两个人同时开发不同功能,修改彼此干扰;
- 某个实验还没完成,但主线又需要保持稳定。
所以 Git 给出的解决办法是:
不要所有改动都挤在同一条线上,而是先开分支。
二、branch 到底是什么
你可以把branch理解成:
项目历史中的一条并行开发线。
最常见的主分支通常叫:
main- 或者
master
如果你现在要做一个新功能、新实验、新 bug 修复,就完全可以从主分支上再开出一条新线,在那上面单独开发。
比如:
main: A -> B -> C feature: D -> E这里的意思是:
- 主分支先走到了
C - 你从
C这个位置开了一个feature分支 - 后续的
D、E都是在这条新分支上发生的
这样做的好处是:
- 主线保持稳定;
- 你可以放心试错;
- 多个人可以在不同分支上并行开发。
1. 最常用的分支命令
查看当前有哪些分支:
gitbranch创建并切换到新分支:
gitswitch-cfeature-login如果你的 Git 版本较老,也可能看到这种写法:
gitcheckout-bfeature-login切回主分支:
gitswitch main三、merge 是什么
当你在分支上把功能做完了,接下来通常会遇到一个问题:
我怎么把这条分支的成果带回主分支?
这时候就轮到merge了。
1. merge 的本质
merge的本质是:
把两条分支的历史汇合起来。
比如:
main: A -> B -> C feature: D -> E当你回到main,执行:
gitmerge feature结果大致可以理解成:
main: A -> B -> C ------ M \ / feature: D -> E这里的M可以理解成一个“合并点”。
它表示:
main原来有自己的历史;feature也有自己的历史;- 现在这两条历史被合到一起了。
2. merge 的优点
merge最大的优点是:
它会比较忠实地保留协作过程。
也就是说,你以后回头看,会更容易知道:
- 这个功能是在哪条分支上做的;
- 什么时候被合并回主线;
- 这段历史原本是并行发展的。
所以如果你比较看重真实协作痕迹,merge会很自然。
四、rebase 是什么
如果说merge是“把两条线接到一起”,那么rebase更像是:
把你这条分支上的提交,重新放到另一个新的起点上。
这句话第一次看会有点绕,我们用图来理解。
假设现在是这样:
main: A -> B -> C -> F -> G feature: D -> E也就是说:
- 你从
C开了feature - 你在
feature上做了D、E - 与此同时,主分支又继续往前走到了
F、G
如果你现在在feature上执行:
gitrebase main它的意思可以理解成:
- 先找到
feature和main原来的分叉点; - 把你在
feature上独有的提交拿出来; - 再把这些提交“重新接到”当前的
main后面。
结果大致会变成:
main: A -> B -> C -> F -> G feature: D' -> E'注意这里我写的是D'、E',而不是原来的D、E。
这是因为:
rebase 不是简单挪位置,而是把这些提交在新起点上重新播放了一遍。
所以从 Git 的角度看,它们已经是“新的提交”了。
1. rebase 的优点
rebase最大的优点是:
历史会更线性、更整洁。
你回头看日志时,不会看到很多交叉出来再 merge 回去的结构,而更像一条连续主线。
这也是为什么很多团队会喜欢在个人分支上用 rebase 来整理历史。
五、merge 和 rebase 到底有什么区别
如果只抓最核心的差别,可以记这几条。
1. merge 更像“保留真实协作历史”
它承认:
- 大家确实在不同分支并行开发过;
- 这些分支后来被合并了;
- 历史里应该看得见这件事。
所以merge更强调:
真实过程
2. rebase 更像“整理历史,让它更线性”
它不太强调原本历史分叉得有多复杂,而是更关注:
- 最终日志是否清楚;
- 提交顺序是否更直;
- 阅读历史时是否更干净。
所以rebase更强调:
整理结果
3. merge 往往会保留一个合并痕迹
而 rebase 通常不会产生那种显式的合并节点,它更像把你的提交重新排了一下。
六、什么时候用 branch、什么时候 merge、什么时候 rebase
这其实是新手最想知道的部分。
1. 什么时候开 branch
只要你准备做下面这些事情,都很适合先开分支:
- 开发一个新功能;
- 修一个 bug;
- 尝试一个实验思路;
- 改一个可能比较大的重构。
一句话就是:
只要改动值得被单独管理,就很适合开分支。
2. 什么时候用 merge
如果你希望:
- 保留更真实的协作历史;
- 清楚看到某个功能分支是什么时候并入主线的;
- 团队里大家都更习惯“分支开发 + 合并回主线”的方式;
那就优先用merge。
对于很多团队协作场景,merge都是很自然也很稳妥的选择。
3. 什么时候用 rebase
如果你希望:
- 在把分支合回去之前,先把自己的分支历史整理得更干净;
- 让自己的分支跟上最新的主分支;
- 让提交历史更线性、更容易阅读;
那就可以考虑rebase。
比较典型的场景是:
- 你在个人分支上开发了一段时间;
- 主分支已经有了新进展;
- 你想先把自己的分支更新到最新主线,再继续工作或再提交合并。
七、为什么很多人说“不要乱 rebase”
这句话不是说rebase不好,而是说:
rebase 会改写提交历史。
这意味着,如果这条分支已经被别人基于它继续开发,或者已经作为共享历史被大家依赖,那你再去 rebase,就可能把别人原来对齐的历史打乱。
所以一个很常见、也很稳的经验是:
个人分支上可以谨慎用 rebase,已经共享给多人使用的公共分支上不要随便改写历史。
你可以先把它理解成:
merge更保守;rebase更讲究整理;- 但整理历史这件事,要建立在你知道这段历史是不是已经被别人依赖的前提上。
八、一个最常见的实际场景
假设你要开发一个登录功能。
第一步:从主分支开分支
gitswitch maingitswitch-cfeature-login第二步:在分支上开发并提交
gitadd.gitcommit-m"新增登录表单"第三步:主分支这时也有别人提交了新内容
这意味着你的分支和主分支已经分开发展了一段时间。
第四步:你有两种常见处理方式
方式一:直接合并主分支变化
在自己的分支上:
gitmerge main或者最后切回主分支再:
gitswitch maingitmerge feature-login方式二:先把自己的分支 rebase 到最新主分支上
gitswitch feature-logingitrebase main然后再回到主分支合并。
这两种方式都可能合理,关键是你想保留哪种历史形态,以及团队平时采用什么习惯。
九、新手可以先记住的最简判断
如果你暂时还不想把这件事想得特别复杂,可以先记住下面这套非常实用的判断:
branch:为了把改动和主线分开,先开一条线;merge:为了把一条线的成果接回去,用 merge;rebase:为了让自己的分支接上最新主线,或者整理历史,用 rebase。
如果你继续往前再压缩成一句话,就是:
branch 用来分开开发,merge 用来汇合历史,rebase 用来整理和重排历史。
十、结尾
很多人一开始会觉得 Git 难,往往不是因为命令本身,而是因为看不到项目历史其实是一张“时间图”。
只要你开始把 Git 理解成“多条历史线如何分开、如何汇合、如何整理”,那么:
branch就不再神秘;merge就不只是一个命令;rebase也不再像一个危险咒语。
下一篇我们继续讲:
Git 冲突和常见报错怎么处理
因为真正开始多人协作之后,最重要的不只是“会提交”,还要学会在出问题时知道该怎么稳稳地处理。