Git 2.55 для великих репозиторіїв: як пошаровий MIDX полегшує обслуговування

GitDevOpsCI

Практичний план перевірки Git 2.55 для команд, у яких великий репозиторій сповільнює checkout, fetch або регулярне обслуговування в CI

Коли проблема не в коді, а в історії репозиторію

Команда вже прискорила тести, кешує залежності й прибрала зайві кроки зі збірки, але CI все одно починає день із кількох повільних Git-операцій. fetch тягнеться довше, checkout інколи виглядає як окрема задача, а нічний maintenance з’їдає час сервера. У таких випадках причина часто не в новому коді, а в тому, як роками накопичувалась історія репозиторію.

Git 2.55 цікавий саме для таких великих проєктів. У релізі з’явилась можливість запускати git repack --write-midx=incremental, а також поєднувати її з --geometric=2 -d. Це не чарівна кнопка для кожного репозиторію, але корисний інструмент для команд, які вже бачать вартість зберігання історії: багато packfiles, довгі службові операції, важкі дзеркала, повільні сервери CI.

Коротка карта сховища Git

Щоб зрозуміти цю зміну, варто уявити .git/objects не як темну службову папку, а як архів. Спочатку Git object можуть лежати окремо, але з часом Git складає їх у packfile. Це економить місце і прискорює читання, бо замість тисяч дрібних файлів з’являються більші впорядковані блоки.

Поруч із packfile Git тримає індекси, щоб швидко знайти потрібний object. Коли packfiles багато, з’являється інша задача: Git має швидко зрозуміти, у якому саме packfile лежить потрібний запис. Для цього існує MIDX, тобто multi-pack-index. Це службовий індекс, який дає один шар пошуку поверх кількох packfiles і зменшує зайву роботу під час читання.

Класичний MIDX простий для читання, але має неприємну ціну для великих репозиторіїв: якщо індекс описує дуже багато packfiles, навіть невелике оновлення може вимагати великого переписування metadata. Саме це болить у регулярному maintenance, де команда не хоче щоразу чіпати весь архів заради кількох нових блоків.

Що додає пошаровий MIDX у Git 2.55

Пошаровий MIDX зберігає індекс не одним великим файлом, а ланцюжком шарів. Старі шари можуть лишатися на місці, а новий шар додається зверху для нових packfiles. Ідея проста: якщо репозиторій щодня отримує нові коміти, Git не обов’язково має щоразу переписувати індекс для всього object store.

У Git 2.55 команда git repack навчилась писати такі пошарові MIDX напряму:

git repack --write-midx=incremental

Для реального maintenance важлива друга частина: ланцюжок шарів не повинен рости безмежно. Тому Git 2.55 підтримує поєднання пошарового MIDX із geometric repacking:

git repack --write-midx=incremental --geometric=2 -d

Практичний сенс такий: нові, менші шари можна переписувати частіше, а старі, більші шари не треба чіпати при кожному запуску. GitHub Blog описує це як компроміс між одним великим MIDX, який зручно читати, але дорого оновлювати, і нескінченним ланцюжком дрібних шарів, який легко дописувати, але складніше підтримувати.

Лабораторний тест на копії

Починати треба не з глобальної зміни CI, а з окремої копії великого репозиторію. Мінімальна перевірка виглядає так:

git --version
du -sh .git/objects
find .git/objects/pack -name '*.pack' | wc -l
time git fetch --all --prune

Якщо у вас уже є maintenance-команда, заміряйте і її. Наприклад, скільки триває поточний git gc, git repack або git maintenance run. Після цього на тестовій копії можна запускати новий режим:

time git repack --write-midx=incremental --geometric=2 -d

Після запуску повторіть ті самі вимірювання. Важливо дивитися не лише на один переможний запуск, а на поведінку після кількох циклів: додали нові object, зробили fetch, запустили maintenance ще раз, порівняли час і кількість packfiles. Якщо перший запуск довгий, а наступні стають помітно дешевшими, це вже корисний сигнал. Якщо різниці немає, можливо, ваш репозиторій замалий або проблема лежить в іншому місці: мережі, кеші залежностей, розмірі робочого дерева чи налаштуваннях CI.

Поступове впровадження без героїзму

Хороше поступове впровадження для такої зміни нудне. Спершу один тестовий сервер CI або дзеркало. Потім один некритичний репозиторій з великою історією. Потім порівняння метрик за кілька днів. Лише після цього варто думати про ширше впровадження.

У плані відкату має бути зрозуміло, як повернути попередній maintenance-процес. Перед експериментом збережіть поточні команди, версію Git, розклад job і базові метрики. Якщо команда використовує спільні кеші або дзеркала, не міняйте їх без резервної копії: помилка в службовому сховищі Git може зупинити не один build, а всю чергу CI.

Також не робіть висновків на маленькому репозиторії. Пошаровий MIDX створений для ситуацій, де кількість object і packfiles уже стала помітною операційною вартістю. На невеликому проєкті новий режим може просто не показати різниці, і це нормально.

Антипатерни

Перший антипатерн — запускати новий repack на production-дзеркалі без копії. Навіть якщо команда офіційна, maintenance змінює службову структуру репозиторію, а не тільки красиву статистику.

Другий — міряти тільки розмір .git після одного запуску. Для цієї теми важливі час регулярного maintenance, кількість packfiles, повторюваність результату і вплив на fetch або checkout.

Третій — вмикати зміну для всіх репозиторіїв однаково. Великий монорепозиторій і невеликий сервіс мають різні проблеми. Для одного пошаровий MIDX може зменшити вартість обслуговування, для іншого це буде зайва складність без помітної користі.

Висновок

Git 2.55 не скасовує потребу в нормальній дисципліні репозиторію, але дає platform-командам ще один практичний важіль. Якщо великий репозиторій уже витрачає хвилини на Git-операції, перевірте пошаровий MIDX у лабораторному режимі, зберіть метрики й впроваджуйте зміну малими кроками. Найкращий результат тут не гучний реліз, а спокійний CI, який перестає платити зайву ціну за багаторічну історію.

Джерела

Короткий чеклист

  • Перевірити, що тестовий сервер має Git 2.55 або новіший.
  • Зробити копію великого репозиторію або використати окреме дзеркало.
  • Заміряти час `fetch`, `checkout` і maintenance до зміни.
  • Запустити `git repack --write-midx=incremental --geometric=2 -d` тільки на тестовій копії.
  • Порівняти кількість packfiles, розмір `.git/objects` і час повторного maintenance.
  • Погодити поступове впровадження лише після вимірювань і плану відкату.

Prompt Pack: план безпечної перевірки пошарового MIDX

Ти допомагаєш команді перевірити Git 2.55 і пошаровий MIDX на великому репозиторії. Вхідні дані, які я надам: - поточна версія Git на робочих машинах і серверах CI; - тип репозиторію: монорепозиторій, багато підмодулів або звичайний великий репозиторій; - приблизний розмір `.git/objects`, кількість packfiles і середній час `fetch`, `checkout`, maintenance; - чи є дзеркальна копія або тестовий сервер CI; - які команди зараз запускаються для `git gc`, `git repack` або `git maintenance`. Підготуй відповідь у такому форматі: 1. Короткий висновок: чи варто тестувати пошаровий MIDX саме тут. 2. План лабораторної перевірки на копії репозиторію. 3. Команди для збору метрик до і після тесту. 4. Ризики та умови відкату. 5. Рішення для поступового впровадження: "не впроваджувати", "пілот на одному сервері CI", або "розширювати поступово". Не пропонуй змін для всіх розробників одразу без тесту й резервної копії.