Skip to content

合并分支

概述

合并分支是将不同分支的修改整合到一起的过程。Git 提供了多种合并方式,理解它们的区别对于高效协作至关重要。

git merge 基本用法

git merge 命令用于将一个或多个分支的修改合并到当前分支。

基本语法

bash
# 将指定分支合并到当前分支
git merge <branch-name>

# 将指定分支合并到当前分支,并生成合并提交
git merge --no-ff <branch-name>

# 将指定分支合并到当前分支,不生成合并提交
git merge --ff-only <branch-name>

# 合并时指定提交信息
git merge -m "Merge feature branch" <branch-name>

合并前准备

bash
# 1. 确保目标分支是最新的
git checkout main
git pull origin main

# 2. 切换到要合并的分支
git checkout feature

# 3. 确保功能分支也是最新的
git pull origin feature

# 4. 切换回目标分支
git checkout main

# 5. 执行合并
git merge feature

快进合并 (Fast-forward)

当目标分支没有新提交时,Git 会执行快进合并。

合并原理

# 合并前
main      A --- B
                 \
feature           C --- D

# 快进合并后
main      A --- B --- C --- D
feature           C --- D

执行快进合并

bash
# 默认情况下,如果可能,Git 会执行快进合并
git checkout main
git merge feature
# 输出:Updating a1b2c3d..e5f6g7h
#       Fast-forward
#        file.txt | 2 +-
#        1 file changed, 1 insertion(+), 1 deletion(-)

禁用快进合并

bash
# 使用 --no-ff 选项,强制生成合并提交
git merge --no-ff feature
# 输出:Merge made by the 'recursive' strategy.
#        file.txt | 2 +-
#        1 file changed, 1 insertion(+), 1 deletion(-)

快进合并的特点

bash
# 优点
# - 历史记录线性,更简洁
# - 没有额外的合并提交

# 缺点
# - 丢失分支信息
# - 不知道哪些提交属于哪个分支

# 建议
# - 功能分支合并:使用 --no-ff 保留分支历史
# - 同步远程更新:使用快进合并

三方合并

当两个分支都有新提交时,Git 会执行三方合并。

合并原理

# 合并前
      A --- B --- C  (main)
             \
              D --- E  (feature)

# 三方合并使用三个点:
# - B:共同祖先(base)
# - C:main 分支的最新提交
# - E:feature 分支的最新提交

# 合并后
      A --- B --- C --- M  (main)
             \         /
              D --- E  (feature)

执行三方合并

bash
# 当无法快进合并时,Git 自动执行三方合并
git checkout main
git merge feature
# 输出:Merge made by the 'recursive' strategy.
#        file.txt | 2 +-
#        1 file changed, 1 insertion(+), 1 deletion(-)

合并提交

bash
# 三方合并会创建一个合并提交
git log --oneline --graph
# 输出:
# *   a1b2c3d (HEAD -> main) Merge branch 'feature'
# |\
# | * e5f6g7h (feature) Add feature
# * | d4e5f6g Update main
# |/
# * b2c3d4e Initial commit

合并策略

bash
# 默认递归策略
git merge feature

# 指定合并策略
git merge -s recursive feature
git merge -s octopus feature  # 合并多个分支
git merge -s ours feature     # 忽略被合并分支的修改

# 递归策略选项
git merge -X ours feature     # 冲突时优先使用当前分支
git merge -X theirs feature   # 冲突时优先使用被合并分支
git merge -X ignore-space-change feature  # 忽略空白变化

合并冲突处理

当两个分支修改了同一文件的同一位置时,会产生合并冲突。

冲突产生

bash
git merge feature
# 输出:Auto-merging file.txt
#       CONFLICT (content): Merge conflict in file.txt
#       Automatic merge failed; fix conflicts and then commit the result.

查看冲突状态

bash
# 查看冲突文件
git status
# 输出:
# Unmerged paths:
#   (use "git add <file>..." to mark resolution)
#   both modified:   file.txt

# 查看冲突详情
git diff

冲突标记

# 冲突文件内容示例
<<<<<<< HEAD
这是 main 分支的内容
=======
这是 feature 分支的内容
>>>>>>> feature
  • <<<<<<< HEAD:当前分支的内容开始
  • =======:分隔线
  • >>>>>>> feature:被合并分支的内容结束

解决冲突

bash
# 方法 1:手动编辑文件
# 打开冲突文件,删除冲突标记,保留需要的内容

# 方法 2:使用 git checkout 选择版本
git checkout --ours file.txt      # 使用当前分支版本
git checkout --theirs file.txt    # 使用被合并分支版本

# 方法 3:使用 git restore
git restore --ours file.txt
git restore --theirs file.txt

# 方法 4:使用合并工具
git mergetool

完成合并

bash
# 标记冲突已解决
git add file.txt

# 完成合并提交
git commit
# 或使用默认提交信息
git commit --no-edit

合并选项

常用选项

bash
# 合并并压缩提交
git merge --squash feature
# 将 feature 分支的所有提交压缩为一个,但不自动提交
git commit -m "Merge feature branch"

# 合并时允许不相关历史
git merge --allow-unrelated-histories feature

# 合并后不提交
git merge --no-commit feature

# 合并时显示详细信息
git merge -v feature

# 合并时自动暂存
git merge --autostash feature

合并配置

bash
# 配置默认合并策略
git config merge.ff false       # 禁用快进合并
git config merge.ff only        # 只允许快进合并
git config merge.ff true        # 允许快进合并(默认)

# 配置合并工具
git config merge.tool vimdiff
git config mergetool.prompt false

合并最佳实践

合并前检查

bash
# 检查分支差异
git log main..feature           # feature 有而 main 没有的提交
git log feature..main           # main 有而 feature 没有的提交
git diff main...feature         # 两个分支的差异

# 检查是否有未提交的修改
git status

# 确保分支是最新的
git fetch --all

保持分支整洁

bash
# 合并前变基功能分支
git checkout feature
git rebase main
git checkout main
git merge feature  # 此时可以快进合并

# 压缩功能分支的提交
git checkout feature
git rebase -i main  # 交互式变基,压缩提交

合并后清理

bash
# 删除已合并的本地分支
git branch -d feature

# 删除已合并的远程分支
git push origin --delete feature

# 清理远程已删除的分支引用
git fetch --prune

总结

  • 快进合并在目标分支无新提交时发生
  • 三方合并创建合并提交
  • 使用 --no-ff 保留分支历史
  • 冲突需要手动解决
  • 合并前确保分支整洁和最新

下一步

学习完合并分支后,建议继续学习: