git merge 默认保留所有提交记录,非快进时生成含两个父提交的合并提交,完整保留分支演进路径;快进时仅移动指针不产生合并提交;加--no-ff可强制生成合并提交以保留分支痕迹。

git merge 默认保留所有提交记录
默认情况下,git merge 会把源分支的每个提交都“原样搬进”目标分支历史,不删、不压、不重排。只要不是 fast-forward 合并,就会生成一个带两个父提交的 merge commit,完整保留两条线的演进路径。
这种行为适合需要审计、回溯或多人协作审查的场景——比如你看到 git log --graph 里出现分叉再汇合的结构,就是它在起作用。
- 不需要额外参数,直接
git checkout main && git merge feature就生效 - 如果
main自从feature分出后没新提交,Git 会走 fast-forward 模式:不产生 merge commit,只是移动指针——此时历史是线性的,分支“痕迹”消失 - 想强制保留分支痕迹?加
--no-ff,哪怕能 fast-forward 也会生成 merge commit
git merge --squash 只留一个提交
git merge --squash 不是真合并,而是把源分支所有变更“摊平”成暂存区修改,不记录任何原始提交信息,也不建立父子关系。它本质是“取内容,丢历史”。
典型用于功能验证通过后、想干净地集成到主干,又不想让几十个调试提交污染 main 历史。
- 执行后必须手动
git commit,否则什么都不会提交 - 源分支不会被删除,也不会被标记为已合并(
git merge-base查不到共同祖先) - 后续再 merge 同一分支,Git 仍会尝试合并全部变更——因为它根本不记得上次“squash 过”
git rebase -i 合并多个本地提交
如果你在自己分支上攒了 5 个提交,但其中 3 个只是 fix typo / debug print,想压缩成 1 个干净提交再推送到远程,git rebase -i HEAD~5 是最直接的路。
监控一个或多个 GitCode 仓库的 PR,通过 OpenClaw Gateway 自动执行 AI 审查,发布 PR 评论,并发送钉钉和企业微信通知。
它操作的是当前分支的**本地提交链**,不影响远程或他人分支,但会改写提交哈希——所以只应在未推送前使用。
- 进入交互界面后,把要合并的提交前的
pick改成s(squash)或f(fixup),第一行保持pick - 保存退出后,Git 会打开编辑器让你重写最终提交信息;若选
f,则直接丢弃那条提交的 message - 完成后运行
git push --force-with-lease覆盖远程分支(仅限你独占的开发分支)
容易被忽略的冲突处理细节
冲突不是“文件没合并完”,而是 Git 明确告诉你:“这两处修改无法自动判断哪个该留”。哪怕只改了一行,只要两边都动过同一块区域,就触发冲突标记 和 <code>>>>>>> feature。
很多人卡在“解决了但 push 不上去”,其实是因为漏了关键动作:
- 编辑完冲突文件后,必须
git add <file></file>标记为已解决——光保存文件没用 - 如果有多个冲突文件,
git status会列出哪些还没add,别靠记忆清点 - 不确定改得对不对?先
git checkout --ours <file></file>或git checkout --theirs <file></file>快速回退到任一侧版本再对比
真正麻烦的从来不是冲突本身,而是合并后没跑测试就直接 push——尤其当冲突涉及逻辑分支或配置项时,编译通过不代表行为正确。










