Git gc: очистить репозиторий без потери данных

Категория: Git · Язык: Bash · Обновлено:

git gc упаковывает loose-объекты, удаляет недостижимые объекты старше grace period и обслуживает reflog. Обычный запуск безопасен: Git сохраняет возможность восстановить недавние коммиты. Опасность представляет --prune=now, который удаляет недостижимые объекты немедленно, не дожидаясь стандартного срока.

Запустить обычную сборку мусора

Bash
git gc
git count-objects -vH

count-objects показывает число loose-объектов, размер pack-файлов и garbage. После gc счётчик count обычно уменьшается, а size-pack отражает сжатые данные. Git запускает gc --auto сам после некоторых операций, поэтому ручной вызов нужен в основном для больших репозиториев или перед архивированием.

git gc не удаляет коммиты, на которые ссылаются ветки, теги, stash или reflog. Срок хранения настраивается через gc.reflogExpire (по умолчанию 90 дней) и gc.reflogExpireUnreachable (30 дней). Не отключайте reflog, если пользуетесь восстановлением через git reflog: после истечения записей пропадут и точки восстановления.

Удалить недостижимые объекты сразу

Bash
git fsck --unreachable
git reflog expire --expire=now --all
git gc --prune=now

Эта последовательность необратима: сначала проверьте список недостижимых объектов, затем очистите reflog и только потом запускайте prune. Не выполняйте её на общем или production-репозитории без резервной копии. Если нужно просто освободить место, начните с обычного git gc и проверки git count-objects -vH.

git gc --aggressive пересобирает pack с более дорогими настройками и почти никогда не нужен в повседневной работе. Для фонового обслуживания используйте git maintenance start: он планирует gc, commit-graph и prefetch без ручных запусков. Не запускайте gc одновременно с другой записью в репозиторий — Git использует блокировки, но длинная операция может задержать коллег.

Перед очисткой убедитесь, что нет незакоммиченных изменений и нужных stash-записей. Для восстановления случайно удалённого коммита сначала проверьте git reflog и git fsck --lost-found; после --prune=now этих объектов уже не будет.

Документация: git gc, git maintenance.