git merge 是什么
git merge 把一个或多个分支的提交并入当前分支。可快进时它直接移动当前分支指针,不产生新提交;分叉之后需要三方合并,生成一个带两个父提交的合并提交。合并属于写入操作,会改变当前分支与工作区,执行前要确认当前分支就是接收方。
快进与合并提交
快进发生在当前分支没有独有提交时,历史保持线性,看不出这里曾经有过分支;一旦分叉,Git 找到共同祖先做三方合并,冲突文件需要人工解决。团队常在主干上关闭快进(--no-ff)以保留「某个特性被整体合入」的痕迹。两种形态各有取舍,关键是与团队的分支策略保持一致。
基本信息
| 适用平台 | Linux / macOS / Windows(Git 2.x) |
|---|---|
| 语法 | git merge [选项] <分支>… |
| 前置状态 | 工作区干净,当前分支是接收方 |
| 常用选项 | --no-ff 强制合并提交;--ff-only 只允许快进;--squash 压缩 |
| 冲突产物 | 冲突区间写入文件,索引标记为未合并 |
| 撤销方式 | git merge --abort 回到合并前状态 |
典型使用场景
- 把功能分支并入主干:评审通过后合进 main
- 同步主干到本地分支:把 main 的最新提交并入自己的分支
- 发布前汇集:把多个修复分支合并进 release
- 保留特性边界:用 --no-ff 让历史看得到一次特性合入
- 保守推进:用 --ff-only 确保只做快进,避免意外的合并提交
- 试用合并:结果不确定时先试,出问题立刻 --abort 放弃
常用示例
常用示例
git branch --show-current # 先确认自己站在接收方分支上
git status --short # 工作区干净才适合合并
git fetch origin # 取回远端最新状态
git merge feature/login # 合并功能分支
git merge --no-edit feature/login # 接受默认生成的合并信息
git merge --no-ff -m 'Merge feature/login' feature/login # 保留合并点
git merge --abort # 放弃本次合并,回到合并前合并结果怎么读
| 提示 | 含义 | 下一步 |
|---|---|---|
| Already up to date | 目标分支没有新提交 | 无需任何动作 |
| Fast-forward | 快进,指针直接前移 | 历史无合并点,可用 --no-ff 避免 |
| Merge made by ort strategy | 已生成合并提交 | 用 git log --graph 核对拓扑 |
| CONFLICT (content) | 同一区域被双方改动 | 编辑文件后 git add 再 continue |
| Automatic merge failed | 冲突需要人工处理 | 解决冲突或 --abort 放弃 |
| unrelated histories | 两个历史没有共同祖先 | 确认来源后再决定是否放行 |
合并之前先执行 git log --oneline --graph -10 --all 看一眼分支拓扑,能提前发现分叉范围,把冲突处理的意外降到最低。
合并方向由「当前在哪条分支」决定,而不是由命令里写的分支名决定。养成先 git branch --show-current 的习惯,可以避免把主干反向合进特性分支。
工作区有未提交改动时,合并可能被拒绝,也可能把改动卷进冲突现场。动手前先用 git status 确认干净,必要时先 git stash 保存现场。
合并提交已经生成后想反悔,merge --abort 已经无效,需要用 git reset --hard ORIG_HEAD 回退,或用 git revert 生成一条反向提交。
合并成功后的收尾
合并成功不等于工作结束,还要确认三件事:冲突文件里没有残留标记,用 git diff --check 扫一遍即可发现;构建与测试仍然通过,尤其是双方都改过的模块最容易出问题;最后把结果推到远端,否则协作者看到的仍是两条分叉的历史。受保护的分支还要按流程提 PR 或 MR,而不是直接推送。
合并前先用 git fetch 把远端的 origin/main 更新到最新,再基于它做集成;只在本地 main 上合并、却不 fetch,等于拿过期基线做判断。
合并提交的信息默认会写清来源分支与冲突文件,保留它有助于日后回溯;需要统一格式时再用 -m 指定,不要在历史里留下一条只有「Merge」的空洞信息。