Packfiles и GC
Тема дорожной карты · Изучи Git
Git хранит каждый объект как отдельный «loose»-файл в директории .git/objects/xx/..., где xx — это первые два символа хэша SHA-1. Это позволяет быстро найти любой объект по его хэшу. Однако, чтобы уменьшить количество файлов и сэкономить место на диске, Git использует команду git gc (garbage collection), которая упаковывает эти отдельные объекты в бинарные файлы .pack с использованием дельта-компрессии. Этот процесс позволяет хранить только различия между похожими блобами, что значительно экономит место на диске.
Кроме того, git gc выполняет очистку ненужных объектов, которые больше не используются. Это происходит по истечении окна времени, заданного параметром gc.pruneExpire, который по умолчанию составляет 2 недели. Команда git gc также подрезает записи в reflog, чтобы избежать их бесконтрольного роста. Опция git gc --aggressive используется для более радикальной оптимизации, но она крайне редко применяется, так как современная версия Git автоматически выполняет сборку мусора по определенным порогам.
Для управления очень большими репозиториями можно использовать команды git repack -ad, которые создают новые упакованные файлы, а также использовать multi-pack индексы и частичные клонирования. Это позволяет эффективно управлять большими объемами данных, сохраняя при этом производительность и доступность информации.
Как это работает
Packfiles и GC: раскладка директории .git включает в себя поддиректории objects/, где хранятся блобы, деревья, коммиты и теги, а также упакованные в бинарные .pack файлы для повышения эффективности. Поддиректория refs/ содержит файлы с хэшами для head, tags и remotes. Файл HEAD указывает на текущий ref, а config файл содержит настройки репозитория. Директория hooks/ содержит скрипты для выполнения пред- и пост- комманд. Файл index представляет собой стадинг-арею в бинарном формате, а директория logs/ содержит записи reflog. Файл packed-refs содержит сжатые refs.
Plumbing-команды, такие как hash-object, cat-file, update-ref, write-tree, commit-tree, являются основными строительными блоками Git, из которых создаются более удобные porcelain-команды, такие как git add, git commit, и другие.
Когда применять
Учить внутренности Git стоит, когда вы начинаете разрабатывать свои собственные Git-тулзы, сталкиваетесь с экзотическими проблемами или просто интересуетесь. Прочтите главу cq 10 из книги Pro Git, чтобы получить полное представление о внутреннем устройстве Git. Также полезно попробовать реализовать команды git add и git commit через plumbing-команды, чтобы лучше понять их работу.
Типичные ошибки
Типичные ошибки при работе с packfiles и GC включают прямое редактирование файлов в директории .git/ без использования команд, таких как update-ref, что может привести к корректировке инвариантов репозитория и его коррупции. Также стоит избегать запуска неизвестных plumbing-команд из блогов, так как некоторые из них могут быть нестабильными или изменяться со временем. Путаница между porcelain и plumbing в скриптах также может привести к проблемам, так как формат вывода porcelain нестабилен и может меняться.