Command Reference

git merge 教程

解释 git merge 的核心作用、fast-forward 与 merge commit 的区别,以及冲突处理策略。

适合谁看
  • 需要整合分支历史的协作者
前置知识
  • 知道分支为什么会分叉
  • 能看懂 merge commit 的含义
常见风险
  • 在冲突没理解清楚时强行继续
  • 把 merge 和 rebase 的适用边界混掉

一句话理解

git merge 会把另一个分支的历史整合到当前分支。它不要求改写已有提交,因此很适合共享分支上的常规整合。

什么时候应该用

  • 把特性分支合并回 main
  • 在团队协作中保留分支汇合关系
  • 你不希望改写已有提交历史时

两种常见结果

1. fast-forward

如果当前分支没有新的分叉提交,Git 可以直接把分支指针向前移动。

2. merge commit

如果两个分支都各自向前发展,Git 会创建一个新的 merge commit 来表达“历史在这里汇合了”。

merge commit 的历史表达merge 不会重写原有提交,而是在两条分支都继续发展的情况下,用一个新的合并提交把它们接起来。
合并前
main
ABC
feature
BDE
合并后
main
ABCM
feature
BDEM

如果你把这张图和 rebase 那张图放在一起看,会发现 merge 更强调“保留两条线最后在这里汇合”,而不是把一条线重新改写成线性历史。

基本流程

git checkout main
git fetch origin
git merge feature/login

建议先 fetch,再 merge,这样你看到的是远端最新状态。

常见参数和策略

--ff-only

只允许 fast-forward。只要历史已经分叉,就直接失败。

git merge --ff-only origin/main

--no-ff

即使可以 fast-forward,也强制生成一个 merge commit,适合团队希望保留“某个分支在这里被合并”的边界时使用。

git merge --no-ff feature/login

冲突时怎么处理

git status
# 手动解决冲突
git add <resolved-files>
git merge --continue

如果想放弃当前合并:

git merge --abort

什么时候 merge 比 rebase 更合适

  • 分支已经被多人共享
  • 你想清楚保留分叉和汇合关系
  • 团队更重视“历史真实过程”,而不是绝对线性

一个实际判断方法

如果你问自己的是“我是不是要把整条分支的历史整合进来”,通常 merge 是更自然的选择。

如果你问自己的是“我是不是只想整理自己分支的历史表达”,通常才更像 rebase 的适用场景。

常见误区

误区 1:merge 一定比 rebase 更脏

不一定。它只是更明确地保留了分支整合关系。

误区 2:merge 冲突比 rebase 冲突更难

本质上都是在解决同一类文本或语义冲突,只是发生时机和历史表达不同。

一个团队建议

对共享主分支,可以优先明确三条规则:

  1. 是否允许 merge commit
  2. 是否默认要求 fast-forward
  3. pull request 合并策略是什么

这条命令在流程里解决什么问题

git merge 直接影响历史表达、引用位置或提交之间的关系。读这类命令时,要先判断这次操作是在整理本地未共享历史,还是在处理已经公开给团队的历史。

典型用例

  • 在合并、回滚、挑提交或整理提交序列时,用 git merge 重塑历史表达。
  • git merge 放进“先备份、再变更、最后复核”的高风险操作流程,降低误操作损失。
  • 在复盘冲突、回滚事故或判断分支关系时,用 git merge 理清提交之间的因果链。

图例理解

历史命令的作用面历史类命令通常围绕提交、当前分支和祖先关系展开,差别在于它是新增历史、移动引用,还是重写已有序列。
输入
提交序列当前分支祖先关系
结果
新的提交关系移动后的引用可恢复路径
这类命令执行前最值得确认的一件事,是“这段历史是不是已经共享给别人”。

特殊情况与边界

  • 历史类命令最常见的风险,是对已经共享出去的提交继续做重写或移动。
  • 如果这次操作可能影响团队协作,先跑 git statusgit log --oneline --graphgit reflog,再决定是否继续。
  • 一旦不确定,就先建一个备份分支,让自己保留“能回去”的选项。
  • 遇到冲突时不要只盯着当前文件,要先确认这次 merge 到底想保留哪一侧的历史语义。

跟着做一遍

练习:区分 fast-forward 和 merge commit

这组练习最值钱的地方,是让你看到 merge 不只是“把代码拼起来”,而是在表达历史如何汇合。

准备环境
git switch -c lab/merge-demo
# 从 main 切出 feature 并各自提交一次
跟着做
  1. 先在没有分叉的情况下执行一次 `git merge --ff-only`。
  2. 再制造 main 和 feature 同时前进的分叉。
  3. 执行 `git merge feature/demo` 并用 `git log --oneline --graph --decorate -8` 观察汇合点。
结果会怎样
  • 没分叉时只会移动分支指针。
  • 分叉后会出现一个新的 merge commit。
  • 历史图会明确保留两条线在某处汇合。
常见错误判断
  • 如果你以为 merge commit 一定是“脏历史”,往往忽略了它保留协作过程的价值。
  • 遇到冲突时不要只问“哪个文件该保留”,还要问“这次整合想保留哪种历史关系”。
  • 如果团队已经要求线性历史,就要先确认平台合并策略。

继续学习建议

如果你已经理解 merge,下一步建议连着学:

  1. git rebase 和 merge 的历史差异
  2. fetchpull 的整合边界
  3. 冲突解决后的恢复策略