第 6 章 · 02 索引与 staging:`git add` 的真相


文档摘要

第 6 章 · 02 索引与 staging: 的真相 本节摘要:新手最困惑的 Git 问题之一:「为什么 add 之后还要 commit?add 到底干了什么?」本节要捅破这层窗户纸。 干的事是:把工作区文件内容存成 blob(进对象库),并在「索引」里记下「这个文件名现在对应这个 blob」。索引(index)是「下一次 commit 的草稿树」——add 是往草稿里添改,commit 是把草稿定稿。理解索引,你就理解了「工作区/暂存区/仓库」三区模型。 内容来源:基于 Git 内部模型整理的导读。 学习目标 阅读完本节,你应当能够: 说清 干的事:把文件内容存成 blob,在索引里记「文件名→blob 哈希」。 解释「索引」是「下一次 commit 的草稿树」。

第 6 章 · 02 索引与 staging:git add 的真相

本节摘要:新手最困惑的 Git 问题之一:「为什么 add 之后还要 commit?add 到底干了什么?」本节要捅破这层窗户纸。git add 干的事是:把工作区文件内容存成 blob(进对象库),并在「索引」里记下「这个文件名现在对应这个 blob」。索引(index)是「下一次 commit 的草稿树」——add 是往草稿里添改,commit 是把草稿定稿。理解索引,你就理解了「工作区/暂存区/仓库」三区模型。

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

学习目标

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

  1. 说清 git add 干的事:把文件内容存成 blob,在索引里记「文件名→blob 哈希」。
  2. 解释「索引」是「下一次 commit 的草稿树」。
  3. 区分 Git 三区:工作区(你看到的)、暂存区/索引(草稿)、仓库/对象库(已 commit 的)。
  4. 解释为什么需要 add(给用户机会筛选「哪些改动一起提交」)。

一、学习价值:解开 Git 最大困惑

「add 完还要 commit」是 Git 新手最大困惑。很多人记成「add 标记为待提交」,但这只是表象。真相是:add 把文件内容物化成 blob 并登记进索引,commit 把索引定稿成一棵 tree 加 commit 对象。

理解索引,你不仅解开困惑,更理解了 Git 的「灵活性」——你可以 add 文件 A 的改动、不 add 文件 B(把它们的改动分到不同 commit),这种「精细控制每次提交内容」的能力,是 Git 相对其他 VCS 的优势,而它建立在索引模型上。

二、子系统拆解

三区模型

工作区(Working) 暂存区(Index/Staging) 仓库(Repository) 你看到的文件 ─add─► 下次commit的草稿 ─commit─► 对象库(.git/objects) ◄─checkout─ ◄─┘
  • 工作区:磁盘上你直接编辑的文件。
  • 暂存区/索引:一个二进制文件 .git/index,记录「文件名 → blob 哈希 + 元信息」的列表,是「下一次 commit 的草稿」。
  • 仓库/对象库:.git/objects/,存所有 blob/tree/commit 对象,不可变。

git add 干的事

git add hello.txt: 1. 读 hello.txt 内容 2. 算哈希, 存成 blob 进对象库(若已存在则跳过, 去重) 3. 在索引里更新/添加一条: "hello.txt → 这个 blob 哈希"

注意:add 只动索引(草稿),没创建 commit。文件内容的 blob 虽进了对象库,但还没有 tree/commit 引用它——它是「待用」状态。

git commit 干的事(下一节详述)

git commit: 1. 把当前索引的「文件名→blob」列表, 构建成一棵 tree 对象 2. 创建一个 commit 对象: 指向这棵 tree + parent(上次 commit) + 信息 3. 移动当前分支指针到新 commit

为什么需要索引(为什么不能直接 commit 工作区)

设想没有索引、commit 直接拍工作区快照——那你改了 5 个文件,只能全部一起提交,无法拆分。索引让你「挑哪些改动进这次 commit」:add A、add B,然后 commit(只含 A、B 的改动),C 的改动留到下次。这种「精细控制提交粒度」是 Git 的核心体验。

三、上手第一步:实现 add 与索引

  1. 索引用一个简单结构存(如 JSON 或文本):{文件名: blob哈希}
  2. add 文件:读内容→hash_object 存 blob→更新索引里该文件名的条目。
  3. status:对比「工作区文件」与「索引」与「当前 commit 的 tree」,显示哪些 add 了、哪些改了没 add。
  4. 验证:改文件、add、status 应显示「已暂存」。

本节要点回顾

  1. git add = 把文件存成 blob + 在索引记「文件名→blob 哈希」,只动索引,不创建 commit。
  2. 索引是「下次 commit 的草稿树」,存 .git/index
  3. 三区:工作区(看到的)→ 暂存区/索引(草稿)→ 仓库/对象库(已 commit);add 跨前两区,commit 跨后两区。
  4. 索引的价值:让你精细控制「哪些改动一起提交」,这是 Git 的核心体验。

推荐上手顺序

  1. 实现最简索引(文件名→blob哈希的映射)。
  2. 实现 add:存 blob + 更新索引。
  3. 实现 status:对比工作区/索引/上次 commit,显示差异。
  4. 理解三区后,下一节实现 commit(把索引定稿为 tree+commit)。

下一节讲 commit——把索引定稿成快照。


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