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)", который может быть интересным, если вы в компиляции из исходного кода.