Introduction
Le garbage collection (gc) garde votre dépôt compact et rapide. Git le lance automatiquement quand certains seuils sont dépassés. Vous pouvez aussi l'invoquer manuellement.
Ce que fait gc
- Pack les objets loose dans des pack files.
- Re-deltifie si demandé.
- Supprime les objets inatteignables plus vieux que la fenêtre de prune-expire.
- Expire les entrées de reflog passé leur TTL.
- Optionnellement écrit le fichier commit-graph.
git gc
git gc --auto
git gc --aggressive
git gc --prune=now
git count-objects -v
Seuils auto-gc
git config gc.auto 6700 # seuil d'objets loose
git config gc.autoPackLimit 50 # seuil du nombre de packs
git config gc.autoDetach true # exécuter en arrière-plan
L'auto-gc se déclenche après les opérations qui créent de nouveaux objets, comme commit et fetch. Avec autoDetach, il s'exécute en arrière-plan et Git rend la main immédiatement.
Expiration du reflog
git config gc.reflogExpire 90.days
git config gc.reflogExpireUnreachable 30.days
git reflog expire --expire=90.days --all
Les entrées atteignables durent 90 jours, les inatteignables 30 par défaut. Les branches et tags que vous supprimez laissent des traces de reflog qui survivent pendant cette fenêtre.
Fenêtre de prune
git config gc.pruneExpire 2.weeks.ago
Les objets inatteignables plus vieux que cela sont éligibles à la suppression pendant gc. --prune=now supprime immédiatement ; utile mais dangereux car il retire les marges de sécurité.
Agressif vs normal
git gc # routine : packer les nouveaux, élaguer les vieux
git gc --aggressive # reconstruire les deltas à partir de zéro
Le gc agressif vaut rarement la peine ; il est lourd en CPU et le gain est généralement faible. Le gc normal suffit pour la plupart des dépôts.
Maintenance
Git moderne (2.29+) a un sous-système maintenance qui consolide et améliore gc :
git maintenance start
git maintenance run --task gc
git maintenance run --task commit-graph
git maintenance run --task incremental-repack
git maintenance start enregistre une tâche de fond (cron, launchd ou timer systemd) qui optimise périodiquement le dépôt.
Opérations verrouillées
Si gc est interrompu, vous pouvez voir un fichier de verrou obsolète :
ls .git/gc.pid
rm .git/gc.pid # seulement après confirmation qu'aucun gc ne tourne
Ce que gc ne supprime jamais
Plusieurs classes d'objets sont exemptes de gc jusqu'à ce que leur référence expire :
- Objets atteignables depuis toute ref sous
refs/. - Objets atteignables depuis le reflog de toute ref (jusqu'à expiration du reflog).
- Objets sous
refs/stash(la liste de stash). - Objets épinglés par les mappings
git replace. - Objets atteignables depuis le HEAD et l'index des worktrees.
git fsck --unreachable --no-reflogs
git reflog expire --expire-unreachable=now --all
git gc --prune=now
Cette dernière séquence est la recette standard « vraiment supprimer l'historique inatteignable » ; à utiliser avec précaution.
Erreurs fréquentes
Exécuter git gc --prune=now juste après une opération destructive, éliminant le filet de sécurité du reflog. Attendez toujours la fenêtre par défaut sauf si vous avez vraiment besoin de l'espace. Désactiver auto-gc sur un dépôt à évolution rapide, accumulant des millions d'objets loose. Lancer --aggressive sur un planning en supposant que « plus c'est mieux » ; cela ne fait que brûler du CPU. Enfin, lancer gc en concurrence avec git push sur un serveur ; Git moderne gère la concurrence sûrement, mais des scripts personnalisés qui se battent pour .git/objects peuvent corrompre. Utilisez git maintenance plutôt que des cron jobs maison.