Полезна ли перепаковка репозитория для больших двоичных файлов?
Я пытаюсь преобразовать большую историю из Perforce в Git, и одна папка (теперь git branch) содержит значительное количество больших двоичных файлов. Моя проблема в том, что у меня не хватает памяти во время работы git gc --aggressive
,
Мой основной вопрос здесь заключается в том, может ли перепаковка репозитория оказать сколько-нибудь значимое влияние на большие двоичные файлы. Сжатие их еще 20% было бы здорово. 0,2% не стоит моих усилий. Если нет, я их пропущу, как предложено здесь.
Для фона я успешно использовал git p4
чтобы создать хранилище в состоянии, в котором я доволен, но это использует git fast-import
за кулисами, поэтому я хочу оптимизировать репозиторий, прежде чем сделать его официальным, и, действительно, любые коммиты автоматически запускаются медленно gc --auto
, Это в настоящее время ~35 ГБ в чистом виде.
Представляется, что рассматриваемые двоичные файлы являются концептуально прошивкой производителя, используемой во встроенных устройствах. Я думаю, что есть приблизительно 25 в диапазоне 400-700 МБ и, возможно, еще пара сотен в диапазоне 20-50 МБ. Это могут быть образы дисков, но я не уверен в этом. Есть множество версий и типов файлов с течением времени, и я вижу, .zip
, tgz
, а также .simg
файлы часто. Таким образом, я ожидаю, что исходный код будет иметь значительное совпадение, но я не уверен, насколько похожи реальные файлы на данный момент, так как я считаю, что эти форматы уже сжаты, верно?
Эти двоичные файлы содержатся в одной (старой) ветке, которая будет использоваться излишне редко (на тот момент, что вопрос управления версиями вообще действителен, но выходит за рамки). Конечно, производительность этой ветви не обязательно должна быть отличной. Но я бы хотел, чтобы остальная часть хранилища была разумной.
Другие предложения для оптимальной упаковки или управления памятью приветствуются. Признаюсь, я не очень понимаю различные варианты git, обсуждаемые по связанному вопросу. Я не очень понимаю, что --window
а также --depth
флаги делают в git repack
, Но основной вопрос заключается в том, делает ли переупаковка самих бинарных файлов что-то значимое.
4 ответа
Мой основной вопрос здесь заключается в том, может ли перепаковка репозитория оказать сколько-нибудь значимое влияние на большие двоичные файлы.
Это зависит от их содержания. Для файлов, которые вы указали конкретно:
Я часто вижу файлы.zip, tgz и.simg.
Файлы Zipfiles и tgz (архив gzipped tar) уже сжаты и имеют ужасные (то есть, высокие) значения энтропии Шеннона - ужасные для Git, то есть - и не будут сжиматься друг против друга. .simg
файлы, вероятно (я должен догадаться здесь), файлы образов диска Singularity; и как они сжаты, я не знаю, но я бы предположил, что они сжаты. (Простой тест состоит в том, чтобы подать его в компрессор, например, в gzip, и посмотреть, сжимается ли он.)
Таким образом, я ожидаю, что исходный код будет иметь значительное совпадение, но я не уверен, насколько похожи реальные файлы на данный момент, так как я считаю, что эти форматы уже сжаты, верно?
Точно. Хранение их в Git без сжатия, как это ни парадоксально, приведет к гораздо большему сжатию в конце. (Но упаковка может потребовать значительного количества памяти.)
Если [это, вероятно, бесполезно], я пропущу их, как предложено здесь.
Это был бы мой первый импульс здесь.:-)
Признаюсь, я не очень понимаю различные варианты git, обсуждаемые по связанному вопросу. Я не очень понимаю, что
--window
а также--depth
флаги делают вgit repack
,
Различные ограничения сбивают с толку (и обильны). Также важно понимать, что они не копируются на клон, так как они находятся в .git/config
который не является зафиксированным файлом, поэтому новые клоны не будут их забирать. .gitattributes
файл копируется на клон, и новые клоны будут по-прежнему избегать упаковки распаковываемых файлов, так что это лучший подход.
(Если вам захочется углубиться в детали, вы найдете некоторые в технической документации Git. Это не обсуждает точно, каковы размеры окон, но это связано с тем, сколько памяти Git использует для отображения данных объекта карты памяти, когда выбор объектов, которые могут хорошо сжиматься друг против друга. Их два: по одному для каждого отдельного mmap в одном файле пакета и один для общего агрегированного mmap во всех файлах пакета. Не упоминается в вашей ссылке: core.deltaBaseCacheLimit
, то есть, сколько памяти будет использовано для хранения дельта-баз, но чтобы понять это, вам нужно получить дельта-сжатие и дельта-цепочки, 1 и прочитать ту же техническую документацию. Обратите внимание, что Git по умолчанию не будет пытаться упаковать любой файловый объект, размер которого превышает core.bigFileThreshold
, Различные pack.*
элементы управления немного сложнее: упаковка выполняется многопоточным, чтобы по возможности использовать преимущества всех ваших процессоров, и каждый поток может использовать много памяти. Ограничение количества потоков ограничивает общее использование памяти: если один поток будет использовать 256 МБ, 8 потоков могут использовать 8*256 = 2048 МБ или 2 ГБ. Растровые изображения в основном ускоряют выборку с загруженных серверов.)
1 Они не так сложны: дельта-цепочка возникает, когда один объект говорит "возьмите объект XYZ и примените эти изменения", а сам объект XYZ говорит "возьмите объект PreXYZ и примените эти изменения". Объект PreXYZ также может принимать другой объект и так далее. Дельта-база - это объект внизу этого списка.
Другие предложения для оптимальной упаковки или управления памятью приветствуются.
У Git 2.20 (Q4 2018) будет один: когда в хранилище слишком много пакетов (что не рекомендуется), поиск объекта в них потребует консультации со многими пакетами .idx
файлы; новый механизм, чтобы иметь один файл, который объединяет все эти .idx
файлы введены.
См. Коммит 6a22d52, коммит e9ab2ed, коммит 454ea2e, коммит 0bff526, коммит 29e2016, коммит fe86c3b, коммит c39b02a, коммит 2cf489a, коммит 6d68e6a (20 августа 2018 г.) от Derrick Stolee ( derrickstolee
)
(Объединено Юнио С Хамано - gitster
- в коммите 49f210f, 17 сентября 2018 г.)
pack-objects
: рассмотреть пакеты в multi-pack-indexПри запуске 'git pack-objects --local' мы хотим избежать упаковки объектов, находящихся в альтернативе.
В настоящее время мы проверяем эти объекты, используя список pack_git_mru, который исключает файлы пакета, охватываемые индексом нескольких пакетов.
Есть новая настройка:
core.multiPackIndex::
Используйте файл индекса нескольких пакетов для отслеживания нескольких файлов пакетов с использованием одного индекса.
И этот индекс нескольких пакетов объясняется здесь и в Documentation/technical/multi-pack-index.txt
:
Multi-Pack-Index (MIDX) Примечания к дизайну
Каталог объектов Git содержит
pack
'каталог, содержащий:
- упаковочные файлы (с суффиксом "
.pack
") а также - pack-indexes (с суффиксом "
.idx
").
Индексы пакетов предоставляют способ поиска объектов и перехода к их смещению в пакете, но они должны идти в паре с пакетными файлами.
Такое сопряжение зависит от имен файлов, так как индекс пакета отличается только суффиксом с файлом пакета.Хотя индексы пакетов обеспечивают быстрый поиск по каждому пакетному файлу, эта производительность снижается по мере увеличения количества пакетных файлов, потому что сокращения должны проверять каждый пакетный файл, и мы с большей вероятностью можем пропустить наш последний использованный пакетный файл.
Для некоторых больших репозиториев перепаковка в один файл пакета невозможна из-за дискового пространства или чрезмерного времени перепаковки.
Multi-pack-index (MIDX для краткости) хранит список объектов и их смещений в нескольких пакетных файлах.
Это содержит:
- Список имен упаковочных файлов.
- Сортированный список идентификаторов объектов.
- Список метаданных для идентификатора i-го объекта, включая:
- Значение j, ссылающееся на j-й файл пакета.
- Смещение в j-ом файле пакета для объекта.
- Если требуются большие смещения, мы используем другой список больших смещений, аналогичный индексам пакетов версии 2.
Таким образом, мы можем предоставить
O(log N)
время поиска любого количества упаковочных файлов.
Что касается MIDX ("Multi-Pack-Index", представленный здесь ), обязательно используйте Git 2.36+:
Ошибка, приводившая к рассинхронизации растрового изображения с несколькими пакетами и порядком объектов, из-за чего
.midx
данные повреждены, исправлено в Git 2.36 (второй квартал 2022 г.).
См. коммит f8b60cf , , коммит a80f0f9 , коммит 791170f , коммит f0ed59a , коммит 90a8ea4 , коммит 09a7799 , коммит 95e8383 , коммит 61fd31a (25 января 2022 г.) Тейлора Блау (
ttaylorr
) .
(Объединено Junio C Hamano --
gitster
-- в коммите f2cb46a , 16 февраля 2022 г.)
коммит 7f514b7
midx
: прочитать фрагмент, если он присутствуетПодписал: Тейлор Блау.
Рецензировал: Деррик Столи.
Рецензировал: Джонатан Тан.
Когда MIDX содержит новый фрагмент, убедитесь, что обратный индекс считывается из него, а не из файла .rev на диске.
Поскольку нам нужно закодировать порядок объектов в самом MIDX по соображениям корректности, нет смысла снова хранить те же данные вне MIDX.Итак, этот патч перестает записывать отдельные файлы .rev и считывает их из самого MIDX.
Это можно сделать с относительно небольшим количеством нового кода, поскольку формат фрагмента RIDX идентичен данным в файле .rev.
Другими словами, мы можем реализовать это, указавrevindex_data
поле в фрагменте обратного индекса MIDX вместо файла .rev без каких-либо других изменений.
Примечание: [
RIDX
Documentation/technical/pack-format.txt
][7]
[Optional] Bitmap pack order (ID: {'R', 'I', 'D', 'X'})
Список позиций MIDX (по одной для каждого объекта в MIDX, всего num_objects, каждая из которых представляет собой 4-байтовое целое число без знака в сетевом порядке байтов), отсортированных в соответствии с их относительными позициями в растровых изображениях/псевдопакетах.
В дополнение к моему предыдущему ответу Git 2.34 (4 квартал 2021 г.) добавляет новую функцию.
Раньше файл растрового изображения достижимости создавался только для одного пакета, но теперь Git 2.34 научился генерировать растровые изображения для истории, которые охватывают несколько файлов пакетов.
См. Коммит 73cd7d9, коммит bfbb60d (09 сентября 2021 г.) и фиксацию eb6e956 , фиксацию d3f17e1 (31 августа 2021 г.) Джефф Кинг (
peff
) .
См совершать 2d59597 , совершать 9387fbd , совершают ff1e653 , совершают 4b58b6f , совершают e255a5e , совершают c51f5a6 , совершают b1b82d1 , совершают aeb4657 , совершают c528e17 , совершают 0f533c7 , совершают a5f9f24 , совершают 711260f , совершают 6b4277e , совершают ed18462 , совершают 9bb6c2e , , совершить 5d3cd09 , фиксация f5909d3 , фиксация 426c00e , совершить 73ff4ad (31 августа 2021 г.), зафиксировать f57a739 (1 сентября 2021 г.) и зафиксировать 917a54c , зафиксировать 1d7f7f2 , зафиксировать 3ba3d06 , зафиксировать fa95666 (24 августа 2021 г.) Тейлор Блау (
ttaylorr
) .
(Слияние Junio C Hamano -
gitster
- в коммите 0649303 , 20 сен 2021)
совершают 177c0d6: сделать вывод о предпочтительном пакете, если ему не дали
Подписано: Тейлор Блау
В 9218c6a ("
midx
: разрешить пометить пакет как предпочтительный ", 2021-03-30, Git v2.32.0-rc0 - merge ), индексный код для нескольких пакетов научился выбирать пакет, из которого выбираются все повторяющиеся объекты.
То есть, если объект появляется в нескольких пакетах, выберите копию в предпочтительном пакете, прежде чем разрывать связи, в соответствии с другими правилами, такими как pack mtime и readdir () order.Не указание предпочтительного пакета может вызвать серьезные проблемы с растровыми изображениями достижимости нескольких пакетов, поскольку эти растровые изображения зависят от наличия по крайней мере одного пакета, из которого выбраны все дубликаты.
Отсутствие такого пакета вызывает проблемы с кодом в объектах пакета для повторного использования пакетов дословно (например, этот код предполагает, что дельта-объект в дословно отправленном фрагменте пакета будет иметь свой базовый объект, отправленный из того же пакета).Так почему же отметка предпочтительного набора не вызывает здесь проблем? Причина примерно следующая:
- Связи разрываются (при работе с повторяющимися объектами) путем сортировки по
midx_oid_compare()
, который сортирует объекты по OID, предпочтительности, времени упаковки и, наконец, идентификатору упаковки (подробнее об этом позже).- Псевдо-пакет-порядок (описанный в Documentation / Technical / pack-format.txt в разделе «обратные индексы с несколькими пакетами») вычисляется с помощью
midx_pack_order()
, и сортирует по идентификатору упаковки и смещению упаковки, причем в первую очередь сортируются предпочтительные упаковки.- Но! Идентификаторы пакетов происходят от увеличения количества пакетов в
add_pack_to_midx()
, который является обратным вызовомfor_each_file_in_pack_dir()
, что означает, что идентификаторы пакетов назначаются в порядке readdir ().При указании предпочтительного пакета все это работает нормально, потому что повторяющиеся объекты правильно разрешаются в пользу копии в предпочтительном пакете, а предпочтительный пакет сортируется первым в порядке объектов.
«Сортировка в первую очередь» имеет решающее значение, потому что код растрового изображения полагается на определение того, какой пакет содержит первый объект в псевдопакете MIDX, чтобы определить, какой пакет является предпочтительным.
Но если мы не указали предпочтительный пакет, и пакет, который идет первым в порядке readdir (), также не имеет самой низкой отметки времени, тогда возможно, что этот пакет (тот, который сортируется первым в порядке псевдопакета, который растровый код будет рассматривать в качестве предпочтительных один) ничего не имеет все повторяющиеся объекты решены в его пользу, в результате поломки.
Исправление простое: выберите (полупроизвольный, непустой) предпочтительный пакет, если он не указан.
Это заставляет эту упаковку иметь дубликаты, разрешенные в ее пользу, и (что особенно важно) сортировать сначала в псевдопакетном порядке.
К сожалению, тестирование этого поведения на переносимость невозможно, поскольку оно зависит от порядка readdir (), который не гарантируется POSIX.(Обратите внимание, что растровые изображения достижимости с несколькими пакетами еще не реализованы; в этом смысле этот патч исправляет ошибку, которая еще не существует.
Но, имея этот патч заранее, мы можем предотвратить появление ошибки.)