Git 合并分支:3 种写法一次讲清,从最小示例讲到边界

2026-10-04 07:05:46 浏览数 (16)

Git 合并分支:3 种写法一次讲清

你本地在 feature 分支上改完功能,想把代码合回 main,却看到 git merge、git rebase、还有那个"快进"提示,不知道该用哪个。Git 合并分支的三种主流写法是:直接用 git merge 产生合并提交、用 git rebase 把提交挪到目标分支之后、以及快进合并(fast-forward)这种无新提交的特殊情况。选错方式主要带来历史线是否干净、冲突处理时机不同两类后果。本文基于 Git 2.x 验证,从最小示例讲到分支分叉、冲突与版本边界。今天这篇文章,编程狮就把这块讲透。

先看结论

你的目标 写法 结果
保留完整合并痕迹 git merge 生成一个合并提交,历史呈网状
历史线保持直线 git rebase 把提交重放到目标分支之后
目标在源头、无分叉 快进合并 指针直接前移,不产生新提交

一句话:想留痕用 merge,想整洁用 rebase,没分叉时 Git 默认快进;团队约定优先于个人偏好。

一、合并前的最小场景与准备

Git 合并分支的前提是两个分支都已有提交,且当前位于"要合入的目标分支"上。先用 Git 教程 里的基础命令确认状态,避免合错方向。

# 切到目标分支,再执行合并
git switch main
git status
git log --oneline --graph -8

以上命令先切换到 main,再用 git status 检查工作区是否干净,git log --graph 用来观察分支拓扑。预期结果是命令行打印出干净的 working tree 与一条提交线;如果 status 提示有未提交修改,先 git stash 或提交掉,否则合并可能被阻断。这一步属于前置配置,能显著降低后面误操作的概率。补充一点:合并前可用 git branch -v 查看每个分支最后一次提交与跟踪关系,确认 feature 确实领先于 main;若工作区有未提交改动,merge 会拒绝执行并提示 "Please commit your changes",此时先 git stash 暂存或提交即可继续。

二、写法一:git merge 产生合并提交

最稳的 Git 合并分支写法是 git merge 分支名,它会在当前分支上新建一个合并提交,把两条历史连起来。适合需要保留"谁在何时合入"证据的场景,比如多人协作的发布分支。

# 把 feature 合入当前所在的 main
git merge feature

运行后 Git 会尝试自动合并;若两个分支改了同一处,会进入冲突状态,文件里出现 <<<<<<< 标记。此时你需要手动编辑保留正确内容,再 git add 与 git commit 收尾。冲突修复完成后,用 git log --graph 验证能看到一个双亲的合并节点。适用场景是对外发布、需要审计合入记录的仓库。

⚠️ 注意:merge 不会改写已有提交,因此最安全;但长期会让历史出现大量合并节点,阅读成本上升。

Git 合并分支快进与非快进决策图

三、写法二:git rebase 保持直线历史

git rebase 的思路是"先把我的提交临时摘下,跳到目标分支最新处,再逐个重放"。它让历史变成一条直线,方便 bisect 与回滚。先用 Git Magic 教程 理解变基的心智模型会更容易上手。

# 在 feature 上,把当前分支变基到 main
git rebase main

运行后你的提交会被依次重放到 main 顶端,预期结果是 git log 看到一条直线。但若 feature 与 main 有冲突,rebase 会在第一个冲突处停下,你需要修复、git add、再 git rebase --continue。变基的核心代价是"改写提交哈希",所以已推送到远端的分支不要随便 rebase,否则别人拉取时会冲突。版本边界上,Git 1.7 之后 rebase 默认不处理已合入的提交,行为更加可预期。rebase 还有几个常用变体:git rebase -i HEAD~3 可交互地压缩或重排最近三次提交,适合发布前清理;当某个补丁已被上游合入、rebase 提示 "patch already applied" 时,用 git rebase --skip 跳过该提交即可;若变基到一半想整体放弃,始终可以用 git rebase --abort 回到起点,不会留下半成品。

四、快进合并与三种方式横向对比

当目标分支是你当前分支的直接祖先(没有分叉)时,Git 会执行快进合并:仅仅把指针前移,不产生合并提交。你可以用 --no-ff 强制保留合并节点,用 --ff-only 拒绝非快进。

# 强制生成合并提交(即使能快进)
git merge --no-ff feature
# 只允许快进,否则报错
git merge --ff-only feature

progitch 教程 把这三种方式的取舍讲得更系统。下面的对照帮助你按团队约定选型:

方式 历史形态 适用 代价
git merge 网状、有合并节点 需留痕的协作 节点多、阅读成本高
git rebase 直线 追求整洁的个人/特性分支 改写哈希、忌动已推送分支
快进合并 直线、无新提交 无分叉的小合入 丢失合并证据

边界上注意:rebase 中途用 git rebase --abort 可整体回退;merge 冲突修复错了可用 git merge --abort 取消本次合并。确认结果时统一用 git log --graph --oneline 检查拓扑是否符合预期。团队约定怎么定?很多团队要求 feature 合入 main 时必须用 --no-ff,以便保留"哪次发布合了哪些功能"的审计线;而个人在本地整理提交、还没推送时,用 rebase 保持直线反而更清爽。关键原则是:已推送、他人可能基于它工作的分支绝不 rebase,本地私有分支则可自由整理。

Git 合并分支三种方式适用场景对照图

总结

Git 合并分支有三种主流写法:merge 留痕、rebase 整洁、快进省提交。

  • 需要审计合入记录用 git merge,它会生成合并提交;
  • 想保持历史直线用 git rebase,但别对已经推送的分支做;
  • 没有分叉时 Git 默认快进,可用 --no-ff / --ff-only 控制行为。

下一步想系统学 Git,可以先过一遍 Git 教程,再结合速查手册巩固命令。

延伸学习

想把这块知识系统补齐,可以按这个顺序来:

  1. 想跟着课程动手练,Git 入门实战课程 是边学边写的形式;
  2. 看版本控制的整体定位,Git 版本控制利器笔记 从协作角度补充认知;
  3. 需要更完整的命令参考,Git 书中文版教程 适合随时查阅。

常见问题

Q:rebase 和 merge 到底该选哪个?

A:团队没有强制约定时,个人特性分支用 rebase 保持整洁,需要留痕的发布合入用 merge。已推送到远端、别人可能基于它工作的分支,优先 merge。

Q:快进合并为什么没有合并提交?

A:因为目标分支本就是当前分支的祖先,没有分叉,Git 只需把指针前移,不创造新提交,所以历史里看不到合并节点。

Q:rebase 中途搞乱了怎么撤销?

A:直接运行 git rebase --abort 就能整体回到变基开始前;如果已经完成但想反悔,可用 git reflog 找到变基前的提交哈希再 reset 回去。