这一篇在干嘛?
分支模型被称为 Git 的「必杀技」:创建分支是瞬间的,切换是秒级的,这与复制整个项目目录的老式 VCS 天壤之别。搞懂它你才算真正会用 Git。对应《Pro Git》第 3 章前半部分。
分支的本质:一个 41 字节的文件
先回顾提交的结构:每次提交生成一个提交对象,包含指向内容快照的指针、作者信息、说明,以及指向父提交的指针。提交串成链,就是历史。
Git 的分支,本质上只是一个指向某条提交的可变指针——实际就是 .git/refs/heads/ 下的一个小文件,里面写着一个 40 位的哈希加换行,共 41 字节。创建分支 = 写一个 41 字节的文件,所以「瞬间完成」毫不夸张。
main(或 master)也不是什么特殊分支,只是 git init 默认创建的第一个分支,和其他分支完全平等。
HEAD:你在哪,它指哪
Git 怎么知道你当前在哪个分支?靠一个特殊指针 HEAD,它指向当前所在的本地分支(再由分支指向具体提交)。
┌────────┐ ┌────────┐
│ testing │───┐ │ main │──┐
└────────┘ │ └────────┘ │
▼ ▼
commit C2 ◀───── 共同历史 C1关键三连:
git branch testing # 创建分支(只建指针,不切换!HEAD 仍在 main)
git checkout testing # 切换过去(HEAD 指向 testing)
git checkout -b newfeat # 创建并切换,一步到位(最常用)切换分支时工作目录的文件会被改变成目标分支的快照内容——切到旧分支,你看到的就是旧版本。若当前有未提交的修改导致无法干净切换,Git 会拒绝并提示。
理解了「分支=指针、HEAD=你在哪」,两分支各自提交后会自然分叉,git log --oneline --graph --all 一眼看清。
合并:快进与三方合并
在 main 上把 feature 的成果收回来:
git checkout main
git merge feature情况一:快进(fast-forward)
如果 main 自分叉后没有新提交,合并就是简单地把 main 指针向前挪到 feature 的最新提交——「快进」,不产生新提交。
情况二:三方合并
如果两个分支都有各自的新提交,Git 会找到它们的共同祖先,把「祖先、你这边最新、对方最新」三方快照做合并,生成一个有两条父指针的合并提交。
冲突:两边改了同一处
两个分支改了同一个文件的同一区域,Git 无法替你决定,会报 CONFLICT (content): Merge conflict in xxx,把该文件标记为冲突状态。打开文件会看到:
<<<<<<< HEAD
你这边的版本
=======
对方分支的版本
>>>>>>> feature解决三步:
- 手动编辑文件,留下想要的最终内容(可以两边都要、可以重写),删掉
<<<<<<</=======/>>>>>>>标记。 git add <冲突文件>标记「已解决」。git commit完成合并提交。
中途想放弃:git merge --abort 回到合并前的状态。工具党可用 git mergetool 打开图形化冲突编辑器。
分支管理常用命令
git branch # 列出本地分支(* 标记当前所在)
git branch -v # 附带每个分支最新提交
git branch --merged # 已合并进当前分支的(可安全删除)
git branch --no-merged # 还有未合并工作的
git branch -d feature # 删除已合并的分支(只是删指针,提交仍在)
git branch -D feature # 强制删除未合并的分支(工作会真的丢失)分支开发工作流
因为建分支几乎零成本,Git 鼓励长期保持 main 稳定可用,所有开发都在主题分支上进行,完成后再合并回去。常见套路:
- 长期分支:
main只放稳定代码,develop承接日常开发,成熟后从 develop 合入 main。 - 主题分支(feature branch):每个功能/每个 bug 一个短命分支,改完即合并删除。分支名用
feature-login、fix-header-crash这类自解释命名。
核心思想:分支是廉价且一次性的,main 是唯一需要长期保持干净的东西。
小结
- 分支 = 指向提交的 41 字节指针文件;
main毫不特殊。 - HEAD 指向当前分支;
git checkout -b建分支并切换。 - 合并两形态:快进(一边没新提交)与三方合并(生成合并提交)。
- 冲突三步:改文件去掉标记 → add → commit;慌了就
--abort。 - 工作流:main 保稳定,一切开发走主题分支。
学完你会得到:
- 「分支只是指针」这个让一切变简单的心智模型
- branch / checkout -b / merge / 冲突处理的完整实操
- 一套直接可用的主题分支工作流
自测
自测
- 为什么说 Git 创建分支是「瞬间」的?分支在磁盘上到底是什么?
git branch testing之后 HEAD 指向哪个分支?要切换需要哪条命令?- 快进合并和三方合并分别在什么条件下发生?
- 冲突标记里的 HEAD 区和 feature 区,各代表谁的修改?
git branch -d删除分支后,该分支上的提交会消失吗?
下一篇:🚀 远程分支与变基