# Git 中如何将一个分支的更改合并到另一个分支?

5 min read
Table of Contents

Git 中如何将一个分支的更改合并到另一个分支?

【核心定义】
在 Git 中,将一个分支的更改合并到另一个分支,本质上是将两个分支的提交历史进行整合,生成一个新的合并提交(或快进合并),使目标分支包含源分支的所有修改。

【关键要点】

  1. 合并命令:使用 git merge <branch-name>,将指定分支合并到当前所在分支。
  2. 合并策略:Git 默认采用递归合并策略(Recursive Strategy),当两个分支有分叉时,会自动寻找共同祖先并生成合并提交。
  3. 快进合并(Fast-forward):如果目标分支是源分支的直接上游(即没有分叉),Git 会直接将目标分支指针移动到源分支的最新提交,不会创建合并提交。
  4. 三方合并(Three-way Merge):当分支出现分叉时,Git 会基于共同祖先、目标分支和源分支的版本进行三方对比,自动解决可合并的更改。
  5. 冲突处理:如果同一文件的同一部分在两个分支上有不同修改,Git 会标记冲突,需手动解决后提交。

【深度推导/细节】

  • 合并冲突的产生逻辑:
    Step 1: Git 定位两个分支的共同祖先提交(Base Version)。
    Step 2: 对比祖先版本与目标分支(Current Version)的差异,以及祖先版本与源分支(Incoming Version)的差异。
    Step 3: 如果两处修改涉及同一代码块且内容不同,Git 无法自动决策,会中断合并并标记冲突文件。
    Step 4: 用户需手动编辑文件解决冲突(保留目标分支内容、源分支内容或重新编写),然后执行 git add 和 git commit 完成合并。

  • 快进合并的触发条件:
    目标分支的最新提交是源分支的直接祖先(即目标分支没有新的提交)。此时合并仅移动分支指针,不会产生额外提交,保持线性历史。

【关联/对比】

  • git merge vs git rebase:
    • merge 保留分支历史,生成合并提交,适合公共分支(如 main)。
    • rebase 将源分支的提交“复制”到目标分支最新提交之后,形成线性历史,适合本地分支整理。
  • git merge --no-ff:强制禁用快进合并,即使满足条件也会生成合并提交,便于追踪分支合并历史。

『面试官追问』

  1. 如何解决合并冲突?

    • 使用 git status 查看冲突文件。
    • 打开文件,根据 <<<<<<<、=======、>>>>>>> 标记手动编辑。
    • 执行 git add <file> 标记为已解决,然后 git commit。
    • 也可用 git mergetool 调用图形化工具。
  2. 合并时出现“分叉历史”怎么办?

    • 这是正常的三方合并场景,Git 会自动处理无冲突部分。若需保持线性历史,可考虑先执行 git rebase 调整源分支基线再合并。
  3. git merge 和 git pull 的关系?

    • git pull = git fetch + git merge,拉取远程分支后自动合并到当前分支。
  4. 如何撤销一个合并?

    • 使用 git merge --abort(合并过程中撤销)。
    • 若已提交,可通过 git reset --hard HEAD~1 回退或 git revert -m 1 <commit-hash> 生成反向提交。

【版本差异】

  • Git 2.23+ 引入 git switch 和 git restore 命令,可替代 git checkout 进行分支切换和文件恢复,但合并操作仍用 git merge。
  • Git 2.33+ 优化了合并算法(如 “merge-ort” 策略),提升大型仓库的合并性能和准确性。

【线程安全】
Git 合并操作本身非线程安全,但 Git 通过文件锁和引用事务保证仓库在并发操作下的数据一致性。例如,合并过程中会锁定 .git/index 文件,防止多个进程同时修改暂存区。

My avatar

文章看完了,不打算去别的篇章转转吗?👀 感谢你的耐心阅读!如果你有问题想探讨,或者发现了文中的 Bug,请务必通过页脚的链接联系我


More Posts

Comments