文章

git-merge

合并分支,把另一个分支的修改合并进当前分支。

git-merge

git merge

git merge 用于将另一个分支的提交历史和修改内容合并到当前所在分支。

它实现的是将两条不同分支的开发历史融合成一条完整的提交记录链

基本概念

  • 当前分支:你现在检出的分支,是合并的目标分支。
  • 合并分支:你想要合并进当前分支的那个分支。

合并的基本类型

快进合并(Fast-forward)

  • 当前分支在合并分支之前没有新的提交,直接把指针往前移动到合并分支的最新提交。
  • 没有产生新的合并提交。
1
2
3
D---E---F---A---B---C   (feature)
             
           (main)

如果当前在 main,执行:

1
git merge feature

结果:

1
D---E---F---A---B---C (main, feature)

这里,main 直接快进到 feature 的最新提交。

真实合并(Merge Commit)

  • 当前分支和合并分支都有新提交,Git 会创建一个新的合并提交(merge commit)。
  • 合并提交有两个父节点,表示历史合并点。

合并前:

1
2
3
  A---B---C  (feature)
 /
D---E---F   (main)

合并后:

1
2
3
  A---B---C  (feature)
 /           \
D---E---F-----M   (main)

M 是合并提交,合并了 mainfeature 两条历史。

基本命令用法

1
2
git checkout main         # 切换到目标分支
git merge feature         # 将 feature 合并进 main

合并流程(原理)

  1. 找到两个分支的最近共同祖先(merge base)。
  2. 计算两个分支各自相对于共同祖先的改动差异。
  3. 把两个差异合并,产生合并结果。
  4. 如果自动合并成功,生成新的合并提交(除非是快进合并)。
  5. 如果冲突,标记冲突文件,等待用户手动解决。

冲突处理

当两个分支都修改了同一文件同一位置,Git 无法自动合并时,会报合并冲突

  • 冲突文件会包含冲突标记:
1
2
3
4
5
<<<<<<< HEAD
当前分支代码
=======
合并分支代码
>>>>>>> feature
  • 需要编辑文件,选择或修改代码,然后执行:
1
2
git add <冲突文件>
git commit               # 完成合并提交

常用合并选项

选项说明
--no-ff禁止快进合并,强制生成合并提交
--ff-only只允许快进合并,否则失败
--squash把所有合并分支的提交压缩成一个提交,且不自动提交
--abort中止合并,回退到合并前状态
--no-commit合并但不自动提交,方便检查或修改合并结果

进阶技巧

--no-ff 保留合并分支的历史记录

1
git merge --no-ff feature

这样即使可以快进,也会生成新的合并提交,方便区分合并点。

使用 --squash 做整洁的合并

1
2
git merge --squash feature
git commit -m "合并 feature 分支"

会把 feature 上所有提交合并成一个新的提交,不保留分支的提交历史

合并冲突可用工具辅助解决

1
git mergetool

调用可视化工具帮助解决冲突。

总结

场景命令示例说明
正常合并分支git merge feature自动合并(或冲突需解决)
禁止快进合并git merge --no-ff feature保留合并历史
只允许快进合并git merge --ff-only feature若不能快进则失败
整合多次提交为一次提交git merge --squash feature不产生合并提交
中止冲突合并git merge --abort放弃本次合并
本文由作者按照 CC BY 4.0 进行授权