Maîtrisez le ramasse-miettes Git pour des performances optimales

Apprenez quand exécuter git gc, ce qu'il nettoie et comment éviter un nettoyage agressif risqué sur des dépôts actifs.

Maîtrisez le ramasse-miettes Git pour des performances optimales

Le ramasse-miettes Git empêche votre dépôt de collecter indéfiniment des objets épars, des commits inaccessibles obsolètes et des fichiers pack inefficaces. Si votre dépôt semble lent, prend trop d'espace disque ou a subi de nombreux rebases et nettoyages de branches, git gc est l'un des premiers outils de maintenance à comprendre.

Vous n'avez généralement pas besoin de l'exécuter tous les jours. Git lance une maintenance automatique lors des commandes normales lorsque certains seuils sont atteints. Néanmoins, savoir ce qu'il fait vous aide à éviter deux erreurs courantes : ignorer un dépôt gonflé pendant des mois, ou exécuter un nettoyage agressif sur un dépôt partagé sans en comprendre l'impact.

Ce que fait le ramasse-miettes Git

Git stocke les données sous forme d'objets : commits, arbres, blobs et étiquettes. Les nouveaux objets peuvent commencer comme des fichiers épars sous .git/objects/. Avec le temps, Git peut regrouper de nombreux objets ensemble dans des fichiers pack compacts. Les objets packés utilisent le disque plus efficacement et sont généralement plus rapides à analyser pour Git.

git gc effectue plusieurs tâches de maintenance, notamment :

  • Packer les objets épars dans des fichiers pack.
  • Consolider les fichiers pack existants lorsque c'est utile.
  • Supprimer les objets inaccessibles suffisamment anciens pour être élagués.
  • Nettoyer les fichiers temporaires laissés par des opérations interrompues.
  • Mettre à jour les données auxiliaires telles que les fichiers commit-graph dans les configurations Git modernes lorsqu'elles sont configurées.

Inaccessible ne signifie pas toujours sûr à supprimer immédiatement. Un commit peut devenir inaccessible après un rebase, un amend, un reset ou une suppression de branche. Git conserve normalement les objets récemment inaccessibles pendant une période de grâce afin que vous ayez le temps de les récupérer avec git reflog.

Vérifiez la taille du dépôt avant de nettoyer

Commencez par mesurer le dépôt au lieu de deviner :

git count-objects -vH

Les champs utiles incluent count, size, in-pack, packs et size-pack. Un nombre élevé d'objets épars peut ralentir les opérations Git quotidiennes. Un size-pack important peut simplement signifier que le dépôt a beaucoup d'historique réel, de gros fichiers binaires ou des actifs fournisseurs.

Pour inspecter l'utilisation du disque directement, exécutez :

du -sh .git

Si .git est énorme parce que quelqu'un a commité des artefacts de build ou de grandes archives, le ramasse-miettes seul peut ne pas résoudre le vrai problème. Vous devrez peut-être supprimer les gros fichiers des futurs commits, les déplacer vers Git LFS ou réécrire l'historique avec un outil tel que git filter-repo après coordination avec l'équipe.

Exécutez un ramasse-miettes normal

Pour un nettoyage de routine, utilisez :

git gc

C'est la valeur par défaut sûre. Elle laisse Git décider quel travail de maintenance vaut la peine et respecte les règles d'élagage normales.

Vous pouvez demander à Git de faire une maintenance automatique uniquement si les seuils le nécessitent :

git gc --auto

La plupart des utilisateurs n'ont pas besoin d'appeler --auto manuellement car Git le fait déjà en arrière-plan. C'est toujours utile dans les scripts où vous voulez un passage de nettoyage peu coûteux sans forcer un reconditionnement complet à chaque fois.

Si vous voulez supprimer les anciens objets inaccessibles en utilisant la période de grâce standard, exécutez :

git gc --prune=now

Utilisez --prune=now avec précaution. Il peut supprimer des points de récupération que git reflog pourrait autrement vous aider à trouver. Évitez-le juste après un rebase compliqué, une suppression de branche ou un reset, sauf si vous êtes certain de ne pas avoir besoin des anciens objets.

Soyez prudent avec --aggressive

git gc --aggressive dit à Git de passer plus de temps CPU à essayer d'optimiser le conditionnement des objets :

git gc --aggressive

Ce n'est pas un bouton magique de vitesse. Sur de nombreux dépôts, le travail supplémentaire apporte peu de bénéfices par rapport à git gc normal, et peut prendre beaucoup de temps sur les grands historiques. Utilisez-le seulement lorsque vous avez mesuré un réel problème de taille de dépôt ou de performance et que vous pouvez vous permettre la fenêtre de maintenance.

Pour le travail quotidien, préférez git gc simple. Si votre dépôt nécessite régulièrement un nettoyage agressif, le problème plus profond est souvent les gros fichiers, les artefacts générés ou un flux de travail qui crée beaucoup d'historique inaccessible.

Utilisez la maintenance Git moderne pour un entretien continu

Les versions récentes de Git incluent git maintenance, qui peut planifier des tâches en arrière-plan telles que le préchargement, les mises à jour du commit-graph et le reconditionnement incrémental selon votre plateforme et configuration.

Pour exécuter la maintenance une fois :

git maintenance run

Pour activer la maintenance planifiée pour votre compte utilisateur :

git maintenance start

Vérifiez votre version de Git et la documentation locale avant de vous fier à la maintenance planifiée dans l'automatisation, car l'intégration exacte du planificateur diffère selon le système d'exploitation et la construction de Git.

Flux de nettoyage pratique

Un flux de nettoyage sûr pour un dépôt local ressemble à ceci :

git status
git count-objects -vH
git gc
git count-objects -vH

Assurez-vous que votre arbre de travail est propre avant la maintenance. Git peut exécuter le ramasse-miettes avec des modifications locales présentes, mais un arbre propre élimine les doutes si vous devez dépanner par la suite.

Pour un dépôt nu partagé sur un serveur, planifiez la maintenance pendant une période calme. Évitez d'exécuter des reconditionnements lourds pendant les pics d'activité CI, car les opérations de clone, fetch et push peuvent entrer en concurrence pour le disque et le CPU.

Quand le ramasse-miettes n'aidera pas

Le ramasse-miettes ne peut pas résoudre tous les dépôts Git lents. Il ne supprimera pas les fichiers qui sont toujours accessibles dans l'historique. Il ne rendra pas un monorepo petit si l'historique actif contient véritablement des années de gros actifs. Il ne réparera pas un dépôt corrompu par lui-même.

Si les performances restent médiocres après un nettoyage normal, recherchez ces causes :

  • Gros fichiers binaires commités directement dans Git.
  • Trop de fichiers générés suivis dans le dépôt.
  • Antivirus ou indexation du système de fichiers analysant .git à chaque opération.
  • Stockage réseau lent hébergeant l'arbre de travail.
  • Arbres de travail très grands où le checkout partiel peut aider.

Utilisez git gc comme maintenance, pas comme substitut à l'hygiène du dépôt. Exécutez un nettoyage normal lorsque le nombre d'objets augmente, évitez le nettoyage agressif sauf si vous avez mesuré un besoin, et traitez les artefacts volumineux suivis comme un problème de flux de travail à corriger à la source.