Компьютеры · Инструкция
git commit-graph: ускорение истории большого Git-репозитория
git commit-graph особенно полезен в репозиториях с длинной историей и большим количеством веток, где команды.
Короткий ответ
git commit-graph хранит предвычисленную информацию о графе коммитов. Как записать, проверить и обслуживать commit-graph, включая split и changed-paths.
Что хранит commit-graph и почему Git может работать быстрее
Файл commit-graph содержит структурированную информацию о коммитах и их связях, чтобы Git не извлекал одни и те же данные заново из object database при каждом обходе истории. Он может хранить generation data и, при соответствующей записи, дополнительную информацию для changed-path Bloom filters. Практический эффект зависит от команды и структуры репозитория: ускорение заметнее там, где много ancestry‑проверок, merge-base, log и операций, которым нужно быстро исключать большие части графа. Сам commit-graph не меняет SHA коммитов и не редактирует ветки. Поэтому его можно рассматривать как производный индекс: если файл удалить или пересоздать, исходная история останется прежней. Это делает настройку подходящей для безопасного performance‑тюнинга, но всё равно полезно проверять файл штатной командой `verify`.
Совет: Сначала измерьте медленную команду до и после. Commit-graph полезен как оптимизация конкретной нагрузки, а не как ритуальная настройка любого маленького репозитория.
Как создать и проверить commit-graph
- Убедитесь, что вы работаете в локальном репозитории и нет необычных механизмов, несовместимых с commit-graph. Документация Git отдельно оговаривает ограничения, например replace objects/grafts могут отключать чтение или запись графа.
- Запустите `git commit-graph write --reachable`. Команда построит граф по коммитам, достижимым из refs. Для репозитория с обычным набором веток это понятная отправная точка.
- Проверьте структуру командой `git commit-graph verify`. Ненулевой exit code следует считать поводом пересоздать граф и проверить object database, а не игнорировать в automation.
- Повторите медленные операции — например `git log`, `git merge-base` или внутренние команды вашего инструмента — и измерьте эффект на той же файловой системе и после сопоставимого прогрева кеша.
- Если репозиторий постоянно получает новые коммиты и полная перезапись становится дорогой, рассмотрите `git commit-graph write --reachable --split`. Split chain позволяет добавлять слои и периодически объединять их по стратегии Git.
Важно: Commit-graph является производным файлом. Если сомневаетесь в его состоянии, безопаснее пересоздать его штатной командой, чем редактировать бинарный файл вручную.
Какой режим записи выбрать
- write --reachable. Первичная простая настройка. Понятный полный граф достижимых коммитов
- write --reachable --split. Очень большой, постоянно растущий repo. Инкрементальная цепочка слоёв
- write --reachable --changed-paths. Нагрузки с path history. Добавляет Bloom filters для changed paths
- verify. Контроль целостности commit-graph. Не заменяет fsck, но проверяет сам граф
Что даёт --changed-paths и почему он не нужен автоматически всем
Опция `--changed-paths` просит Git вычислить и сохранить Bloom filters, которые помогают некоторым history queries быстрее определять, мог ли коммит затрагивать интересующий путь. Выигрыш зависит от запросов. Если команда постоянно делает log по конкретным каталогам в огромной монорепе, дополнительные данные могут окупиться. Если нагрузка почти не использует path filtering, вы получите более дорогую запись и дополнительный объём без заметного эффекта. Поэтому включать changed-paths лучше после измерения. После обновления Git также стоит учитывать, что формат и алгоритмы обслуживания развиваются, а старые графы можно пересоздать. Commit-graph — кеш/индекс, а не артефакт, который нужно переносить между машинами как часть исходников проекта.
Предупреждение: Не коммитьте файлы commit-graph в рабочее дерево проекта. Они относятся к внутреннему состоянию `.git` и конкретной object database.
Как обслуживать split commit-graph в активно растущем репозитории
Split commit-graph хранит цепочку файлов, чтобы при каждом небольшом fetch не пересчитывать гигантский монолит с нуля. Новые слои добавляются поверх базовых, а Git умеет объединять их по правилам размера. Это удобно на серверах, зеркалах и больших developer clones, где refs постоянно двигаются. Но большее количество слоёв не означает бесконечное накопление: обслуживание должно позволять Git периодически compact/merge цепочку. Если ваша организация уже использует `git maintenance`, проверьте, не управляет ли commit-graph автоматизация за вас; дублирующие cron‑задачи могут зря создавать I/O. В CI с одноразовыми shallow clones построение графа обычно не окупается — job завершится раньше, чем индекс даст пользу в повторных операциях. Оптимизируйте persistent repositories, где история действительно используется много раз.
Когда commit-graph имеет смысл
- Репозиторий большой по числу коммитов и веток, а не только по размеру бинарных файлов.
- Медленны операции по ancestry/history, а не checkout из-за медленного диска.
- Клон долгоживущий и commit-graph будет использоваться многократно.
- Есть базовое измерение времени до оптимизации.
- После записи `git commit-graph verify` проходит успешно.
- Для changed-paths есть реальные path-based запросы, которые можно сравнить до/после.
Ограничения: replace objects, shallow clones и ожидания от ускорения
Commit-graph не универсально ускоряет любую операцию Git. Он не сделает быстрее передачу данных из сети, не уменьшит размер LFS‑объектов и не исправит медленный antivirus scan по рабочему дереву. Документация также указывает особенности совместимости с replace objects и grafts: такие механизмы могут приводить к отключению commit-graph, потому что они меняют представление истории. Shallow repositories имеют собственные ограничения полноты графа. Если после записи вы не видите выигрыша, проверьте, действительно ли bottleneck связан с обходом commit ancestry. Иногда более сильный эффект даст `git maintenance`, multi-pack-index, обновление Git или исправление процесса, который запускает тысячи одинаковых команд. Commit-graph полезен именно как точечный индекс для графа коммитов, а не как общий «ускоритель Git». Для команд с историей по путям отдельно учитывайте версию changed-path Bloom filters. В актуальной документации Git параметр `commitGraph.changedPathsVersion` управляет тем, какие версии фильтров читаются и записываются; более новые варианты могут быть несовместимы со старыми Git в смешанной среде. Поэтому на shared workstations и build-агентах сначала проверьте версии клиентов, а уже потом принудительно меняйте формат. Если такой совместимости не требуется, обычно достаточно поведения по умолчанию и периодической штатной перезаписи графа.
Что учитывать
Файл commit-graph содержит структурированную информацию о коммитах и их связях, чтобы Git не извлекал одни и те же данные заново из object database при каждом обходе истории. Он может хранить generation data и, при соответствующей записи, дополнительную информацию для changed-path Bloom filters. Практический эффект зависит от команды и структуры репозитория: ускорение заметнее там, где много ancestry‑проверок, merge-base, log и операций, которым нужно быстро исключать большие части графа. Сам…
Источники и проверка
Фактическая часть сверена по первичным источникам (в т.ч. git-commit-graph Documentation). Пример и формулировки — редакция N1RO на 2026-09-21.