Git:对象的含义 'size' 由 git 验证包返回



git-verify pack命令有一个-v选项,它为packfile中的每个对象输出大量诊断信息。然而,经过deltified的对象的size字段返回的值与我模糊的预期不匹配——我以为它会是Git对象的未压缩"真实"大小?这个字段的实际含义是什么?

具体来说,我有一个Git包文件,其中包含一个大对象:

$ git cat-file -s 7daa9e75f86aa168748aef6c16c76b2acee1acca
61464170

(即对象大小约为58MB,这确实是我检查文件时看到的)

但是,git verify-pack -v为此对象返回的行是:

7daa9e75f86aa168748aef6c16c76b2acee1acca blob   568352 529608 770759074 1 27e47895a3822906eb31b05fe674ad470296c12e

(此处提供验证包输出的完整副本)

正如您所看到的(在阅读了git verify-pack的文档后),该对象被存储为增量,列的定义如下:

SHA1 type size size-in-packfile offset-in-packfile depth base-SHA1

因此,这个对象的"大小"是568352(而"packfile中的大小"是529608),但考虑到实际对象大小是61464170字节,这意味着什么?大小的数量级差异一定意味着大小数字只是指德尔塔?

首先,请参阅此图。然后,基于源(builtin/index-pack.c),第四个字段中的值为:

(unsigned long)(obj[1].idx.offset - obj->idx.offset)

它是原始的打包大小(obj[1]是这个之后的下一个对象或预告片)。当存储项被三角化时,这就是三角压缩数据的大小加上开销。第三字段中的值是obj->size(来自开销区域的第一个大小值)。

(要获得实际数据,甚至其大小,您必须对流进行一点膨胀,然后查看delta标头。对象的"true"大小在标头中编码为第二个大小值。请参阅sha1_file.c中的get_size_from_deltadelta.h中的get_delta_hdr_size和图中的"偏移编码"。)


编辑添加:好吧,重读这个问题,你会问更多关于为什么第四个尺寸比第三个小得多的问题。这是因为第三个是物体的膨胀(但不是去增量)大小。所以:packfile(字段4)中的大小是经过放气后的,但也包含了一点头开销;delta压缩文件(字段3)的大小是显而易见的;在取消delta压缩后,最终文件的大小在报头中,该报头的字节计数与packfile中的大小一起包括(字段4)。

额外编辑:packfile(字段5)中的偏移量为obj->idx.offset。这就是你必须在包文件中使用lseek()才能开始读取对象的地方(我想,我面前也有一些处理OBJ_OFS_DELTA的令人困惑的代码:-)。

通过Git 2.21(2019年第1季度),"对象大小"的含义得到了澄清,因为for-each-refbranchtag的"--format=<placeholder>"选项学习到了可以通过object_info API学习的对象的更多特征。

参见Olga Telezhnaya(telezhnaya)提交的提交59012fe、提交5610d9f、提交33311fa、提交f4ee22b、提交5305a55、提交1867ce6(2018年12月24日)
(由Junio C Hamano合并——gitster——提交55574bd,2019年1月18日)

ref-filter:添加objectsize:disk选项

添加新的格式化选项objectsize:disk,以了解对象在磁盘上占据的确切大小。

git for-each-ref手册页现在显示:

objectsize:

对象的大小(与'git cat-file -s'报告相同)
附加:disk以获得对象在磁盘上占用的大小(以字节为单位)。

deltabase:

如果给定对象存储为delta,则扩展为该对象的delta基的对象名称
否则,它将扩展为空对象名称(全部为零)。

注意事项:

请注意,磁盘上对象的大小是准确报告的,但在得出哪些引用或对象负责磁盘使用的结论时应小心
打包的非delta对象的大小可能远大于相对于它进行delta的对象的大小,但选择哪个对象是基对象,哪个对象是delta是任意的,并且在重新打包过程中可能会发生变化

还要注意,对象数据库中可能存在对象的多个副本;在这种情况下,将报告哪个副本的大小或delta基数是未定义的。

因此,您可以将这些值与git verify-pack -v报告的值进行比较,因为git for-each-ref现在(5年多后)能够显示更多数据。

最近有一个补丁系列[RFC/PACH 0/4]cat file-batch disk size讨论,其中包括"[PACH 07/10]cat file:add%(objectsize:disk)format atom",如果你想从源代码编译,这可能会很有趣。

最新更新