第 6 章 · 04 分支与 HEAD:本质都是指针


文档摘要

第 6 章 · 04 分支与 HEAD:本质都是指针 本节摘要:无数人用 Git 多年仍觉得「分支」很神秘,其实它的真相简单得惊人:分支只是一个指向某 commit 的可变指针。本节要讲清分支、HEAD、checkout 的本质:分支是 下的一个文件,存着 commit 哈希;HEAD 是个特殊指针,指向「你当前在哪个分支」。理解「一切皆指针」,你就懂得为什么创建分支这么廉价(只是加个指针)、为什么切分支这么快。 内容来源:基于 Git 内部模型整理的导读。 学习目标 阅读完本节,你应当能够: 说清分支的本质:一个指向 commit 的可变指针(存 )。 说清 HEAD 的本质:指向「当前分支」的特殊指针(存 )。 解释为什么创建分支廉价(只是加个指针文件,不复制内容)。

第 6 章 · 04 分支与 HEAD:本质都是指针

本节摘要:无数人用 Git 多年仍觉得「分支」很神秘,其实它的真相简单得惊人:分支只是一个指向某 commit 的可变指针。本节要讲清分支、HEAD、checkout 的本质:分支是 .git/refs/heads/ 下的一个文件,存着 commit 哈希;HEAD 是个特殊指针,指向「你当前在哪个分支」。理解「一切皆指针」,你就懂得为什么创建分支这么廉价(只是加个指针)、为什么切分支这么快。

内容来源:基于 Git 内部模型整理的导读。

学习目标

阅读完本节,你应当能够:

  1. 说清分支的本质:一个指向 commit 的可变指针(存 .git/refs/heads/分支名)。
  2. 说清 HEAD 的本质:指向「当前分支」的特殊指针(存 .git/HEAD)。
  3. 解释为什么创建分支廉价(只是加个指针文件,不复制内容)。
  4. 解释 git checkout 干的事:移动 HEAD + 把工作区恢复到目标 commit 的状态。
  5. 实现 branch/checkout。

一、学习价值:解开「分支神秘感」

很多人觉得 Git 分支「重」——可能受其他 VCS(如 SVN)影响,那里分支是「复制整个目录」。但 Git 的分支轻得不可思议:它就是一个 41 字节的文件(40 字符哈希 + 换行),存着「这个分支现在指向哪个 commit」。

理解这点,你就懂得:

  • 创建分支 O(1)(加个文件)。
  • 切分支 O(项目大小)(恢复工作区,但 commit 都在不动)。
  • 分支不「属于」某 commit,它只是「指着」某 commit。

二、子系统拆解

分支是文件

.git/refs/heads/main 内容: commit3的哈希 .git/refs/heads/dev 内容: commit2的哈希

每个分支一个文件,内容是该分支当前指向的 commit 哈希。「分支」就是这种指针。

HEAD 指向当前分支

.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

  1. 把 HEAD 改成指向 dev:.git/HEAD 内容 = ref: refs/heads/dev
  2. 把工作区与索引恢复成 dev 指向的 commit 的状态(读那棵 tree,写文件到工作区)。

第 2 步是「让工作区匹配目标分支」,这是切分支的主要成本(但 commit 对象不动)。

分支指针随 commit 前移

在 dev 分支 commit,dev 指针前移,main 不动:

commit 前: dev → commit2 ← main(假设都在这) commit 在 dev 后: dev → commit3(新), commit3.parent → commit2 ← main

这就是「分支 divergence」——dev 与 main 各自前进,形成分叉。

三、上手第一步:实现 branch/checkout

  1. branch 名:在 refs/heads/ 加文件,内容 = 当前 commit。
  2. checkout 名:改 HEAD 指向 + 把工作区恢复成目标 commit 的 tree(读 tree,写文件)。
  3. 验证:在 A 分支 commit,B 分支不动;切回 B,工作区变回 B 的状态。

本节要点回顾

  1. 分支 = 指向 commit 的可变指针(.git/refs/heads/分支名 存 commit 哈希)。
  2. HEAD = 指向当前分支的特殊指针(.git/HEAD)。
  3. 创建分支 O(1):只加个指针文件,不复制内容——所以分支廉价。
  4. checkout = 移动 HEAD + 恢复工作区到目标 commit;commit 对象不动。
  5. commit 在某分支,该分支指针前移,其他不动——这就是分叉。

推荐上手顺序

  1. 实现 branch:加指针文件。
  2. 实现 checkout:改 HEAD + 读目标 commit 的 tree 写工作区。
  3. 在 A 分支 commit,B 不动;切回 B 验证状态。
  4. 理解分叉后,下一节讲合并。

下一节讲合并——快进 vs 三方,以及 packfile。


发布者: 作者: 灏天文库 转发
评论区 (0)
U