Index是Git的一个缓冲区域,很多操作都会涉及index。

作用

Index作为一个准备区域,在提交到仓库之前,改动会先缓存在Index之中;从仓库检出代码的时候,也会将内容在Index进行缓存。

Index主要用于索引关乎于仓库存储的各种标的项,但是也包含扩展项,为索引添加额外内容。

相关的介绍文章有:

格式

格式参考

所有的数值都是以网络序存储

  • 12字节头部
    • 4字节签名
      • DIRC四个独立的字母,代表dircache
    • 4字节版本号
      • 支持的版本号:2、3或4
    • 32bit,用于记录索引项的数目
  • 索引项列表
  • 扩展
    • 扩展有各自的签名,长度为4个字节
    • 签名首字节为AZ的扩展是可选的,可以被忽略
    • Git默认支持cache tree和resolve undo阔炸,不被Git识别的会被忽略
    • 扩展的内容大小以32bit表示
  • 上述内容的校验和

索引项按名字字段升序排列。名字比较采用的是memcmp,没有任何本地化的慨念。名字字段相同的按照stage字段升序排列。

一个索引项通常对应一个文件(sparse-checkout情形下例外),有32比特ctime的秒数部分、32比特ctime的纳秒数部分,32比特的mtime的秒数部分、32的mtime的纳秒数部分、32比特dev号、32比特ino号、32比特模式(分高低比特)、4比特对象类型(常规文件、符号链接、gitlink)、3比特不做使用、9比特unix文件权限、32比特uid、32比特gid、32比特文件大小(大小超过32比特部分砍掉)、对象名字、16比特旗标、1比特assume-flag旗标、1比特扩展旗标(版本2中必须为0)、2比特stage(合并过程使用)、12比特名字长度(如果超过则设为0xFFF)、16比特字段,用作扩展旗标(须前面的1比特扩展旗标置一)、1比特保留、1比特skip-worktree旗标(用于sparse checkout)、1比特须添加旗标(使用于"git add -N")、13比特全零不做使用、相对于仓库顶层目录的(可变长)路径名(v4中格式可能不同)、1到8个nul字节用于补齐(v4中不需要)

split index 模式下,index的格式有所不同。

Cache tree扩展

索引项里面不包含目录,所以cache tree用于缓存tree,也就是目录相关的标的。

cache tree扩展的签名是’T', ‘R’, ‘E’, ‘E’。

Resolve undo扩展

索引中的冲突项的stage旗标会被置上。已化解的冲突项会被移到这个扩展中。

Resolve undo扩展的签名是’R', ‘E’, ‘U’, ‘C’。

Split index扩展

可以把索引分散到多个文件中。

Split index扩展的签名是’l', ‘i’, ‘n’, ‘k’。

Untracked cache扩展

缓存不受跟踪的文件列表。

Untracked cache的签名是’U', ‘N’, ‘T’, ‘R’。

File System Monitor cache扩展

用于缓存core.fsmonitor所告知的文件

File System Monitor cache扩展是’F', ‘S’, ‘M’, ‘N’ 。

End of Index Entry扩展

用于分隔索引项和扩展项。

End of Index Entry扩展的签名是’E', ‘O’, ‘I’, ‘E’。

Index Entry Offset Table扩展

有助于开启针对index的多线程处理。

Index Entry Offset Table扩展的签名是’I', ‘E’, ‘O’, ‘T’。

Sparse Directory Entries扩展

Sparse Directory Entries扩展的签名为’s', ’d', ‘i’, ‘r’。

实践

首先创建一个git repo

mkdir repo
cd repo
git init
echo a > a
git add a
echo b > b
git add b

这样文件a的内容就会缓存在index中。可以通过git ls-files --stage查看缓存的内容。

可以通过pip安装一个python脚本in查看此仓库index的内容:

pip3 install gin
gin .

参考链接

关于git internals的介绍文章

其他介绍文章

(完)