Cours
Git adopte une approche préventive vis-à-vis de la suppression des données, afin d’éviter toute perte accidentelle de commits ou d’informations importantes.
Cependant, cela peut laisser visibles des données obsolètes, comme des références à des branches supprimées. Avec le temps, les dépôts Git peuvent accumuler des objets non référencés, qui consomment de l’espace disque inutilement et peuvent semer la confusion.
La commande git prune est un utilitaire de maintenance destiné principalement à nettoyer les objets inaccessibles du dépôt.
Un objet inaccessible est un objet qui n’est joignable par aucune branche, étiquette (tag), branche de suivi distante ou autre référence. Ces objets occupent de l’espace dans le dépôt et finissent par l’encombrer de données superflues.
Bien que git prune soit un outil puissant pour garder des dépôts légers, la plupart des utilisateurs n’ont pas besoin de l’exécuter directement grâce à la collecte des ordures automatique de Git (git gc). Comprendre son rôle reste toutefois utile pour les utilisateurs avancés de Git ou dans des situations où une maintenance manuelle du dépôt est nécessaire ou préférable.
Devenez ingénieur en données
Qu’est-ce que git prune ?
La commande git prune sert à supprimer les objets qui ne sont plus nécessaires dans le dépôt local. Il peut s’agir de commits, d’arbres (instantanés de répertoires), de blobs (fichiers) et de tags qui ne sont plus accessibles depuis aucune branche ou étiquette du dépôt.
En clair, git prune aide à nettoyer les fichiers et données inutiles du dépôt, ce qui permet d’économiser de l’espace et de réduire l’encombrement.
Comment des objets deviennent-ils inaccessibles ?
Plusieurs situations peuvent rendre des objets inaccessibles : par exemple la suppression de branches ou la réécriture de l’historique. Lorsqu’on supprime des branches, les commits qui leur sont propres et qui n’appartiennent à aucune autre branche ou tag deviennent inaccessibles.
La réécriture de commits, via des commandes comme git rebase, génère de nouveaux commits et abandonne les anciens, qui deviennent à leur tour inaccessibles.
Période de grâce et reflogs
Git conserve un journal des mises à jour des pointes de branches et d’autres références, appelé reflog (journal des références). On peut l’afficher avec la commande git reflog.
Même si un objet est inaccessible, s’il figure encore dans le reflog, il ne sera pas supprimé par git prune.
Par défaut, le reflog expire au bout de 90 jours, offrant une période de grâce durant laquelle les objets inaccessibles sont conservés temporairement et ne sont pas immédiatement élagués.
Quand utiliser git prune ?
En règle générale, nous n’avons pas besoin d’exécuter directement git prune. Git dispose d’un mécanisme de collecte des ordures qui s’exécute automatiquement après certaines commandes pour nettoyer les fichiers inutiles et optimiser l’efficacité du dépôt local en compressant certains objets.
Néanmoins, il peut être utile de nettoyer manuellement le dépôt, par exemple :
- Après une opération dont on sait qu’elle créera des objets inaccessibles, comme la suppression d’une branche.
- Lorsque l’on souhaite libérer de l’espace disque immédiatement.
- Pour garder le dépôt propre et bien rangé en permanence.
Collecte des ordures avec git gc
Plutôt que de lancer un élagage direct, il est généralement recommandé de s’appuyer sur la collecte des ordures, qui exécute non seulement un git prune, mais optimise aussi l’espace en compressant des objets.
Comme indiqué plus haut, la collecte des ordures est exécutée automatiquement après certaines commandes. Nous pouvons aussi la déclencher manuellement avec :
git gc
Comment utiliser git prune ?
Puisque git prune supprime des données, il est recommandé de l’exécuter d’abord avec l’option --dry-run.
git prune --dry-run
Cette option liste les objets qui seraient supprimés sans effectuer la suppression. La sortie ressemble à :
0d7dff8258654c03a058987b3e63c86feca9200d commit
ea1380f52f0bfa0142e46767adfd56593681091a blob
fa91af78a1ab453c1d7632192b3ca8bf217ec711 commit
Cette sortie indique que deux commits et un blob sont inaccessibles et seraient supprimés. Après s’être assuré qu’aucune donnée importante n’est listée, on peut lancer le nettoyage :
git prune
Dans certains cas, on souhaite nettoyer le dépôt juste après une action dont on sait qu’elle va créer des objets inaccessibles, comme la suppression d’une branche. On exécute git prune --dry-run, mais la sortie est vide. La raison est que les commits supprimés sont encore référencés dans le reflog.
Si l’on ne veut pas attendre leur expiration dans le reflog, on peut l’anticiper manuellement avec :
git reflog expire --expire-unreachable=now --all
Détaillons les options utilisées :
- L’option
--expire-unreachable=nowfixe la date d’expiration de tous les objets inaccessibles à maintenant, ce qui les fait expirer immédiatement. - L’option
--allcible toutes les entrées du reflog du dépôt. Sans elle, il faudrait préciser une référence particulière (branche ou tag) sur laquelle opérer.
git prune : usages avancés
Voyons quelques techniques avancées, comme la définition d’un délai d’expiration ou l’élagage d’objets déjà packagés.
Définir un délai d’expiration
On peut vouloir ne nettoyer que les objets inaccessibles anciens, par exemple ceux âgés d’au moins deux semaines.
L’option --expire <time> permet de fixer un seuil temporel. Git supprimera les objets inaccessibles depuis plus longtemps que la durée indiquée. Le paramètre <time> accepte différents formats tels que « 2 weeks ago », « 3 days », « yesterday », etc., pour offrir de la flexibilité.
Exemple :
git prune --expire=2.weeks.ago
Élaguer les objets packagés
Git stocke les objets de deux façons principales : en fichiers individuels (objets « loose ») et dans des fichiers packagés (packs). Le « packaging » permet d’économiser de l’espace et d’améliorer les performances en regroupant plusieurs objets dans un seul fichier et en éliminant les redondances.
Il arrive qu’un objet existe à la fois en version loose et packagée. Bien que cette redondance ne soit pas problématique (hormis un léger surcoût d’espace), on peut vouloir supprimer ces objets loose déjà présents dans un pack pour récupérer de la place.
La commande git prune-packed supprime les objets loose s’ils sont déjà inclus dans un pack. Contrairement à git prune, git prune-packed n’accepte pas d’options comme --expire <time>. Elle se contente de nettoyer les objets loose déjà packagés.
Conclusion
À mesure que l’on utilise un dépôt, certains objets deviennent inaccessibles, ce qui entraîne une consommation d’espace inutile. Git gère cela grâce à un système de collecte des ordures qui supprime les objets inaccessibles après un certain temps d’inactivité.
Ce mécanisme s’exécute automatiquement après certaines commandes, mais on peut aussi le lancer manuellement avec git gc. Le processus ne se contente pas de supprimer les objets inaccessibles via git prune ; il optimise aussi l’espace disque en compressant certains objets.
Les utilisateurs avancés de Git peuvent souhaiter maintenir un dépôt parfaitement propre. La commande git prune permet de supprimer manuellement les objets inaccessibles. Il convient toujours d’exécuter git prune --dry-run avant git prune pour avoir un aperçu des objets qui seront supprimés.
