Git索引究竟包含什么,以及我可以使用什么命令来查看索引的内容?
更新
谢谢你的所有答案.我知道索引充当临时区域,提交的内容是索引而不是工作树.我只是对索引对象的内容感到好奇.我想它可能是文件名/目录名列表,SHA-1对,也许是一种虚拟树?
在Git术语中,是否有任何可用于列出索引内容的管道命令?
Von*_*onC 150
Git书包含一篇关于索引包含的内容的文章:
索引是一个二进制文件(通常保存在其中
.git/index),包含一个排序的路径名列表,每个路径名都有权限和blob对象的SHA1;git ls-files可以显示索引的内容:
$ git ls-files --stage
100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0 .gitignore
100644 5529b198e8d14decbe4ad99db3f7fb632de0439d 0 .mailmap
Run Code Online (Sandbox Code Playgroud)
该情趣git的问题给出了该结构的详细说明:
索引是git中最重要的数据结构之一.
它通过记录路径列表及其对象名称来表示虚拟工作树状态,并用作暂存区域以写出要提交的下一个树对象.
状态是"虚拟的",因为它不一定必须与工作树中的文件匹配,并且通常不匹配.
要了解更多信息,请参阅 " git/git/Documentation/technical/index-format.txt ":
所有二进制数均按网络字节顺序排列.除非另有说明,否则此处描述
版本2.
- 一个12字节的标头,包括:
- 4字节签名:
签名为{'D','I','R','C'}(代表"dircache")- 4字节版本号:
当前支持的版本为2,3和4.- 32位索引条目数.
- 许多排序的索引条目.
- 扩展:
扩展通过签名识别.
如果Git不理解它们,可以忽略可选扩展.
Git目前支持缓存树并解析撤消扩展.
- 4字节扩展签名.如果第一个字节是'
A'..'Z',则扩展名是可选的,可以忽略.- 32位大小的扩展名
- 扩展数据
- 在此校验和之前,索引文件的内容为160位SHA-1.
如果索引是准备下一个提交的地方,为什么"
git ls-files -s"在提交后不返回任何内容?
因为索引表示正在跟踪的内容,并且在提交之后,所跟踪的内容与上次提交相同(不git diff --cached返回任何内容).
因此git ls-files -s列出了所有跟踪的文件(输出中的对象名称,模式位和阶段编号).
该列表(被跟踪的元素)使用提交的内容进行初始化.
切换分支时,索引内容将重置为刚刚切换到的分支引用的提交.
Git 2.20(Q8 2018)添加了索引条目偏移表(IEOT):
请参阅Ben Peart()提交77ff112,提交3255089,提交abb4bb8,提交c780b9c,提交3b1d9e0,提交371ed0d(2018年10月10日).
见提交252d079通过(2018年9月26日)阮泰玉维战().(由Junio C Hamano合并- -在提交e27bfaa,2018年10月19日)benpeartpclouds
gitster
ieot:添加索引条目偏移表(IEOT)扩展名
此补丁通过向索引添加其他数据来解决加载索引的CPU成本,这将允许我们有效地多线程加载和转换缓存条目.
它通过添加(可选)索引扩展来实现此目的,该扩展是索引文件中缓存条目块的偏移表.
为了使这适用于V4索引,在写入缓存条目时,它通过对当前条目进行编码来定期"重置"前缀压缩,就好像前一个条目的路径名完全不同,并保存该条目在IEOT中的偏移量.
基本上,对于V4索引,它会生成前缀压缩条目块的偏移量.
使用新的index.threads配置设置,索引加载现在更快.
Cir*_*四事件 60
我决定做一些测试,以更好地理解格式,并更详细地研究一些领域.
对于Git版本1.8.5.2和结果,下面的结果是相同的2.3.
我有一些我不确定/未找到的标记TODO:请随意补充这些要点.
正如其他人所提到的,索引存储在.git/index,而不是作为标准树对象,其格式是二进制的,并记录在:https://github.com/git/git/blob/master/Documentation/technical/index-format.文本
定义索引的主要结构位于cache.h,因为索引是用于创建提交的缓存.
当我们启动一个测试存储库时:
git init
echo a > b
git add b
tree --charset=ascii
Run Code Online (Sandbox Code Playgroud)
该.git目录看起来像:
.git/objects/
|-- 78
| `-- 981922613b2afb6025042ff6bd878ac1994e85
|-- info
`-- pack
Run Code Online (Sandbox Code Playgroud)
如果我们得到唯一对象的内容:
git cat-file -p 78981922613b2afb6025042ff6bd878ac1994e85
Run Code Online (Sandbox Code Playgroud)
我们得到了a.这表明:
index指向文件内容的点,因为git add b创建了一个blob对象现在让我们看一下索引本身:
hd .git/index
Run Code Online (Sandbox Code Playgroud)
得到:
00000000 44 49 52 43 00 00 00 02 00 00 00 01 54 09 76 e6 |DIRC.... ....T.v.|
00000010 1d 81 6f c6 54 09 76 e6 1d 81 6f c6 00 00 08 05 |..o.T.v. ..o.....|
00000020 00 e4 2e 76 00 00 81 a4 00 00 03 e8 00 00 03 e8 |...v.... ........|
00000030 00 00 00 02 78 98 19 22 61 3b 2a fb 60 25 04 2f |....x.." a;*.`%./|
00000040 f6 bd 87 8a c1 99 4e 85 00 01 62 00 ee 33 c0 3a |......N. ..b..3.:|
00000050 be 41 4b 1f d7 1d 33 a9 da d4 93 9a 09 ab 49 94 |.AK...3. ......I.|
00000060
Run Code Online (Sandbox Code Playgroud)
接下来我们将得出结论:
| 0 | 4 | 8 | C |
|-------------|--------------|-------------|----------------|
0 | DIRC | Version | File count | ctime ...| 0
| ... | mtime | device |
2 | inode | mode | UID | GID | 2
| File size | Entry SHA-1 ...|
4 | ... | Flags | Index SHA-1 ...| 4
| ... |
Run Code Online (Sandbox Code Playgroud)
首先是头文件,定义于:struct cache_header:
44 49 52 43:DIRC.托多:为什么这有必要?
00 00 00 02:format version:2.索引格式随着时间的推移而发展.目前存在最多4个版本.在GitHub上的不同计算机之间进行协作时,索引的格式不应该是一个问题,因为裸存储库不存储索引:它是在克隆时生成的.
00 00 00 01:索引上的文件数:只有一个,b.
接下来启动一个索引条目列表,由struct cache_entry定义.这里我们只有一个.它包含:
一堆文件元数据:8字节ctime,8字节mtime,然后4字节:设备,inode,模式,UID和GID.
请注意:
ctime并且与预期mtime相同(54 09 76 e6 1d 81 6f c6),因为我们没有修改文件
第一个字节是自EPOCH十六进制以来的秒数:
date --date="@$(printf "%x" "540976e6")"
Run Code Online (Sandbox Code Playgroud)
得到:
Fri Sep 5 10:40:06 CEST 2014
Run Code Online (Sandbox Code Playgroud)
这就是我做这个例子的时候.
第二个4字节是纳秒.
UID和GID是00 00 03 e8十六进制的1000:单用户设置的常用值.
所有这些元数据(其中大部分都不存在于树对象中)允许Git在不比较整个内容的情况下检查文件是否快速更改.
在一行的开头30:00 00 00 02:文件大小:2个字节(a和\n从echo)
78 98 19 22 ... c1 99 4e 85:条目的先前内容上的20字节SHA-1.请注意,根据我使用假定有效标志的实验,此SHA-1中不考虑其后面的标志.
2字节标志: 00 01
1位:假设有效标志.我的调查表明,这个命名不佳的国旗是git update-index --assume-unchanged存储其状态的地方:https://stackoverflow.com/a/28657085/895245
1位扩展标志.确定是否存在扩展标志.必须是0版本2,没有扩展标志.
合并期间使用的2位阶段标志.阶段记录在man git-merge:
0:常规文件,不在合并冲突中1:基地2:我们的3:他们的在合并冲突期间,1-3中的所有阶段都存储在索引中以允许类似的操作git checkout --ours.
如果您git add,则将阶段0添加到路径的索引中,Git将知道冲突已标记为已解决.TODO:检查一下.
将跟随的路径的12位长度0 01::仅自路径起1字节b
2字节扩展标志.只有在基本标志上设置了"扩展标志"时才有意义.去做.
62(ASCII b):可变长度路径.在前面的标志中确定的长度,这里只有1个字节,b.
然后是00:1-8个字节的零填充,这样路径将以空值终止,索引将以8个字节的倍数结束.这仅在索引版本4之前发生.
没有使用扩展名.Git知道这一点,因为文件中没有足够的空间用于校验和.
最后ee 33 c0 3a .. 09 ab 49 94,对索引的内容进行20字节校验和.
use*_*312 12
Git索引是工作目录和存储库之间的暂存区域.您可以使用索引构建一组要一起提交的更改.创建提交时,提交的内容是此索引中当前的内容,而不是工作目录中的内容.
要查看索引中的内容,请发出以下命令:
git status
Run Code Online (Sandbox Code Playgroud)
当您运行git status时,您可以看到哪些文件已暂存(当前在您的索引中),哪些文件已修改但尚未暂存,哪些文件完全未跟踪.
你可以读这个.谷歌搜索引发了许多链接,这应该是相当自给自足的.
| 归档时间: |
|
| 查看次数: |
58380 次 |
| 最近记录: |