git-pack-objects
Имя
git-pack-objects — создание упакованного архива объектов
Краткое описание
git pack-objects [-q | --progress | --all-progress] [--all-progress-implied]
[--no-reuse-delta] [--delta-base-offset] [--non-empty]
[--local] [--incremental] [--window=<n>] [--depth=<n>]
[--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
[--cruft] [--cruft-expiration=<time>]
[--stdout [--filter=<filter-spec>] | <base-name>]
[--shallow] [--keep-true-parents] [--[no-]sparse]
[--name-hash-version=<n>] [--path-walk] < <object-list> Описание
Читает список объектов из стандартного ввода и записывает на диск один или несколько упакованных архивов с указанным базовым именем либо упакованный архив в стандартный вывод.
Упакованный архив — эффективный способ передачи набора объектов между двумя репозиториями, а также формат архивирования с быстрым доступом. В упакованном архиве объект хранится либо целиком в сжатом виде, либо как разница относительно другого объекта. Последний вариант часто называют дельтой.
Формат упакованного архива (.pack) разработан как автономный, чтобы его можно было распаковать без дополнительной информации. Поэтому каждый объект, от которого зависит дельта, должен присутствовать в пакете.
Для быстрого произвольного доступа к объектам в пакете создается файл индекса пакета (.idx). Размещение и индексного файла (.idx), и упакованного архива (.pack) в подкаталоге pack/ каталога $GIT_OBJECT_DIRECTORY (или любого из каталогов в $GIT_ALTERNATE_OBJECT_DIRECTORIES) позволяет Git читать архив пакета.
Команда git unpack-objects может прочитать упакованный архив и развернуть содержащиеся в пакете объекты в формат «один файл — один объект»; обычно это делают команды интеллектуальной выборки, когда для эффективной передачи по сети их узлы создают пакет на лету.
Параметры
- base-name
-
Записывает пары файлов (.pack и .idx), используя <base-name> для определения имени создаваемого файла. При использовании этого параметра два файла пары записываются в файлы <base-name>-<SHA-1>.{pack,idx}. <SHA-1> — это хеш, вычисленный на основе содержимого пакета; он выводится в стандартный поток вывода команды.
- --stdout
-
Записывает содержимое пакета (то, что было бы записано в файл .pack) в стандартный поток вывода.
- --revs
-
Читает аргументы ревизий из стандартного ввода вместо отдельных имен объектов. Аргументы ревизий обрабатываются так же, как в
git rev-list: флаг--objectsиспользует аргументыcommitдля формирования списка выводимых объектов. Объекты из полученного списка упаковываются. Помимо ревизий, также принимаются строки--notили--shallow<SHA-1>. - --unpacked
-
Подразумевает
--revs. При обработке списка аргументов ревизий, прочитанного из стандартного ввода, ограничивает набор упаковываемых объектов теми, которые еще не упакованы. - --all
-
Подразумевает
--revs. Помимо списка аргументов ревизий, прочитанного из стандартного ввода, рассматривает все ссылки вrefs/как включенные в список. - --include-tag
-
Включает не запрошенные аннотированные теги, если объект, на который они ссылаются, включен в результирующий файл пакета. Это может быть полезно для передачи новых тегов клиентам Git.
- --stdin-packs[=<mode>]
-
Читает из стандартного ввода базовые имена файлов пакетов (например,
pack-1234abcd.pack) вместо имен объектов или аргументов ревизий. Результирующий пакет содержит все объекты, перечисленные во включенных пакетах (не начинающихся с^), за исключением объектов, перечисленных в исключенных пакетах (начинающихся с^).Если
modeимеет значение "follow", перед именами пакетов может дополнительно указываться!, обозначая, что эти пакеты исключены, но не обязательно замкнуты относительно достижимости. Помимо объектов из включенных пакетов, результирующий пакет может содержать дополнительные объекты в следующих случаях:-
Если некоторые пакеты помечены как
!, будут включены объекты, достижимые из таких пакетов или включенных пакетов через объекты, находящиеся вне исключенных замкнутых пакетов. В этом случае все пакеты^считаются замкнутыми относительно достижимости. -
В противном случае (если пакетов
!нет) объекты из неуказанных пакетов будут включены, если они (1) достижимы из включенных пакетов и (2) не найдены ни в одном из исключенных пакетов.
Этот режим полезен, например, для восстановления ранее недостижимых объектов из cruft-пакетов и создания пакетов, замкнутых относительно достижимости вплоть до границы, заданной исключенными пакетами.
Несовместим с
--revsи параметрами, подразумевающими--revs(например,--all), за исключением совместимого параметра--unpacked. -
- --cruft
-
Упаковывает недостижимые объекты в отдельный пакет "cruft", обозначаемый наличием файла
.mtimes. Обычно используется командойgitrepack--cruft. Вызывающая команда передает список имен пакетов и указывает, какие пакеты останутся в репозитории, а какие будут удалены (такие пакеты отмечаются префиксом-). В cruft-пакет входят все объекты, отсутствующие в сохраняемых пакетах и не вышедшие за пределы льготного периода (см. ниже--cruft-expiration), а также объекты, вышедшие за пределы льготного периода, но достижимые из другого объекта, который еще не вышел за его пределы.Если во входных данных указан пакет, содержащий все достижимые объекты, а все остальные пакеты помечены для удаления, соответствующий cruft-пакет будет содержать все недостижимые объекты (с mtime новее
--cruft-expiration), а также недостижимые объекты с mtime старше--cruft-expiration, если они достижимы из недостижимого объекта с mtime новее--cruft-expiration).Несовместим с
--unpack-unreachable,--keep-unreachable,--pack-loose-unreachable,--stdin-packs, а также с любыми другими параметрами, подразумевающими--revs. - --cruft-expiration=<approxidate>
-
Если указан, объекты удаляются из cruft-пакета, если их mtime старше <approxidate>. Если параметр не указан (и задан
--cruft), объекты не удаляются. - --window=<n>
- --depth=<n>
-
Эти два параметра влияют на способ хранения объектов в пакете с использованием дельта-сжатия. Сначала объекты сортируются внутри программы по типу, размеру и, при необходимости, именам; затем каждый объект сравнивается с другими объектами в пределах --window, чтобы определить, позволит ли дельта-сжатие сэкономить место. Параметр --depth ограничивает максимальную глубину дельты; слишком большая глубина снижает производительность распаковки, поскольку данные дельт приходится применять указанное количество раз, чтобы получить нужный объект.
Значение --window по умолчанию равно 10, а --depth — 50. Максимальная глубина — 4095.
- --window-memory=<n>
-
Этот параметр задает дополнительное ограничение сверх
--window; размер окна будет динамически уменьшаться, чтобы потребление памяти не превышало<n>байт. Это полезно в репозиториях, содержащих объекты разных размеров: большой размер окна не приведет к нехватке памяти, а для небольших объектов при этом можно будет использовать преимущества большого окна. К размеру можно добавить суффикс "k", "m" или "g". Значение--window-memory=0снимает ограничение на потребление памяти. По умолчанию используется значение переменной конфигурацииpack.windowMemory. - --max-pack-size=<n>
-
В исключительных случаях файловая система может не поддерживать создание файлов больше определенного размера. Этот параметр позволяет указать команде разбить результирующий файл пакета на несколько независимых файлов, каждый из которых не превышает заданный размер. К размеру можно добавить суффикс "k", "m" или "g". Минимально допустимый размер — 1 МиБ. По умолчанию ограничение отсутствует, если только не задана переменная конфигурации
pack.packSizeLimit. Обратите внимание: этот параметр может привести к увеличению размера репозитория и снижению его производительности; см. обсуждение вpack.packSizeLimit. - --honor-pack-keep
-
Этот флаг приводит к тому, что объект, уже находящийся в локальном пакете с файлом .keep, игнорируется, даже если в противном случае он был бы упакован.
- --keep-pack=<pack-name>
-
Этот флаг приводит к тому, что объект, уже находящийся в указанном пакете, игнорируется, даже если в противном случае он был бы упакован. <pack-name> — это имя файла пакета без начального каталога (например,
pack-123.pack). Этот параметр можно указать несколько раз, чтобы сохранить несколько пакетов. - --incremental
-
Этот флаг приводит к тому, что объект, уже находящийся в пакете, игнорируется, даже если в противном случае он был бы упакован.
- --local
-
Этот флаг приводит к тому, что объект, заимствованный из альтернативного хранилища объектов, игнорируется, даже если в противном случае он был бы упакован.
- --non-empty
-
Создает упакованный архив, только если в нем будет хотя бы один объект.
- --progress
-
По умолчанию ход выполнения отображается в стандартном потоке ошибок, если он подключен к терминалу, кроме случаев, когда указан -q. Этот флаг принудительно включает отображение хода выполнения, даже если стандартный поток ошибок не направлен в терминал.
- --all-progress
-
Если указан --stdout, отчет о ходе выполнения отображается во время подсчета и сжатия объектов, но не во время записи. Это сделано потому, что в некоторых случаях поток вывода напрямую связан с другой командой, которая может захотеть отображать собственный ход обработки поступающих данных пакета. Этот флаг действует как --progress, но также принудительно включает отчет о ходе выполнения на этапе записи, даже если используется --stdout.
- --all-progress-implied
-
Этот параметр подразумевает --all-progress при включении отображения хода выполнения. В отличие от --all-progress, сам по себе этот флаг не включает отображение хода выполнения.
- -q
-
Этот флаг запрещает команде отображать ход выполнения в стандартном потоке ошибок.
- --no-reuse-delta
-
При создании упакованного архива в репозитории с уже существующими пакетами команда повторно использует существующие дельты. Иногда это приводит к созданию немного неоптимального пакета. Этот флаг запрещает повторное использование существующих дельт и предписывает вычислять их заново.
- --no-reuse-object
-
Этот флаг запрещает повторное использование любых существующих данных объектов, в том числе объектов без дельта-сжатия, и принудительно сжимает все заново. Подразумевает --no-reuse-delta. Полезен только в редком случае, когда требуется применить другой уровень сжатия ко всем упакованным данным.
- --compression=<n>
-
Задает уровень сжатия для новых сжимаемых данных в создаваемом пакете. Если параметр не указан, уровень сжатия пакета определяется сначала значением pack.compression, затем core.compression, а если ни одно из них не задано, используется значение по умолчанию -1 (значение по умолчанию для zlib). Добавьте --no-reuse-object, если хотите задать единый уровень сжатия для всех данных независимо от их источника.
- --sparse
- --no-sparse
-
Включает или выключает алгоритм "sparse", определяющий, какие объекты включать в пакет, при использовании вместе с параметром "--revs". Этот алгоритм обходит только деревья, присутствующие в путях, добавляющих новые объекты. Это может значительно повысить производительность при вычислении пакета для передачи небольшого изменения. Однако если включенные коммиты содержат некоторые типы прямых переименований, в файл пакета могут попасть лишние объекты. Если этот параметр не указан, используется значение
pack.useSparse, равное true, если не задано иное. - --thin
-
Создает "тонкий" пакет, исключая общие для отправителя и получателя объекты, чтобы уменьшить объем передаваемых по сети данных. Этот параметр имеет смысл только вместе с --stdout.
Примечание: тонкий пакет нарушает формат упакованного архива, поскольку в нем отсутствуют обязательные объекты, и поэтому Git не может использовать его, пока он не станет автономным. Используйте
gitindex-pack--fix-thin(см. git-index-pack[1]), чтобы восстановить автономность. - --shallow
-
Оптимизирует пакет, предназначенный для клиента с неглубоким репозиторием. Этот параметр в сочетании с --thin позволяет уменьшить размер пакета за счет скорости.
- --delta-base-offset
-
Упакованный архив может указывать базовый объект дельты либо его 20-байтовым именем, либо смещением в потоке, но старые версии Git не понимают второй вариант. По умолчанию
git pack-objectsиспользует только первый формат для лучшей совместимости. Этот параметр позволяет команде использовать второй формат для компактности. В зависимости от средней длины цепочки дельт этот параметр обычно уменьшает размер результирующего файла пакета на 3–5 процентов.Примечание: команды верхнего уровня, такие как
gitgc(см. git-gc[1]) иgitrepack(см. git-repack[1]), по умолчанию передают этот параметр в современных версиях Git при упаковке объектов репозитория. То же относится к командеgitbundle(см. git-bundle[1]) при создании связки. - --threads=<n>
-
Задает число потоков, создаваемых при поиске наилучших совпадений дельт. Для работы этого параметра pack-objects должен быть собран с поддержкой pthreads; в противном случае параметр игнорируется с предупреждением. Он предназначен для сокращения времени упаковки на многопроцессорных компьютерах. Однако объем памяти, необходимый для окна поиска дельт, умножается на число потоков. Значение 0 заставляет Git автоматически определить число процессоров и соответственно задать количество потоков.
- --index-version=<version>[,<offset>]
-
Предназначен только для использования тестовым набором. Позволяет принудительно задать версию создаваемого индекса пакета, а также использовать 64-битные записи индекса для объектов, расположенных выше заданного смещения.
- --keep-true-parents
-
При использовании этого параметра родители, скрытые с помощью grafts, все равно упаковываются.
- --filter=<filter-spec>
-
Исключает некоторые объекты (обычно блобы) из результирующего файла пакета. Допустимые формы <filter-spec> см. в git-rev-list[1].
- --no-filter
-
Отключает все ранее заданные аргументы
--filter=. - --missing=<missing-action>
-
Отладочный параметр, предназначенный для помощи в дальнейшей разработке "частичного клонирования". Определяет, как обрабатывать отсутствующие объекты.
Форма
--missing=errorтребует остановить pack-objects с ошибкой при обнаружении отсутствующего объекта. Если репозиторий является частичным клоном, перед тем как объявить объект отсутствующим, будет предпринята попытка загрузить его. Это действие используется по умолчанию.Форма
--missing=allow-anyпозволяет продолжить обход объектов при обнаружении отсутствующего объекта. Загрузка отсутствующего объекта не выполняется. Отсутствующие объекты молча исключаются из результатов.Форма
--missing=allow-promisorдействует какallow-any, но позволяет продолжить обход объектов только для ОЖИДАЕМЫХ отсутствующих объектов promisor. Загрузка отсутствующего объекта не выполняется. При обнаружении неожиданно отсутствующего объекта возникает ошибка. - --exclude-promisor-objects
-
Исключает объекты, которые, как известно, находятся на удаленном сервере promisor. (Этот параметр предназначен для обработки только объектов, созданных локально, чтобы при повторной упаковке сохранялось различие между локально созданными объектами [без .promisor] и объектами с удаленного сервера promisor [с .promisor].) Используется при частичном клонировании.
- --keep-unreachable
-
Недостижимые объекты из пакетов, указанных с помощью параметра --unpacked=, добавляются в результирующий пакет вместе с достижимыми объектами, отсутствующими в пакетах, помеченных файлами *.keep. Подразумевает
--revs. - --pack-loose-unreachable
-
Упаковывает недостижимые отдельные объекты (а их отдельные копии удаляет). Подразумевает
--revs. - --unpack-unreachable
-
Оставляет недостижимые объекты в отдельном виде. Подразумевает
--revs. - --delta-islands
-
Ограничивает сопоставление дельт на основе «островов». См. раздел «ДЕЛЬТА-ОСТРОВА» ниже.
- --name-hash-version=<n>
-
При дельта-сжатии Git группирует потенциально похожие объекты, используя эвристики, основанные на пути к объекту. Группировка объектов по точному совпадению пути подходит для путей с множеством версий, однако поиск пар дельт по разным полным путям также имеет свои преимущества. Git собирает объекты сначала по типу, затем по «хешу имени» пути и после этого по размеру, стремясь сгруппировать объекты, которые хорошо сжимаются вместе.
По умолчанию используется версия хеша имени
1, которая обеспечивает локальность хеша, придавая наибольший вес последним байтам пути. Эта версия хорошо различает короткие пути и находит переименования между каталогами. Однако функция хеширования в основном зависит от последних 16 байт пути. Если в репозитории много путей с одинаковыми последними 16 байтами, различающихся только родительским каталогом, хеш имени может привести к слишком большому числу коллизий и ухудшить результаты. В настоящее время эта версия обязательна при записи файлов битовых карт достижимости с помощью--write-bitmap-index.Версия хеша имени
2обладает свойствами локальности, схожими со свойствами версии1, но рассматривает каждый компонент пути отдельно и накладывает хеши друг на друга со сдвигом. При этом приоритет по-прежнему отдается последним байтам пути, но младшие биты хеша также «подмешивают» имена родительских каталогов. Этот метод сохраняет некоторые преимущества локальности версии1, устраняя при этом большинство коллизий, возникающих, когда файлы с одинаковыми именами находятся в разных каталогах. В настоящее время эта версия не допускается при записи файлов битовых карт достижимости с помощью--write-bitmap-index; она будет автоматически заменена на версию1. - --path-walk
-
Выполняет сжатие в два прохода: сначала упорядочивает объекты по путям, затем сжимает их между путями обычным способом. Это может улучшить дельта-сжатие, особенно если имена файлов приводят к коллизиям в используемом Git по умолчанию алгоритме хеширования имен.
Несовместим с
--delta-islands. При наличии--path-walkпараметр--use-bitmap-indexигнорируется. Параметр--path-walkподдерживает формы--filter=<spec>:blob:none,blob:limit=<n>,tree:0,object:type=<type> иsparse:<oid>. Эти поддерживаемые типы фильтров можно комбинировать, используя формуcombine:<spec>+<spec>.
Дельта-острова
При возможности pack-objects пытается повторно использовать существующие дельты на диске, чтобы не искать новые на лету. Это важная оптимизация при обслуживании запросов на выборку: серверу не нужно распаковывать большинство объектов, достаточно отправить байты напрямую с диска. Эта оптимизация не работает, если объект хранится как дельта относительно базового объекта, которого нет у получателя (и который мы не отправляем). В таком случае сервер «разрывает» дельту и должен найти новую, что требует значительных затрат процессорного времени. Поэтому для производительности важно, чтобы набор объектов в отношениях дельт на диске соответствовал объектам, которые клиент будет получать.
В обычном репозитории это, как правило, происходит автоматически. Большинство объектов достижимы из веток и тегов, а именно их получают клиенты. Любые найденные на сервере дельты, скорее всего, связывают объекты, которые есть или будут у клиента.
Однако в некоторых конфигурациях репозитория могут существовать несколько связанных, но отдельных групп вершин ссылок, которые клиенты обычно получают независимо друг от друга. Например, представьте, что вы храните несколько «ответвлений» репозитория в одном общем хранилище объектов и предоставляете клиентам доступ к ним как к отдельным репозиториям через GIT_NAMESPACE или к отдельным репозиториям с помощью механизма alternates. При наивной повторной упаковке может оказаться, что оптимальная дельта для объекта строится относительно базового объекта, присутствующего только в другом ответвлении. Но при получении данных у клиента не будет базового объекта, и нам придется искать новую дельту на лету.
Аналогичная ситуация может возникнуть, если у вас есть много ссылок за пределами refs/heads/ и refs/tags/, указывающих на связанные объекты (например, refs/pull или refs/changes, используемые некоторыми хостинг-провайдерами). По умолчанию клиенты получают только вершины и теги, поэтому дельты относительно объектов, присутствующих только в других группах, нельзя отправить без изменений.
Дельта-острова решают эту проблему, позволяя объединять ссылки в отдельные «острова». Pack-objects вычисляет, какие объекты достижимы из каких островов, и запрещает строить дельту от объекта A относительно базового объекта, отсутствующего хотя бы в одном из островов A. В результате пакеты немного увеличиваются (поскольку некоторые возможности построения дельт не используются), но гарантируется, что при получении одного острова не придется пересчитывать дельты на лету из-за пересечения границ островов.
При повторной упаковке с дельта-островами окно дельт обычно заполняется кандидатами, запрещенными конфигурацией. Повторная упаковка с большим значением --window помогает (и занимает меньше времени, чем могла бы, поскольку некоторые пары объектов можно отклонить по островам, не анализируя их содержимое).
Острова настраиваются параметром pack.island, который можно указывать несколько раз. Каждое значение — регулярное выражение с привязкой к началу, соответствующее именам ссылок. Например:
[pack] island = refs/heads/ island = refs/tags/
помещает вершины и теги в один остров (его имя — пустая строка; подробнее об именовании см. ниже). Все ссылки, не соответствующие этим регулярным выражениям (например, refs/pull/123), не относятся ни к одному острову. Поэтому любой объект, достижимый только из refs/pull/ (но не из вершин или тегов), не может использоваться в качестве базового объекта для refs/heads/.
Ссылки группируются по «именам» островов; два регулярных выражения, создающие одинаковое имя, считаются относящимися к одному острову. Имена формируются из регулярных выражений путем объединения всех групп захвата с разделением через - дефис. (Если групп захвата нет, имя будет пустой строкой, как в примере выше.) Это позволяет создавать произвольное количество островов. Однако поддерживается не более 14 таких групп захвата.
Например, предположим, что ссылки каждого ответвления хранятся в refs/virtual/ID, где ID — числовой идентификатор. Тогда можно настроить следующее:
[pack] island = refs/virtual/([0-9]+)/heads/ island = refs/virtual/([0-9]+)/tags/ island = refs/virtual/([0-9]+)/(pull)/
Так вершины и теги каждого ответвления попадут в отдельный остров (с именем вроде "1234"), а ссылки на запросы на включение для каждого ответвления — в собственный остров "1234-pull".
Обратите внимание: для каждого регулярного выражения выбирается только один остров по правилу «побеждает последний» (это позволяет конфигурации конкретного репозитория иметь приоритет над пользовательской конфигурацией и так далее).
Конфигурация
На упаковку влияют различные переменные конфигурации; см. git-config[1] (выполните поиск по словам "pack" и "delta").
Обратите внимание: дельта-сжатие не используется для объектов, размер которых превышает значение переменной конфигурации core.bigFileThreshold, а также для файлов, у которых атрибут delta установлен в false.
См. также
pack-objects
© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/git-pack-objects