土法炼钢兴趣小组的算法知识备份

【Git 内部】index 暂存区:dircache v2 与扩展节

文章导航

分类入口
opensource
标签入口
#git#git-internals#index#dircache#staging

目录

git status 比较的是工作区、索引与 HEAD 三处状态;git add 写入的是 .git/index,不是对象库。index 是二进制 dircache 文件,记录路径、元数据(stat)、对象 SHA 和冲突 stage。读不懂 index,就无法解释 merge 冲突时 git ls-files -u 的三行同名路径。

本文对照 gitformat-index 说明 v2 布局与常见扩展。冲突 stage 在 merge 场景的完整例子见 第 13 篇


一、文件角色

操作 对 index 的影响
git add 更新或新增条目,stage=0
git commit 用 index 生成 tree,commit 后通常与 HEAD 一致
git checkout 用目标 tree 重写 index
merge 冲突 同路径多条目,stage 1/2/3

index 不进入对象库;但条目里的 SHA 指向 blob 对象(git add 时创建)。

dircache v2 逻辑布局:DIRC 头、条目、扩展节与尾部校验

二、头部与魔数

xxd .git/index 前几行(Git 2.54.0,单文件仓库):

00000000: 4449 5243 0000 0002 0000 0001 6a49 509e  DIRC........jIP.
偏移 内容
0–3 魔数 DIRC
4–7 版本号 2(常见为 dircache v2)
8–11 条目数

其后是每个 index entry 和可选 extensions


三、index entry 概要

每个条目(简化)包含:

git ls-files -s 显示 stage 与 SHA:

100644 ce013625030ba8dba906f756967f9e9ca394464a 0   hello.txt

100644 为模式,0 为 stage(正常暂存)。


四、冲突 stage

merge 失败时,同一路径可出现三条:

100644 df967b96… 1  shared.txt
100644 c354fa8c… 2  shared.txt
100644 1de5a387… 3  shared.txt
stage 含义
1 共同祖先(base)
2 当前分支(ours)
3 并入分支(theirs)
merge 冲突时 index 中同一路径的 stage 0/1/2/3 条目

磁盘上即 index 中三条独立 entry,同名不同 stage。


五、扩展节(extensions)

常见扩展(四字 tag + 数据):

Tag 作用
TREE 缓存的 tree 对象结构,加速 git write-tree
REUC 冲突未合并路径的 stage 信息
FSMN fsmonitor 令牌,加速 status
EOIE / IEOT 条目排序索引,加速查找

本实验仓库 index 末尾可见 TREE 扩展(xxd 中出现 TREE ASCII)。扩展可忽略解析仍能正常用 Git 操作——只有写工具时才需完整实现 gitformat-index


六、index 与工作区一致性

index 存 stat 用于快速判断工作区是否修改(git status 先 stat 再可能读内容)。git update-index --assume-unchanged 等标志在 flags 里。这与对象库不变性正交:blob 一旦写入 objects,内容不因 index 改变。


七、本文边界

复现:

git add .
xxd .git/index | head -6
git ls-files -s

参考资料

系列索引Git 内部结构 · 上篇reflog · 下篇pack 格式

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-07-05 · opensource

【Git 内部】Git 内部结构:对象库与磁盘文件格式

从 .git 目录布局、松散对象与 packfile 格式,到 refs、index、reflog、gc/fsck 与 fetch/push 落地——用官方 format 文档与本地实测 dump 系统讲清 Git 把版本历史存在哪、每个命令改写了哪些文件。全 16 篇。


By .