linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it works
  • Уроки
  • База знаний
  • Собеседование
home/git/kb/Объектная модель/packfile

kb/objects ── Объектная модель ── advanced

Packfile

Сжатый файл в `.git/objects/pack/`, в который Git упаковывает множество loose-объектов, чтобы экономить место и ускорять сетевые операции. Использует дельта-компрессию между похожими объектами.

view as markdownaka: pack, git-packfile

Когда объект только появился (от git add, git commit), он лежит отдельным файлом - loose object: .git/objects/8d/0e41.... Удобно для записи, неудобно для хранения миллионов файлов. Поэтому Git периодически сжимает их в packfiles.

Что внутри packfile

В .git/objects/pack/ появляются пары файлов:

pack-abc123def456.pack    # сжатые объекты
pack-abc123def456.idx     # индекс по SHA для быстрого поиска

Внутри .pack:

  • объекты упакованы один за другим, каждый в zlib-сжатом виде;
  • между похожими объектами вычисляется дельта - хранится только разница относительно базы;
  • всё это дополнительно сжато на уровне потока.

Дельта-компрессия

Главная экономия в Git происходит здесь. Допустим, есть две версии большого файла, отличающиеся на пять строк. В loose-формате это два blob'а, каждый занимает почти полный размер файла. В packfile одна версия лежит целиком, вторая - как «возьми вот ту, примени следующие правки».

Алгоритм похож на xdelta/bsdiff. Git подбирает базу не по имени файла, а по эвристике: пытается найти похожий объект схожего типа и размера. Поэтому могут быть дельты между двумя совершенно разными файлами, если они случайно похожи.

Когда packfiles создаются

  • При git gc (manual или auto).
  • При git push/fetch - стороны обмениваются объектами в packfile- формате, а не по одному.
    • При git clone - сервер сразу отдаёт всё содержимое в packfile.

Авто-gc срабатывает при превышении порогов:

  • больше 6700 loose-объектов;
  • больше 50 packfile'ов.

Эти пороги настраиваются: gc.auto, gc.autoPackLimit.

Чтение объектов из packfile

Команды Git работают одинаково независимо от того, где лежит объект - в loose-формате или в packfile. git cat-file -p <sha> найдёт объект в любой форме.

Просмотр содержимого pack'а руками:

bash
git verify-pack -v .git/objects/pack/pack-abc.idx
# SHA  type  size  packfile-offset  base-SHA?

Видно, какие объекты - base, какие - дельта, и от кого они зависят.

Подводные камни

  • Дельта не значит, что Git «диффы хранит». Логически модель данных остаётся snapshot-based (commit держит tree, а не diff). Дельта - это уровень физического хранения.
  • При очень большом packfile отдельный read может быть медленным: Git распаковывает цепочку дельт. Поэтому есть лимит pack.deltaCacheSize.
  • git gc --aggressive пересчитывает дельты с нуля, выбирая лучшие базы. Долго, но даёт меньший размер. Стоит делать раз в несколько месяцев на больших проектах.

§ команды

bash
git gc

Собрать loose-объекты в packfile, удалить недостижимое

bash
git verify-pack -v <pack.idx>

Распечатать содержимое packfile с типами и размерами

bash
git count-objects -v

Показать сколько loose-объектов и packfile'ов в репозитории

§ см. также

  • blobBlobОбъект Git, который хранит содержимое одного файла. Только байты, без имени, прав и даты. Имя файла лежит в `tree`, не в blob.
  • treeTreeОбъект Git, который хранит список того, что лежит в одной директории: записи `(права, тип, SHA, имя)`. Рекурсивно ссылается на другие tree для поддиректорий.
  • commitCommitОбъект Git: снимок состояния всего проекта (через tree) плюс метаданные - автор, коммиттер, дата, родители, сообщение. SHA коммита включает SHA родителя, что делает историю криптографически связанной.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки