git索引包含什么?

moc*_*ino 166 git internal

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 ":

Git索引文件具有以下格式

所有二进制数均按网络字节顺序排列.除非另有说明,否则此处描述
版本2.

  • 一个12字节的标头,包括:
    • 4字节签名:
      签名为{' D',' I',' R',' C'}(代表" dircache")
    • 4字节版本号:
      当前支持的版本为2,3和4.
    • 32位索引条目数.
  • 许多排序的索引条目.
  • 扩展:
    扩展通过签名识别.
    如果Git不理解它们,可以忽略可选扩展.
    Git目前支持缓存树并解析撤消扩展.
    • 4字节扩展签名.如果第一个字节是' A'..' Z',则扩展名是可选的,可以忽略.
    • 32位大小的扩展名
    • 扩展数据
  • 在此校验和之前,索引文件的内容为160位SHA-1.

mljrg 评论:

如果索引是准备下一个提交的地方,为什么" 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日)benpeart
pclouds
gitster

ieot:添加索引条目偏移表(IEOT)扩展名

此补丁通过向索引添加其他数据来解决加载索引的CPU成本,这将允许我们有效地多线程加载和转换缓存条目.

它通过添加(可选)索引扩展来实现此目的,该扩展是索引文件中缓存条目块的偏移表.

为了使这适用于V4索引,在写入缓存条目时,它通过对当前条目进行编码来定期"重置"前缀压缩,就好像前一个条目的路径名完全不同,并保存该条目在IEOT中的偏移量.
基本上,对于V4索引,它会生成前缀压缩条目块的偏移量.

使用新的index.threads配置设置,索引加载现在更快.

  • 关于Git模型中索引的重要性,请参阅http://stackoverflow.com/questions/1450348/git-equivalents-of-most-common-mercurial-commands/1450641#1450641 (6认同)

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对象
  • 它将元数据存储在索引文件中,而不是存储在树对象中,因为只有一个对象:blob(在常规Git对象上,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\necho)

  • 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字节校验和.

  • @NielsBom是的,那也行.在解释程序时,我更倾向于采用两种方法:首先是经验性的,以查看它产生的输出,然后才读取源.否则,可能会陷入源代码边缘情况,甚至不会出现在简单的输出上.当然,我确实查看了源代码结构以帮助指导我,并且每个TODO都可以解决我对这些结构如何被操纵的解释,这是困难的部分. (3认同)

use*_*312 12

Git索引是工作目录和存储库之间的暂存区域.您可以使用索引构建一组要一起提交的更改.创建提交时,提交的内容是此索引中当前的内容,而不是工作目录中的内容.

要查看索引中的内容,请发出以下命令:

git status
Run Code Online (Sandbox Code Playgroud)

当您运行git status时,您可以看到哪些文件已暂存(当前在您的索引中),哪些文件已修改但尚未暂存,哪些文件完全未跟踪.

你可以读这个.谷歌搜索引发了许多链接,这应该是相当自给自足的.

  • `git status`不会列出索引中的所有文件.它仅列出索引和工作目录之间不同的文件.要查看索引中的所有文件,您需要使用`git ls-files`. (7认同)
  • 是的,它列出了一些索引文件,但它没有显示索引中的所有内容,这就是他在回答中所说的内容.这就像说盒子里面有2个绿球和3个红球.要查看盒子里面的内容,请拉出2个绿球.阿卡什所说的最准确,要查看索引中的所有文件,请使用git ls-files. (3认同)
  • 确实.`git status`列出索引中的文件,是,但不列出索引中的_all_文件.解释`git status` _actually_如何工作对某些问题是一个有益的答案,尽管可能不是这个问题. (3认同)

归档时间:

查看次数:

58380 次

最近记录:

6 年,4 月 前