第 6 章 · 04 分支与 HEAD:本质都是指针 本节摘要:无数人用 Git 多年仍觉得「分支」很神秘,其实它的真相简单得惊人:分支只是一个指向某 commit 的可变指针。本节要讲清分支、HEAD、checkout 的本质:分支是 下的一个文件,存着 commit 哈希;HEAD 是个特殊指针,指向「你当前在哪个分支」。理解「一切皆指针」,你就懂得为什么创建分支这么廉价(只是加个指针)、为什么切分支这么快。 内容来源:基于 Git 内部模型整理的导读。 学习目标 阅读完本节,你应当能够: 说清分支的本质:一个指向 commit 的可变指针(存 )。 说清 HEAD 的本质:指向「当前分支」的特殊指针(存 )。 解释为什么创建分支廉价(只是加个指针文件,不复制内容)。
本节摘要:无数人用 Git 多年仍觉得「分支」很神秘,其实它的真相简单得惊人:分支只是一个指向某 commit 的可变指针。本节要讲清分支、HEAD、checkout 的本质:分支是
.git/refs/heads/下的一个文件,存着 commit 哈希;HEAD 是个特殊指针,指向「你当前在哪个分支」。理解「一切皆指针」,你就懂得为什么创建分支这么廉价(只是加个指针)、为什么切分支这么快。
内容来源:基于 Git 内部模型整理的导读。
阅读完本节,你应当能够:
.git/refs/heads/分支名)。.git/HEAD)。git checkout 干的事:移动 HEAD + 把工作区恢复到目标 commit 的状态。很多人觉得 Git 分支「重」——可能受其他 VCS(如 SVN)影响,那里分支是「复制整个目录」。但 Git 的分支轻得不可思议:它就是一个 41 字节的文件(40 字符哈希 + 换行),存着「这个分支现在指向哪个 commit」。
理解这点,你就懂得:
.git/refs/heads/main 内容: commit3的哈希 .git/refs/heads/dev 内容: commit2的哈希
每个分支一个文件,内容是该分支当前指向的 commit 哈希。「分支」就是这种指针。
.git/HEAD 内容: ref: refs/heads/main
HEAD 通常存「当前在哪个分支」(是个符号引用)。少数情况 HEAD 直接指向 commit(「detached HEAD」状态)。
git branch dev在当前 commit 上建分支 dev:在 .git/refs/heads/ 加个文件 dev,内容 = 当前 commit 哈希。仅此而已,不复制任何内容。所以分支创建是 O(1)。
git checkout dev.git/HEAD 内容 = ref: refs/heads/dev。第 2 步是「让工作区匹配目标分支」,这是切分支的主要成本(但 commit 对象不动)。
在 dev 分支 commit,dev 指针前移,main 不动:
commit 前: dev → commit2 ← main(假设都在这) commit 在 dev 后: dev → commit3(新), commit3.parent → commit2 ← main
这就是「分支 divergence」——dev 与 main 各自前进,形成分叉。
branch 名:在 refs/heads/ 加文件,内容 = 当前 commit。checkout 名:改 HEAD 指向 + 把工作区恢复成目标 commit 的 tree(读 tree,写文件)。.git/refs/heads/分支名 存 commit 哈希)。.git/HEAD)。下一节讲合并——快进 vs 三方,以及 packfile。