rebase不是合并操作,它重写历史、不保留原始哈希,仅适用于未推送的本地分支;merge才是真正的分支合并,创建双父提交,历史可追溯、协作安全。

rebase 不是合并操作,它不保留原始提交哈希,也不创建合并提交;merge 才是真正的分支合并,历史可追溯、协作安全。
git rebase 会重写提交历史,慎用于已推送的分支
rebase 的本质是「复制 + 重放」:把当前分支的每个 commit 拆成补丁,在目标分支最新提交之后重新生成新 commit。由于 parent、时间戳、甚至作者信息(取决于参数)都变了,SHA-1 哈希值必然不同。
这意味着:
- 如果
feature分支已git push到远程,再本地git rebase main,然后强制推送git push --force-with-lease,其他协作者拉取时会遇到「非快进」拒绝,或更糟——他们基于旧提交做的工作可能被覆盖 - CI/CD 流水线里若依赖某次提交的 SHA(比如用 commit ID 触发构建),rebase 后该 ID 失效
- 用
git bisect排查 bug 时,rebase 后的线性历史看似干净,但丢失了真实开发时序和上下文
git merge 创建合并提交,适合公共分支间整合
merge 是原子性合并:把两个分支的 HEAD 快照合并,生成一个带两个 parent 的新提交(merge commit)。这个提交明确记录了「谁、何时、从哪来」。
典型使用场景包括:
- 将
feature/login合入main或develop—— 这是发布流程的正式环节,必须可审计 - 集成测试通过后合入预发分支,需要保留
feature分支的完整迭代过程(比如修复了三次才跑通 CI) - 多人并行开发同一功能模块,各自在子分支上提交,最终用 merge 整合,避免互相覆盖
注意:git merge --ff-only 可以禁止创建合并提交,仅当目标分支是当前分支的直接祖先时才允许快进,否则报错——这能帮你守住「是否真有分叉」的事实。
rebase 的合理用法:仅限未共享的本地分支同步
rebase 真正安全且有价值的场景,只有一种:你自己的、尚未 push 的本地特性分支,需要吸收上游(如 main)的更新,避免后续 merge 出现大量无关冲突。
操作建议:
- 先确保本地
main是最新的:git checkout main && git pull - 切回你的分支:
git checkout feature/search - 执行变基:
git rebase main(不是git rebase -i,除非你明确要编辑/压缩提交) - 如果中途冲突,解决后
git add . && git rebase --continue;想放弃就git rebase --abort - 确认无误后再
git push -u origin feature/search(首次推送)
关键点:整个过程没碰过远程分支,所有操作都在你本地,别人完全不受影响。
merge --squash 是第三种选择,适用于“功能即提交”场景
它既不保留分支历史,也不重写提交,而是把目标分支所有改动「摊平」成一次普通提交,然后由你手动 git commit。
适用情况:
- PR/MR 审查要求「单次提交说明清楚全部变更」,比如文档更新、配置调整等轻量修改
- 临时实验分支验证完方案,不需要保留中间调试提交
- 第三方贡献者提交了 20 个粒度极细的 commit,你希望合入时只留一个语义清晰的提交
命令链:git checkout main && git merge --squash feature/docs && git commit -m "docs: update API reference"。注意:它不会自动 commit,必须手动触发。
真正容易被忽略的点是:rebase 和 merge 的选择,从来不是「哪个更高级」,而是「谁拥有这个分支的控制权」——如果你不能确保没人基于它的旧提交继续工作,就别动它。历史可丢,协作信任不能丢。


















