Date de la publication : 19 novembre 2025

Lecture : 13 min

Nouveautés de Git 2.52.0

Découvrez les contributions à cette version, notamment la nouvelle commande git-last-modified(1), les améliorations des outils de réécriture de l'historique et une nouvelle stratégie de maintenance.

Le projet Git a récemment publié Git 2.52. Après un cycle de publication relativement court de 8 semaines pour la version 2.51, en raison de l'été dans l'hémisphère nord, cette version revient au cycle habituel de 12 semaines. Passons en revue certaines modifications notables, notamment les contributions de l'équipe Git de GitLab ainsi que de l'ensemble de la communauté Git.

Nouvelle commande git-last-modified(1)

De nombreuses forges Git comme GitLab affichent les fichiers dans une vue arborescente comme celle-ci :

Nom Dernier commit Dernière mise à jour
README.md README: *.txt -> *.adoc fixes Il y a 4 mois
RelNotes Start 2.51 cycle, the first batch Il y a 4 semaines
SECURITY.md SECURITY: describe how to report vulnerabilities Il y a 4 ans
abspath.c abspath: move related functions to abspath Il y a 2 ans
abspath.h abspath: move related functions to abspath Il y a 2 ans
aclocal.m4 configure: use AC_LANG_PROGRAM consistently Il y a 15 ans
add-patch.c pager: stop using the_repository Il y a 7 mois
advice.c advice: allow disabling default branch name advice Il y a 4 mois
advice.h advice: allow disabling default branch name advice Il y a 4 mois
alias.h rebase -m: fix serialization of strategy options Il y a 2 ans
alloc.h git-compat-util: move alloc macros to git-compat-util.h Il y a 2 ans
apply.c apply: only write intents to add for new files Il y a 8 jours
archive.c Merge branch 'ps/parse-options-integers' Il y a 3 mois
archive.h archive.h: remove unnecessary include Il y a 1 an
attr.h fuzz: port fuzz-parse-attr-line from OSS-Fuzz Il y a 9 mois
banned.h banned.h: mark strtok() and strtok_r() as banned Il y a 2 ans



Outre les fichiers eux-mêmes, nous affichons également le dernier commit qui a modifié chaque fichier. Cette information est facile à extraire de Git en exécutant la commande suivante :


$ git log --max-count=1 HEAD -- <filename>

Bien que simple et pratique, cette approche présente une limitation importante : Git ne dispose pas d'un moyen d'extraire cette information pour chacun de ces fichiers en une seule commande. Ainsi, pour obtenir le dernier commit de tous les fichiers de l'arborescence, il faut exécuter cette commande pour chaque fichier séparément, ce qui donne un pipeline similaire à celui-ci :


$ git ls-tree HEAD --name-only | xargs --max-args=1 git log --max-count=1 HEAD --

Néanmoins, cette approche n'est pas très efficace :

  • Il est nécessaire de lancer une nouvelle commande Git pour chaque fichier.

  • Git doit parcourir l'historique de chaque fichier séparément.

En conséquence, cette opération complète est assez coûteuse et génère une charge importante pour GitLab.

Pour répondre à ces défis, une nouvelle sous-commande Git, git-last-modified(1), a été introduite. Elle indique le dernier commit pour chaque fichier d'un commit donné :


$ git last-modified HEAD


e56f6dcd7b4c90192018e848d0810f091d092913        add-patch.c
373ad8917beb99dc643b6e7f5c117a294384a57e        advice.h
e9330ae4b820147c98e723399e9438c8bee60a80        advice.c
5e2feb5ca692c5c4d39b11e1ffa056911dd7dfd3        alloc.h
954d33a9757fcfab723a824116902f1eb16e05f7        RelNotes
4ce0caa7cc27d50ee1bedf1dff03f13be4c54c1f        apply.c
5d215a7b3eb0a9a69c0cb9aa43dcae956a0aa03e        archive.c
c50fbb2dd225e7e82abba4380423ae105089f4d7        README.md
72686d4e5e9a7236b9716368d86fae5bf1ae6156        attr.h
c2c4138c07ca4d5ffc41ace0bfda0f189d3e262e        archive.h
5d1344b4973c8ea4904005f3bb51a47334ebb370        abspath.c
5d1344b4973c8ea4904005f3bb51a47334ebb370        abspath.h
60ff56f50372c1498718938ef504e744fe011ffb        banned.h
4960e5c7bdd399e791353bc6c551f09298746f61        alias.h
2e99b1e383d2da56c81d7ab7dd849e9dab5b7bf0        SECURITY.md
1e58dba142c673c59fbb9d10aeecf62217d4fc9c        aclocal.m4

L'avantage de cette approche est évident : nous n'avons plus besoin d'exécuter qu'un seul processus Git pour obtenir toutes ces informations. Mais plus important encore, Git ne doit parcourir l'historique qu'une seule fois pour tous les fichiers.

Voici comment faire :

  1. Commencez à parcourir l'historique depuis le commit souhaité.
  2. Pour chaque commit :
    1. S'il ne modifie aucun des chemins d'accès qui nous intéressent, continuez au commit suivant.
    2. En cas de chemins d'accès modifiés, affichez l'identifiant du commit avec le chemin, puis retirez le chemin de l'ensemble des chemins.
  3. Arrêtez-vous lorsque la liste des chemins est vide. Gitaly a déjà été adapté pour utiliser la nouvelle commande, mais la logique est encore protégée par un feature flag. Des tests préliminaires ont montré que dans la plupart des situations, git-last-modified(1) est au moins deux fois plus rapide que git log --max-count=1.

Ces modifications ont été écrites à l'origine par plusieurs développeurs de GitHub et ont été intégrées en amont dans Git par Toon Claes.

Améliorations liées aux signatures pour git-fast-export(1) et git-fast-import(1)

Les commandes git-fast-export(1) et git-fast-import(1) sont conçues pour être principalement utilisées par des outils d'interopérabilité ou de réécriture d'historique. Les outils d'interopérabilité ont pour objectif d'assurer des interactions harmonieuses entre Git et un autre logiciel, le plus souvent un système de contrôle de version qui stocke les données dans un format différent de Git. Par exemple, hg-fast-export.sh est un « convertisseur Mercurial vers Git utilisant git-fast-import ».

Les outils de réécriture d'historique permettent aux utilisateurs, généralement des administrateurs, d'apporter des modifications à l'historique de leurs dépôts qui ne sont pas possibles ou pas autorisées par le système de contrôle de version. Par exemple, reposurgeon indique dans son introduction que son objectif est « de permettre des opérations risquées que les systèmes de contrôle de version n'autorisent pas comme (a) modifier des commentaires et métadonnées passés, (b) supprimer des commits, (c) fusionner et diviser des commits, (d) supprimer des fichiers et sous-arbres de l'historique du dépôt, (e) fusionner ou greffer deux dépôts ou davantage et (f) diviser un dépôt en deux en dissociant une relation parent-enfant et en préservant la structure des branches des deux dépôts enfants ».

Au sein de GitLab, nous utilisons git-filter-repo pour autoriser les administrateurs à effectuer certaines opérations risquées sur leurs dépôts Git. Malheureusement, jusqu'à la version Git 2.50 publiée en juin dernier, ni git-fast-export(1) ni git-fast-import(1) ne prenaient en charge les signatures cryptographiques de commits. Bien que git-fast-export(1) ait une option --signed-tags=<mode> qui permette aux utilisateurs de modifier la façon dont les signatures cryptographiques de tags sont gérées, les signatures de commits étaient simplement ignorées.

Les signatures cryptographiques sont très fragiles, car elles sont basées sur les données exactes du commit ou du tag qui ont été signées. Lorsque les données signées ou l'historique qui les précède changent, la signature cryptographique devient invalide. C'est une exigence fragile mais qui rend ces signatures utiles.

Dans le contexte de la réécriture d'historique, cette approche devient problématique :

  • Nous pourrions vouloir conserver les signatures cryptographiques pour les commits et les tags toujours valides après la réécriture (par exemple, parce que l'historique n'a pas changé).

  • Nous pourrions vouloir créer de nouvelles signatures cryptographiques pour les commits et les tags dont la signature précédente est désormais invalide.

Cependant, ni git-fast-import(1) ni git-fast-export(1) ne prennent en charge ces cas d'utilisation, ce que des outils comme git-filter-repo ou reposurgeon ne peuvent accomplir.

Voici les progrès significatifs réalisés :

  • Dans la version Git 2.50, nous avons ajouté une option --signed-commits=<mode> à git-fast-export(1) pour exporter les signatures de commits, et une prise en charge dans git-fast-import(1) pour les importer.

  • Dans la version Git 2.51, nous avons amélioré le format utilisé pour exporter et importer les signatures de commits et modifié git-fast-import(1) afin que la commande puisse importer à la fois une signature sur l'ID d'objet SHA-1 du commit et une sur son ID d'objet SHA-256.

  • Dans la version Git 2.52, nous avons ajouté les options --signed-commits=<mode> et --signed-tags=<mode> à git-fast-import(1), afin que l'utilisateur puisse contrôler la gestion des données signées au moment de l'importation.

Le travail n'est pas encore terminé. Nous devons encore ajouter les fonctionnalités suivantes :

  • Conserver uniquement les signatures de commits qui sont toujours valides dans git-fast-import(1).

  • Signer à nouveau les données dont la signature est devenue invalide.

Nous avons déjà commencé à travailler sur ces prochaines étapes, qui devraient être intégrées à Git 2.53. Une fois ces fonctionnalités disponibles, des outils comme git-filter-repo(1) pourront enfin mieux gérer les signatures cryptographiques. Nous vous tiendrons informés dans notre prochain article de blog consacré à la sortie de version Git.

Ce projet a été mené par Christian Couder.

Améliorations des stratégies git-maintenance(1)

Les dépôts Git nécessitent une maintenance régulière pour garantir de bonnes performances. Lors de cette opération, les références sont optimisées, les objets compressés et les données obsolètes éliminées.

Jusqu'à la version Git 2.28, ces tâches de maintenance étaient effectuées par git-gc(1). Néanmoins, cette commande n'a pas été conçue dans un esprit de personnalisation : bien que certains paramètres puissent être configurés, il n'est pas possible de contrôler les parties d'un dépôt à optimiser. Elle ne convient donc pas à tous les cas d'utilisation. Plus important encore, il est très difficile d'itérer sur la façon dont Git effectue la maintenance du dépôt.

Pour résoudre ce problème et itérer à nouveau, Derrick Stolee a déployé git-maintenance(1). Contrairement à git-gc(1), cette commande a été conçue pour être personnalisable et permet à l'utilisateur de configurer les tâches spécifiques qui doivent s'exécuter dans un certain dépôt. Ce nouvel outil est devenu l'outil par défaut pour la maintenance automatisée de Git dans la version Git 2.29, mais, par défaut, il utilise toujours git-gc(1) pour effectuer la maintenance.

Bien que cette stratégie de maintenance par défaut fonctionne bien pour les dépôts de petite taille ou même de taille moyenne, elle se révèle problématique dans le contexte de grands monorepos. Le principal facteur limitant est la façon dont git-gc(1) rempaquette les objets : dès que le nombre de fichiers d'empaquetage (« packfiles ») dépasse les 50, l'outil les fusionne en un seul fichier. Cette opération gourmande en CPU provoque de nombreuses opérations d'E/S et peut facilement prendre plusieurs minutes, voire des heures pour les grands monorepos.

Git sait déjà comment minimiser ces rempaquetages via le « rempaquetage géométrique ». L'idée est simple : les fichiers d'empaquetage du dépôt doivent suivre une progression géométrique, c'est-à-dire que chaque fichier doit contenir au moins deux fois plus d'objets que le fichier suivant plus petit. Git peut ainsi amortir le nombre de rempaquetages requis et garantir une quantité relativement limitée de fichiers d'empaquetage. Ce mode a été introduit par Taylor Blau dans la version Git 2.32, mais il n'était pas intégré dans la maintenance automatisée.

Tous les éléments existants servent à faciliter la mise à l'échelle de la maintenance du dépôt pour les grands monorepos : l'outil flexible git-maintenance(1) peut être étendu pour intégrer une nouvelle stratégie de maintenance, et nous disposons d'une meilleure méthode pour rempaqueter les objets. Il ne reste plus qu'à combiner ces deux éléments.

Et c'est exactement ce que nous avons fait dans la version Git 2.52. La nouvelle stratégie de maintenance « géométrique » peut être configurée dans vos dépôts Git et est destinée à remplacer complètement l'ancienne stratégie basée sur git-gc(1). Voici le code de configuration dont vous avez besoin :


$ git config set maintenance.strategy geometric

À partir de maintenant, Git utilisera le rempaquetage géométrique afin d'optimiser vos objets. Résultat : un taux d'attrition plus faible et une optimisation de l'état de vos objets, en particulier dans les grands monorepos.

Dans Git 2.53, nous prévoyons d'en faire la stratégie par défaut.

Ce projet a été dirigé par Patrick Steinhardt.

Nouvelle sous-commande pour git-repo(1) afin d'afficher les métriques du dépôt

Les performances des opérations Git dans un dépôt dépendent souvent de certaines caractéristiques de sa structure sous-jacente. Chez GitLab, nous hébergeons des dépôts extrêmement volumineux, et il est essentiel d'avoir un aperçu de la structure générale d'un dépôt pour comprendre ses performances. Bien qu'il soit possible de combiner diverses commandes Git et d'autres outils pour obtenir certaines métriques du dépôt, il est impossible d'afficher des informations sur la forme/structure d'un dépôt via une seule commande dans Git. Pour combler cette lacune, des outils externes comme git-sizer(1) ont été développés.

Avec la sortie de Git 2.52, une nouvelle sous-commande « structure » a été ajoutée à git-repo(1) dans le but d'afficher des informations sur la structure d'un dépôt. Actuellement, elle indique le nombre de références et d'objets dans le dépôt sous la forme suivante :


$ git repo structure


| Repository structure | Value  |
| -------------------- | ------ |
| * References         |        |
|   * Count            |   1772 |
|     * Branches       |      3 |
|     * Tags           |   1025 |
|     * Remotes        |    744 |
|     * Others         |      0 |
|                      |        |
| * Reachable objects  |        |
|   * Count            | 418958 |
|     * Commits        |  87468 |
|     * Trees          | 168866 |
|     * Blobs          | 161632 |
|     * Tags           |    992 |

Dans les versions ultérieures, nous espérons enrichir cette commande et fournir d'autres points de données intéressants comme les objets les plus volumineux du dépôt.

Ce projet a été mené par Justin Tobler.

Améliorations liées au Google Summer of Code 2025

Nous avons mené trois projets avec succès au cours du Google Summer of Code.

Refactorisation pour réduire l'état global de Git

Git contient plusieurs variables globales utilisées dans tout le code source qui augmentent la complexité du code et réduisent sa maintenabilité. Dans le cadre de ce projet, Ayush Chandekar a réduit l'utilisation de la variable globale the_repository via une série de correctifs.

Le projet a été encadré par Christian Couder et Ghanshyam Thakkar.

Outil de requête d'informations lisibles par machine sur le dépôt

Git manque d'un moyen centralisé pour récupérer des informations sur les dépôts. Les utilisateurs sont donc obligés de les obtenir à partir de diverses commandes. Bien que git-rev-parse(1) soit devenu l'outil par défaut pour accéder à une grande partie de ces données, il ne s'agit pas de son objectif principal.

Dans le cadre de ce projet, Lucas Oshiro a créé une nouvelle commande, git-repo(1), qui centralisera toutes les informations au niveau du dépôt. Les utilisateurs peuvent maintenant utiliser git repo info pour obtenir des informations sur un dépôt :


$ git repo info layout.bare layout.shallow object.format references.format

layout.bare=false
layout.shallow=false
object.format=sha1
references.format=reftable

Le projet a été encadré par Patrick Steinhardt et Karthik Nayak.

Consolidation des fonctionnalités liées aux références dans git-refs

Git propose plusieurs commandes pour gérer les références, à savoir git-for-each-ref(1), git show-ref(1), git-update-ref(1) et git-pack-refs(1). Cette multiplication des commandes freine leur utilisation et crée des fonctionnalités redondantes. Pour résoudre ce problème, nous avons développé la commande git-refs(1) afin de consolider ces opérations dans une interface unique. Dans le cadre de ce projet, Meet Soni a étendu la commande avec les sous-commandes suivantes :

  • git refs optimize pour optimiser le backend qui gère les références

  • git refs list pour afficher toutes les références

  • git refs exists pour vérifier l'existence d'une référence

Le projet a été encadré par Patrick Steinhardt et shejialuo.

Et après ?

Prêt à découvrir ces améliorations ? Passez à la version Git 2.52.0 et commencez à utiliser git last-modified.

Chez GitLab, nous nous assurerons que toutes ces améliorations soient déployées dans une instance GitLab près de chez vous !

Pour en savoir plus, consultez les notes de version officielles de Git 2.52.0 et explorez notre archive complète du développement Git.

Votre avis nous intéresse

Cet article de blog vous a plu ou vous avez des questions ou des commentaires ? Partagez vos réflexions en créant un sujet dans le forum de la communauté GitLab.
Donnez votre avis

Plus de 50 % des entreprises du classement Fortune 100 font confiance à GitLab

Commencez à livrer des logiciels de meilleure qualité plus rapidement

Découvrez comment la plateforme DevSecOps intelligente

peut aider votre équipe.