Git Index文件数据结构
前言
在使用git工具管理项目的时候,.git
目录下存放了index文件,这个文件是git的staging area
,也叫做暂存区,也可以理解为当前工作区已经被托管文件的区域。index文件是使用二进制的方式进行存储的,具体内容是一些基础信息数据,然后面就是暂存区的条目信息。
基础环境
我这里简单创建了一个小环境具体创建过程如下
1 | E:\TEMP\TEMPGIT>dir |
使用16进制编辑器打开项目下.git/index
文件,具体内容如下
1 | 44 49 52 43 00 00 00 02 00 00 00 02 67 52 7D 35 |
基础信息
基础信息就是前12bytes具体内容位,它们依次代表的内容如下
1 | 44 49 52 43 00 00 00 02 00 00 00 02 |
前4byte是固定的文件头44 49 52 43
,转换到10进制的内容就是DIRC
.
紧接着的4byte是记录git版本的00 00 00 02
这里的git版本就是2
再后面的4byte是记录git提交次数的00 00 00 02
这里的提交次数是2
条目信息
条目信息的前62位是固定的,之后的长度是按照文件路径名字来计算的,按照上面的数据来说第一条的数据是
1 | 67 52 7D 35 28 C5 D9 74 67 52 7D 42 34 FA 3B A4 |
下面依次说一下每个byte代表的作用
- 8byte内容是ctime,创建文件的时间,前4byte是从1970年1月1日00:00:00计算的时间戳,后4byte是nanosecond微秒,一般前都用前面4byte,文件创建的时间戳
67 52 7D 35
转换过来就是1733459253
即2024-12-06 12:27:33
- 8byte内容是mtime,上次修改的时间,他的格式和CTIME一样,前4byte是时间戳,后面是nanosecond微秒。
67 52 7D 42
转换的时间戳是1733459266
即2024-12-06 12:27:46
- 4byte的内容应该是device即文件存储的设备,我这里是
00 00 00 00
,全0肯定是有些问题,具体问题我也没研究出来。 - 4byte的内容应该是Inode即
文件在设备的文件系统中存储的具体块的编号
,我这里是00 00 00 00
,全0肯定是有些问题,具体问题我也没研究出来。 - 4byte的内容是文件权限,我这里的内容为
00 00 81 A4
转换之后就是100644
,100是代表普通文件,后面的644就是linux中的权限,这里不多说 - 4byte的内容是uid,大概率是因为我用的win系统,所以没展示出来全是0x00
- 4byte的内容是gid,大概率是因为我用的win系统,所以没展示出来全是0x00
- 4byte的内容是文件大小,我这里是
00 00 00 10
转换过来即16,就是16字节 - 20byte的内容是sha-1,我这里的内容为
75 7C B5 AA CC 80 7E B5 B1 FD 67 4E 1F 51 EC 71 DE 00 22 A3
,这个内容在objects
目录中会有对应的文件,这个可以理解为对应文件的索引,以这个sha-1为例,他的位置应该是在.git\objects\75\7cb5aacc807eb5b1fd674e1f51ec71de0022a3
- 2byte的内容是文件的长度,我这里的长度是
00 09
即9位 - 文件名在条目中的占用长度是不固定的,以当前条目为例,其长度为9字节,文件名内容是
52 45 41 44 4D 45 2E 6D 64 00
,转换后为README.md
.但它实际占用了10字节.这是因为在存储时,文件名后会填充0x00
即00
作为分隔符.为了满足存储规则,文件名会按照8字节对齐的方式进行填充.因此,如果条目的总字节长度不能被8整除,会继续填充0x00
,直到长度达到8的倍数.比如本条目就通过填充一个00
字节使得长度符合对齐要求
扩展信息
条目解析结束之后,后面还有一段信息,这段信息的内容是index文件的扩展信息,内容如下
1 | 54 52 45 45 00 00 00 19 00 32 20 30 0A 7E 4E 0F |
前面四个字节是TREE,代表记录的是TREE的信息,这里会记录当前HEAD的SHA-1还有index的SHA-1来确定文件的完整性,这里当前HEAD的sha-1是7E 4E 0F A2 7B 51 A7 2C E3 BA 34 E5 70 F0 8B 89 63 58 C5 9F
紧接着就是index的SHA-1,即4D 52 68 C5 94 87 74 75 74 DA D9 91 8F 7E 56 3D B7 01 82 CD