Git: значение объекта 'size', возвращаемое git verify-pack

Команда git verify-pack имеет -v опция, которая выводит много диагностической информации для каждого объекта, найденного в файле пакета. Однако значение, возвращаемое size поле для объекта с разделением на части не соответствует моим туманным ожиданиям - я думал, что это будет что-то вроде несжатого "истинного" размера объекта Git? Каково действительное значение этого поля?

В частности, у меня есть Git packfile, который содержит большой объект:

$ git cat-file -s 7daa9e75f86aa168748aef6c16c76b2acee1acca
61464170

(т. е. размер объекта составляет около 58 МБ, и это действительно то, что я вижу, когда проверяю файл)

Однако строка, возвращаемая для этого объекта git verify-pack -v это:

7daa9e75f86aa168748aef6c16c76b2acee1acca blob   568352 529608 770759074 1 27e47895a3822906eb31b05fe674ad470296c12e

(полная копия результатов проверки пакета доступна здесь)

Как вы можете видеть (после прочтения документации для git verify-pack), этот объект хранится в deltafied, и определение столбцов таково:

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

Таким образом, "размер" для этого объекта - 568352 (а "размер-в-файле" - 529608) - но что это значит, учитывая, что фактический размер объекта составляет 61464170 байт? Разница между величиной и порядком в размерах должна означать, что значение размера относится только к дельте?

2 ответа

Решение

Сначала посмотрите на эту диаграмму. Затем, исходя из источника (builtin/index-pack.c), значение в четвертом поле:

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

который является сырым упакованным размером (obj[1] следующий объект после этого, или трейлер). Поскольку хранимый элемент делитифицирован, это размер дельта-сжатых данных плюс накладные расходы. Значение в третьем поле obj->size (первое значение размера из верхней области).

(Чтобы получить фактические данные или даже их размер, вам нужно немного надуть поток, а затем посмотреть на дельта-заголовки. "Истинный" размер объекта кодируется в заголовке как второе значение размера. См. get_size_from_delta в sha1_file.c, get_delta_hdr_size в delta.hи "кодирование смещения" на диаграмме.)


Отредактируйте, чтобы добавить: Хорошо, перечитывая вопрос, вы спрашиваете больше о том, почему четвертый размер намного меньше, чем третий. Это было бы потому, что третий - это завышенный (но не детализированный) размер объекта. Итак: size-in-packfile (поле 4) находится после дефляции, но также включает в себя немного заголовка; размер дельта-сжатого файла (поле 3) очевиден; и размер конечного файла после отмены дельта-сжатия находится в заголовке, чей счетчик байтов включен в файл size-in-packfile (поле 4).

Дополнительное редактирование: смещение в пакете (поле 5) obj->idx.offset, Вот где ты должен lseek() в файле пакета, чтобы начать чтение объекта (я думаю, у меня есть некоторый запутанный код для обработки OBJ_OFS_DELTA тоже:-)).

В Git 2.21 (Q1 2019) значение слова "размер объекта" уточняется как " --format=<placeholder> вариант for-each-ref, branch а также tag научился показывать еще несколько признаков объектов, которые могут быть изучены API object_info.

Смотри коммит 59012fe, коммит 5610d9f, коммит 33311fa, коммит f4ee22b, коммит 5305a55, коммит 1867ce6 (24 декабря 2018 г.) от Olga Telezhnaya ( telezhnaya )
(Объединено Юнио С Хамано - gitster - в коммите 55574bd, 18 января 2019 г.)

ref-filter: добавлять objectsize:disk вариант

Добавить новую опцию форматирования objectsize:disk чтобы узнать точный размер этого объекта на диске.

git for-each-ref Страница man теперь гласит:

objectsize:

Размер объекта (такой же как git cat-file -s доклады).
присоединять :disk чтобы получить размер в байтах, который объект занимает на диске.

deltabase:

Это расширяется до имени объекта дельта-базы для данного объекта, если оно хранится как дельта.
В противном случае он расширяется до нулевого имени объекта (все нули).

Предостережения:

Обратите внимание, что размеры объектов на диске сообщаются точно, но при составлении выводов о том, какие ссылки или объекты отвечают за использование диска, следует соблюдать осторожность.
Размер упакованного недельта-объекта может быть намного больше, чем размер объектов, которые являются дельтами против него, но выбор того, какой объект является основой, а какой является дельтой, является произвольным и может изменяться во время повторной упаковки.

Также обратите внимание, что в базе данных объектов может присутствовать несколько копий объекта; в этом случае не определено, какой размер копии или дельта-база будут сообщены.

Таким образом, вы можете сравнить эти значения с сообщенным git verify-pack -v, как git for-each-ref теперь (5+ лет спустя) может отображать больше данных.

Недавно была выпущена серия патчей [RFC/PATCH 0/4] cat-file - размеры пакетного диска, в которую вошло "cat-file [PATCH 07/10]: добавить атом формата%(objectsize:disk)", который может быть интересным, если вы в компиляции из исходного кода.

Другие вопросы по тегам