到底是选 merge 还是选 rebase

写这篇文章的契机也是因为有次组内技术分享会里面讨论过这个话题,这两个指令都是用来合并分支代码的,rebase 可以把分支记录弄成一条线性,而 merge 保留了分支树状图,以我的习惯是更倾向于 merge,因为我大部分场景用不上 rebase

我们先看个大家开发中非常常见的场景,两个人基于 master 的同一个 commit 节点各自拉起一个新的 feature 分支,其中一个人 A 有多个 commit,并率先完成任务合入 master,B 也有多个 commit ,在他完成任务准备合入 master 时,发现有冲突,这里我模拟的每个提交都是针对同一个文件,每个 commit 都会有冲突

在 A 合并 master 前的分支图如下

可以看到 feature/A 分支 和 feature/B 分支都是基于 master 最新的 commit 拉起的分支,两条分支并行开发,这里我为了跟随时间线,用顺序数字模拟 commit 信息,两条分支各自新增了 3 个 commit

现在我们把 A 通过 merge 合并到 master 上

bash 复制代码
git checkout master
git merge feature/A

可以看到 A merge 到 master 后,master 和 feature/A 保持一致了

好了,开头说的场景已经出现了,这个时候你是 B 你会怎么做,要是我会选择 merge,那就先看下 merge 的表现

bash 复制代码
git checkout master
git merge feature/B

由于我的每个 commit 都是针对同一个文件做出更改,所以最终汇入必然要去解决冲突

可以看到这里的冲突是让你一次性解决的,解决完冲突后提交看 分支图

可以看到,merge 会创建一个新的合并提交,把两个分支平行的合并,保留了分支历史

这里顺带解释下为啥有时候 merge 没有 mr 节点,有时候又有,其实大部分情况下都会有。比如这里的 feature/A 合入 master 就没产生 mr 节点,feature/B 后合入 master 就产生了 mr 节点

merge 节点有没有取决于 git 是否需要创建一个新的合并提交

可能你体感上是永远会有 mr 节点,因为远程合作大部分场景 master 都是一直在前进的

  • fast-forward 合并
    • master 还停留在你分支起点的那个提交,比如 feature/A 合入到 master 的时候,master 和 feature/A 同一个起点,这就是 fast-forward 提交,就不会产生 mr 节点
  • 非 fast-forward 合并
    • master 相较于你的分支有了新的提交,比如 feature/B 的起点是最初的 docs: add README ,在 feature/B 准备合入 master 时,master 最新的提交却是 feature/A 的 dosc: 5

估计这个时候就小盆友要说了,我的这个 mr 节点是在我解决冲突时提交的,其实就算没有冲突,非 fast-forward 合并就是会产生 mr 节点

好,我们现在撤回 feature/B merge 到 master,我们改用 rebase 再来看下对比

撤回之后的分支图如下,master 还是停留在 docs: 5

现在使用 rebase

bash 复制代码
git checkout feature/B
git rebase master

可以看到 vscode 编辑器让我去解决冲突,这还是第一个

要是每个 commit 都有冲突那就每个 commit 都要单独解决一次冲突

一旦解决冲突并 git add,再运行 git rebase --continue,git 就会继续重放下一个提交,若同一段代码在多个提交中都改过,就会感觉是在重复解决冲突

现在回过头来看 git 树

可以看到 最终的 git 记录成一条直线了,看着确实顺眼不少,并且你的分支所有提交都会提前,你也不会产生 合并 的 mr 节点 ,但是你分支上原本的 commit hash (docs:3, dosc: 4, dosc: 6)会发生变化

结论

从 git 提交记录看

  • merge 保留历史记录,非线性,容易产生 mr 节点
  • rebase 将自己的 commit 记录提前并更改你之前的 commit hash,线性,不产生多余的 mr 节点

从 解决冲突 看

  • merge 在汇入那一刻解决所有的冲突,直接对比两个分支代码的终极形态
  • rebase 会按顺序重放你的所有 commit,但凡有冲突的提交都会让你挨个去解决

用 rebase 是有使用场景的,要是不清楚无脑 merge 就好。只有你一个人使用的分支,并且还没 push 到远端,可以去使用 rebase 整理下 git 历史,否则其余所有情况都可以用 merge

git rebase -i 可以整理提交顺序,合并多个小提交,改写提交信息

rebase 一定不能在公共分支上使用,因为这会篡改共有分支的 commit hash,别人再去合代码必然导致冲突

相关推荐
怕浪猫1 小时前
你的能力正在被重新定价:AI 时代程序员资产重估指南
程序员
深蓝AI3 小时前
自报提效 12 倍,模型进步加速 1.9 倍:METR 报告到底量了什么
人工智能·程序员
陈随易4 小时前
C++26 草案被否,二十八年来头一回
前端·后端·程序员
怕浪猫4 小时前
从工具到代理:一张图看懂 2026–2030 年 AI 如何重构 11 个行业
人工智能·程序员·产品
wo_jack11 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
聪明的笨猪猪13 小时前
AI应用架构选型:架构师的核心决策困境与权衡
经验分享·面试·架构
疯华整猫15 小时前
被杀掉之后:我把 Android 的「唤起 + 常驻」重做了一遍
前端·面试·架构
nice_lcj52016 小时前
Java 并发容器入门:ConcurrentHashMap、CopyOnWriteArrayList、阻塞队列
java·面试·并发编程·阻塞队列·concurrenthashmap·copyonwritearraylist
深蓝AI18 小时前
Agent 查数据库先问口径再动手:NVIDIA 开源语义层 Auto Ontology,连续两天登顶 GitHub Python 趋势榜
人工智能·程序员
岁月宁静1 天前
AI 应用开发工程师简历怎么写:HR 初筛、技术复筛、面试追问,三道关卡各看什么?
人工智能·python·面试