Git merge 和 rebase 有什么区别?为什么共享分支要谨慎变基?
下面是一段教学用的模拟面试。
🧑💻 面试官:merge 和 rebase 有什么区别?
🙋♂️ 我:merge 有合并提交,rebase 让历史更直。
🧑💻 面试官:merge 一定有新提交吗?如果可以快进呢?
🙋♂️ 我:快进可以只移动分支指针。
🧑💻 面试官:那同事已经从你的提交继续开发,你再 rebase 并强推,他手里的提交关系会发生什么?
重点不是历史好不好看,而是「提交身份有没有变化,以及别人是否已经依赖它」。
面试速答(60 秒版)
merge 把两条历史合到一起。分支已经分叉时,通常建立一个连接两边历史的合并提交;如果可以快进,也可能只是移动指针,不产生新的合并提交。
rebase 则把待迁移提交的改动,在新的基点上重新应用。重放后的提交有新的父关系,因此提交 ID 通常也会改变,历史看起来更线性。
对于还没有被别人依赖的个人分支,rebase 可以帮助整理提交。已经共享、别人已经在其上继续开发的历史,应谨慎改写,否则协作者仍拿着旧提交,后续整合会变复杂。
两者都可能发生冲突,也都需要验证合并后的代码。是否线性,不代表代码一定正确。

知识点详解:用一张提交图,而不是一份文件列表理解
merge 保留两边是怎样走来的
假设共同起点是 A。主分支继续到 B,功能分支继续到 C。
两边已经分叉。如果把功能分支合入主分支,普通 merge 可以建立 M,M 的父提交包括 B 和 C。它记录的是两条历史在这里连接了。
文件层面的最终结果,是整合两边修改;图层面的结果,是保留两条来路。这个父关系很有用,不能只把 M 理解成一个“多余的点”。
但如果主分支仍停在 A,而功能分支已经到 C,就可能直接快进到 C。此时没有必要制造一次三方合并。具体行为还受命令选项与项目策略影响。
rebase 重放的是改动,不是搬走原来的提交
还是 A 分出 B 和 C 的例子。功能分支在 B 上 rebase,会把 C 所引入的改动重新应用到 B,得到 C’。
C’ 不是把旧 C 改个显示位置。它有新的父关系,提交身份也不同。旧提交不会因此在所有仓库里自动变成 C’。
提交对象还包含树、作者等信息,父提交也是身份的一部分。因此,就算最终文件很相似,也不能说“代码没变,所以提交 ID 必须一样”。
Pro Git用提交图解释了这种重放与合并的差别。

为什么别人依赖了旧提交,就更麻烦?
假设同事已经从 C 继续提交 D。你在 B 上重放得到 C’,再把远端指向 C’。
同事本地仍然是基于 C 的 D。他需要辨认哪些改动已经以新提交存在,哪些是自己的新增工作,并重新整合。简单再合一次,可能把两套相似历史重新连接回来。
所以风险不是 Git 禁止你改,而是改写影响了别人的参照。已经共享的分支,需要清楚的团队约定与协调,不因历史“看着乱”就直接强推。

冲突处理为什么也有不同体验?
merge 整合两边端点的变化;rebase 通常逐个重放待迁移提交。多次提交碰到同一片区域时,rebase 可能在不同重放步骤里多次需要处理冲突。
冲突解决以后,还要运行测试并检查实际行为。没有冲突,只说明 Git 没有要求你手动决定某些文本整合,不说明接口和逻辑没有冲突。
默认 rebase 还可能改变原有合并结构,需要保持合并关系时有专门选项与额外理解成本。本文不把“重放一定保持所有历史形状”当成默认行为。
可以怎样验证自己的理解?
在独立测试仓库中建立 A、B、C 这样的分叉,记录提交 ID,分别试普通 merge、快进和 rebase。
检查合并提交的父数,比较 C 与 C’ 的 ID,并用 log 的图形输出查看关系。这个实验不要直接在正在协作的项目上做,更不要把 force push 当成学习步骤。
Git 命令是工具操作,不是语言实现,不需要为了双语言形式补一份 Python 代码。
面试官继续追问
squash merge 等于 rebase 吗?
不是。squash 会把一组改动整理成相应结果供提交,不等于逐个重放原提交,也不会自动保留同样的历史关系。先说清最终提交图,再比较用途。
force-with-lease 能让共享分支改写完全安全吗?
不能。它帮助避免在远端参照不符合预期时覆盖,但不能消除别人已经基于旧提交开发的协作问题。
个人分支就一定要 rebase 吗?
不必。如果团队希望保留分叉与合并过程,merge 也合理。先遵守协作策略,再选择整理方式,不把一种历史外观当成全部项目的标准。
面试速记卡
- merge:连接历史;分叉时常有合并提交,快进可能没有。
- rebase:在新基点重放,提交身份通常改变。
- 共享边界:别人依赖旧提交以后,不随意改写与强推。
- 冲突:两者都可能发生,解决后仍要验证代码。
- 判断对象:提交图与协作关系,不只是 log 好不好看。
公司面试真题
真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。
字节跳动 · 前端 · 原帖未明确批次
Git rebase 怎样工作?(题意整理)
字节跳动 前端 3+1 面经(字节教育) ↗
原帖编辑于 2020-08-24