Git索引确切包含什么,我可以使用什么命令查看索引的内容?
更新资料
感谢您的所有答复。我知道索引充当临时区域,提交的内容在索引中而不是工作树中。我只是对索引对象的组成感到好奇。我想这可能是文件名/目录名称,SHA-1对的列表,也许是一种虚拟树?
用Git术语,是否可以使用任何管道命令列出索引的内容?
Git索引确切包含什么,我可以使用什么命令查看索引的内容?
更新资料
感谢您的所有答复。我知道索引充当临时区域,提交的内容在索引中而不是工作树中。我只是对索引对象的组成感到好奇。我想这可能是文件名/目录名称,SHA-1对的列表,也许是一种虚拟树?
用Git术语,是否可以使用任何管道命令列出索引的内容?
Answers:
Git书中包含有关索引包含的内容的文章:
索引是一个二进制文件(通常保存在中
.git/index
),其中包含路径名称的排序列表,每个路径名称都具有权限和blob对象的SHA1;git ls-files
可以向您显示索引的内容:
$ git ls-files --stage
100644 63c918c667fa005ff12ad89437f2fdc80926e21c 0 .gitignore
100644 5529b198e8d14decbe4ad99db3f7fb632de0439d 0 .mailmap
该情趣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(Q4 2018)添加了一个索引条目偏移表(IEOT):
请参阅Ben Peart()的提交77ff112,提交3255089,提交abb4bb8,提交c780b9c,提交3b1d9e0,提交371ed0d(2018年10月10日)。
见提交252d079通过(2018年9月26日)阮泰玉维战()。(由Junio C Hamano合并--在commit e27bfaa中,2018年10月19日)benpeart
pclouds
gitster
ieot:添加索引条目偏移表(IEOT)扩展
该补丁可通过向索引添加其他数据来解决加载索引的CPU开销,这将使我们能够高效地对缓存条目的加载和转换进行多线程处理。
它通过添加(可选)索引扩展来实现此目的,该索引扩展是索引文件中缓存条目块的偏移量表。
为了使此功能适用于V4索引,在写入缓存条目时,它会通过对当前条目进行编码来周期性地“重置”前缀压缩,就好像前一个条目的路径名完全不同一样,并将该条目的偏移量保存在IEOT中。
基本上,使用V4索引,它会将偏移量生成为前缀压缩条目的块。
使用新的index.threads配置设置,现在索引加载速度更快。
结果(使用IEOT),提交7bd9631清理read-cache.c load_cache_entries_threaded()
Git 2.23(Q3 2019)的功能。
请参阅提交8373037,提交d713e88,提交d92349d,提交113c29a,提交c95fc72,提交7a2a721,提交c016579,提交be27fb7,提交13a1781,提交7bd9631,提交3c1dce8,提交cf7a901,提交d64db5b,提交76a7bc0(09年5月7日)(Jeff (peff
)。
(通过合并JUNIOÇ滨野- gitster
-在提交c0e78f7,2019年6月13日)
读取缓存:从线程加载中删除未使用的参数
该
load_cache_entries_threaded()
函数采用src_offset
不使用的参数。自从77ff112诞生以来就一直存在(read-cache
:在工作线程上加载缓存条目,2018-10-10,Git v2.20.0-rc0)。在邮件列表中,该参数是该系列早期迭代的一部分,但是当代码切换为使用IEOT扩展时,则不再需要该参数。
使用Git 2.29(2020年第四季度)时,格式说明会根据最近的SHA-256工作进行调整。
参见MartinÅgren()提交8afa50a,提交0756e61,提交123712b,提交5b6422a(2020年8月15日)。(通过合并JUNIOÇ滨野- -在提交74a395c 8月19日2020)none
gitster
index-format.txt
:文档SHA-256索引格式签字人:马丁·奥格伦
证明在SHA-1存储库中我们使用SHA-1,在SHA-256存储库中我们使用SHA-256,然后将“ SHA-1”的所有其他使用替换为更中性的东西。
避免引用“ 160位”哈希值。
technical/index-format
现在在其手册页中包括:
所有二进制数字均以网络字节顺序排列。
在使用传统SHA-1的存储库中,以下提到的校验和和对象ID(对象名称)全部使用SHA-1计算。
同样,在SHA-256存储库中,这些值是使用SHA-256计算的。除非另有说明,否则此处将描述版本2。
我决定进行一些测试,以更好地理解格式并更详细地研究某些领域。
下面的结果与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
的 .git
目录是这样的:
.git/objects/
|-- 78
| `-- 981922613b2afb6025042ff6bd878ac1994e85
|-- info
`-- pack
如果我们得到唯一对象的内容:
git cat-file -p 78981922613b2afb6025042ff6bd878ac1994e85
我们得到 a
。这表明:
index
自git add b
创建blob对象以来指向文件内容点现在让我们看一下索引本身:
hd .git/index
给出:
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
接下来我们将得出结论:
| 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
| ... |
首先是标头,定义在:struct cache_header:
44 49 52 43
:DIRC
。TODO:为什么这是必要的?
00 00 00 02
:格式版本:2.索引格式随着时间而发展。当前存在的版本不超过4。在GitHub上的不同计算机之间进行协作时,索引的格式应该不是问题,因为裸存储库不存储索引:它是在克隆时生成的。
00 00 00 01
:索引上的文件数:仅一个,b
。
接下来启动由struct cache_entry定义的索引条目列表。这里只有一个。它包含了:
一堆文件元数据:8字节ctime
,8字节mtime
,4字节:设备,索引节点,模式,UID和GID。
注意如何:
ctime
并且mtime
是相同的(54 09 76 e6 1d 81 6f c6
我们预期),因为我们尚未修改文件
自EPOCH起以十六进制表示的第一个字节为秒:
date --date="@$(printf "%x" "540976e6")"
给出:
Fri Sep 5 10:40:06 CEST 2014
这是我制作此示例的时间。
后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字节的校验和。
git add
,根据您的意见TODO
:您是正确的。如果给定路径上有高级索引条目(发生冲突),则在git add
该路径上时,所有高级索引条目都将被删除,而工作目录副本将在stage处添加0
。(解决冲突)。
Git索引是工作目录和存储库之间的临时区域。您可以使用索引来构建要一起提交的一组更改。创建提交时,提交的内容是此索引中当前的内容,而不是工作目录中的内容。
要查看索引中的内容,请发出以下命令:
git status
当您运行git status时,您可以看到哪些文件已暂存(当前在索引中),哪些文件已修改但尚未暂存以及哪些文件未完全跟踪。
您可以阅读此内容。Google搜索会抛出许多链接,这些链接应该足够自给。
git status
不列出索引中的所有文件。它仅列出索引目录和工作目录之间不同的那些文件。要查看索引中的所有文件,您需要使用git ls-files
。
git status
确实事实上列表索引文件,不论他们是否指数和WORKDIR不同。
git status
列出索引中的文件(是),但不列出索引中的所有文件。解释git status
实际的工作方式将是一个问题的有益答案,尽管可能不是这个问题。
git status
显示工作树状态(工作树和索引之间的差异)。它实际上没有显示索引。git-scm.com/docs/git-status
这正是您真正需要的,使用此命令。
$ binwalk index
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
1717 0x6B5 Unix path: /company/user/user/delete.php
1813 0x715 Unix path: /company/user/user/get.php
1909 0x775 Unix path: /company/user/user/post.php
2005 0x7D5 Unix path: /company/user/user/put.php
3373 0xD2D Unix path: /urban-airship/channel/channel/post.php
3789 0xECD Unix path: /urban-airship/named-user/named-user/post.php
3901 0xF3D Unix path: /user/categories/categories/delete.php
4005 0xFA5 Unix path: /user/categories/categories/get.php
4109 0x100D Unix path: /user/categories/categories/put.php
4309 0x10D5 Unix path: /user/favorites/favorites/delete.php
.git/index
),其中包含路径名的排序列表,每个路径名均具有权限和blob对象的SHA1;git ls-files
可以向您显示索引的内容。请注意,单词index
,stage
和cache
在Git中是同一回事:它们可以互换使用。
Git索引或Git缓存具有3个重要属性:
资料来源:
回应@ ciro-santilli-%e9%83%9d%e6%b5%b7%e4%b8%9c%e5%86%a0%e7%8a%b6%e7%97%85%e5%85%ad %e5%9b%9b%e4%ba%8b%e4%bb%b6%e6%b3%95%e8%bd%ae%e5%8a%9f详细深入查看该指标,共享一份输出在的TODO。
“如果您使用git add,则将阶段0添加到该路径的索引中,Git将知道该冲突已被标记为已解决。TODO:请检查一下。”
并且,更具体地说,是不同的合并阶段。
有关各个阶段的数字表示形式的详细信息,在这种情况下为冲突文件。
$ git ls-files -s
100644 f72d68f0d10f6efdb8adc8553a1df9c0444a0bec 0 vars/buildComponent.groovy
$ git stash list
stash@{0}: WIP on master: c40172e turn off notifications, temporarily
$ git stash apply
Auto-merging vars/commonUtils.groovy
Auto-merging vars/buildComponent.groovy
CONFLICT (content): Merge conflict in vars/buildComponent.groovy
$ git ls-files -s
100644 bc48727339d36f5d54e14081f8357a0168f4c665 1 vars/buildComponent.groovy
100644 f72d68f0d10f6efdb8adc8553a1df9c0444a0bec 2 vars/buildComponent.groovy
100644 24dd5be1783633bbb049b35fc01e8e88facb20e2 3 vars/buildComponent.groovy