什么时候该用 git rebase 而不是 git merge
rebase 用于:同步主干到个人功能分支(线性历史)、合并前整理提交(squash 杂乱 WIP)、搬运提交串。merge 用于:共享分支合并、需要保留真实合并记录的场景。铁律:已推送且有人使用的历史不 rebase。
简单口诀:自己的提交整理用 rebase,别人的历史汇合用 merge。 rebase 得到线性干净的历史但改写提交;merge 保留已有提交关系;非快进合并产生合并节点,快进合并不会。
该用 rebase 的场景
- 功能分支同步主干:
git rebase main——以本地 main 的当前位置重放你的提交;若需远端最新状态,应先 fetch 并选择正确基点,历史一条线; - 合并前整理:
git rebase -i把 "fix typo"、"wip" 之类的杂乱提交 squash 干净再合 PR; - 搬运提交串:
git rebase --onto把分支嫁接到另一个基点。
该用 merge 的场景
- 共享分支的汇合:main/release 上的合并——历史真实可审计;
- 需要"这个特性是整体进来的"语义:合并提交本身就是边界标记(--no-ff);
- 长期并行分支:反复 rebase 长分支会不断重写,冲突反复出现,merge 通常按一次合并处理冲突,但后续合并仍可能再次冲突,不保证永远只解一次。
黄金法则
已推送并被他人使用(或可能使用)的提交,不要 rebase。
rebase 改写哈希,别人基于旧历史的工作会全部错位。个人分支中未共享的提交可按需要 rebase,仍需保留恢复途径并检查结果;公共历史只进不退(merge/revert)。
常见问题(FAQ)
Q:pull 时用 rebase 还是 merge?
个人习惯 + 团队约定。pull.rebase=true 让你本地的零星提交不产生无意义合并节点,仅应重放适合改写的本地提交;具体选择按团队约定,不能直接用于所有共享历史。
Q:rebase 的"线性历史"有什么实际好处?
git log 的主线阅读可能更直接,但 bisect 效果还取决于中间提交是否可构建、可测试;撤销整个特性是否容易取决于提交边界,并非线性历史天然更好。历史是给未来的自己看的文档。
Q:两者能混用吗?
日常就是混用的:功能分支上 rebase 整理,合回 main 用 merge(或 squash)。关键是别对共享历史 rebase。