Date de publication : 27 avril 2026

Temps de lecture : 12 min

Nouveautés de Git 2.54.0

Découvrez les contributions à cette release de Git 2.54.0, notamment la nouvelle maintenance des dépôts, une nouvelle commande pour modifier l'historique des commits, le remplacement de git-sizer(1) et plus encore.

Le projet Git a récemment publié Git 2.54.0. Passons en revue quelques-unes des nouveautés marquantes de cette release, qui comprend des contributions de l'équipe Git chez GitLab.

Bases de données d'objets modulaires

Git offre déjà la possibilité de stocker les références avec le backend « files » ou avec le backend « reftable ». Ce scénario est rendu possible grâce à des abstractions appropriées dans Git qui permettent de disposer de différents backends.

Mais les références ne constituent qu'un des deux types importants de données stockées dans les dépôts, l'autre étant les objets. Les objets sont stockés dans la base de données d'objets, et chaque base de données d'objets est à son tour composée de plusieurs sources d'objets à partir desquelles les objets peuvent être lus ou écrits. Chaque source d'objets stocke soit des objets individuels sous forme d'objets dits « libres », soit compresse plusieurs objets dans un fichier d'empaquetage (« packfile ») dans le répertoire .git/objects.

Jusqu'à présent, cependant, ces sources ne disposaient pas d'une couche d'abstraction appropriée, de sorte que le format de stockage des objets était entièrement codé en dur dans Git. Mais les choses changent enfin avec les bases de données d'objets enfichables. Le concept est simple et similaire à ce qui a été fait pour les références par le passé : au lieu de chemins de code en dur pour le stockage des objets, nous introduisons une couche d'abstraction qui permet de disposer de différents backends pour le stockage des objets.

Si l'idée est simple, la mise en œuvre ne l'est pas, car les spécificités des formats de stockage sont codées en dur partout dans Git. En réalité, nous avons commencé à travailler sur ce projet dès Git 2.48, qui a été publié en janvier 2025. Dans un premier temps, nous nous sommes concentrés sur l'encapsulation des sous-systèmes liés aux objets et sur la création de sous-systèmes dédiés pour les backends existants dans Git.

Avec Git 2.54, nous franchissons une étape importante : le backend de la base de données d'objets est désormais modulaire. Toutes les fonctionnalités de Git ne sont pas encore couvertes, mais l'introduction d'un backend alternatif capable de gérer un sous-ensemble significatif d'opérations est désormais un objectif réaliste.

Pour l'instant, seuls les workflows locaux comme la création de commits, l'affichage de graphes de commits ou l'exécution de merges fonctionneront avec une telle implémentation alternative. Cette approche exclut notamment tout ce qui interagit avec un dépôt distant, comme les opérations de récupération ou de push de modifications. Quoi qu'il en soit, il s'agit de l'aboutissement de près de deux ans de travail, répartis sur près de 400 commits fusionnés en amont, et nous continuerons bien entendu à itérer.

Mais pourquoi ce projet est-il important ? L'objectif est de simplifier l'introduction de nouveaux formats de stockage dans Git. Voici quelques exemples :

  • Un format de stockage capable de gérer les fichiers binaires volumineux de manière plus efficace que les fichiers d'empaquetage actuels
  • Un format de stockage sur mesure pour GitLab afin de garantir que nous puissions servir les dépôts à nos utilisateurs de manière encore plus efficace qu'actuellement

Il s'agit d'un effort à grande échelle qui est susceptible de façonner l'avenir de Git et de GitLab.

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

Modification simplifiée de votre historique de commits

Dans de nombreux projets de développement logiciel, il est courant pour les développeurs de ne pas seulement peaufiner le code qu'ils souhaitent soumettre, mais aussi de soigner l'historique des commits afin de faciliter la revue. Le résultat est un ensemble de commits petits et atomiques, chacun dédié à une seule tâche, accompagné d'un bon message de commit qui décrit l'intention ainsi que les nuances spécifiques.

Bien entendu, ces commits atomiques ne sont le plus souvent pas le fruit naturel du processus de développement. L'auteur des modifications acquiert plutôt une meilleure compréhension au fur et à mesure des itérations, et la manière de découper les commits se clarifie avec le temps. De plus, le processus de revue qui s'ensuit peut donner lieu à des retours nécessitant des modifications des commits déjà préparés.

Par conséquent, le développeur devra réécrire son historique de commits de nombreuses fois au cours du développement. Git offre depuis longtemps cette possibilité via les rebasages interactifs. Ces rebasages interactifs sont un outil extrêmement puissant : ils permettent de réordonner les commits, de réécrire les messages de commits, de regrouper plusieurs commits ou d'effectuer des modifications arbitraires sur n'importe quel commit.

Mais ils sont aussi quelque peu obscurs et difficiles à appréhender. L'utilisateur doit identifier le commit de base pour le rebasage, comprendre comment modifier une « feuille d'instructions » assez obscure et connaître le fonctionnement à état du processus de rebasage. Par exemple, les utilisateurs se voient présenter une feuille d'instructions similaire à celle ci-dessous lors du rebasage d'une branche thématique :

      pick b60623f382 # t: detect errors outside of test cases # empty
pick b80cb55882 # t: prepare `test_match_signal ()` calls for `set -e`
pick 5ffe397f30 # t: prepare `test_must_fail ()` for `set -e`
pick 5e9b0cf5e1 # t: prepare `stop_git_daemon ()` for `set -e`
pick 299561e7a2 # t: prepare `git config --unset` calls for `set -e`
pick ed0e7ca2b5 # t: detect errors outside of test cases

    

Ainsi, bien que les rebasages interactifs soient puissants, ils restent assez intimidants pour l'utilisateur moyen.

Mais ce n'est pas une fatalité. Des outils comme Jujutsu offrent des interfaces beaucoup plus simples d'utilisation par rapport à Git, puisqu'il suffit par exemple d'exécuter jj split pour diviser un commit en deux. Avec Git et les rebasages interactifs, ce cas d'utilisation requiert de nombreuses étapes avec des arguments en ligne de commande peu explicites.

Nous nous sommes donc inspirés de Jujutsu et avons introduit dans Git une nouvelle commande git-history(1), qui constitue le socle d'une meilleure modification de l'historique. Pour l'instant, cette commande dispose de deux sous-commandes :

  • git history reword vous permet de réécrire facilement un message de commit. Il vous suffit d'indiquer le commit que vous souhaitez mieux documenter, Git vous demande le nouveau message de commit, et c'est terminé.
  • git history split vous permet de diviser un commit en deux, à l'image de jj split. Vous indiquez un commit, Git vous demande quelles modifications mettre dans quel commit ainsi que les deux messages de commit, et c'est terminé.

Ce n'est bien sûr qu'un début, et nous souhaitons ajouter des sous-commandes supplémentaires au fil du temps. Par exemple :

  • git history fixup pour prendre les modifications indexées et les intégrer automatiquement à un commit spécifique
  • git history drop pour supprimer un commit
  • git history reorder pour réordonner la séquence de commits
  • git history squash pour regrouper une série de commits

Mais ce n'est pas tout. En plus de simplifier la modification de l'historique, cette nouvelle commande sait aussi rebaser automatiquement toutes vos branches locales qui incluaient précédemment ce commit. Cela signifie que vous pouvez modifier un commit qui ne se trouve pas sur la branche courante, et toutes les branches contenant ce commit seront réécrites.

Au premier abord, il peut sembler surprenant que Git rebase automatiquement les branches dépendantes, car cela constitue une divergence significative par rapport au fonctionnement de git-rebase(1). Mais cela s'inscrit dans un effort plus large visant à améliorer la prise en charge des « diffs empilés » (« Stacked Diffs ») dans Git, une méthode permettant de créer une série de plusieurs branches dépendantes pouvant être revues indépendamment, mais qui concourent ensemble à un objectif plus vaste.

Ce projet a été mené par Patrick Steinhardt avec le soutien d'Elijah Newren.

Remplacement natif de git-sizer(1)

La taille d'un dépôt Git est un facteur important qui détermine la capacité de Git et de GitLab à le gérer efficacement. Mais la taille n'est pas le seul facteur, car les performances d'un dépôt résultent en définitive d'une combinaison de plusieurs aspects :

  • La taille de l'historique des commits
  • La structure de l'arborescence des répertoires
  • La taille des fichiers stockés dans le dépôt
  • Le nombre de références

Ce ne sont là que quelques-uns des aspects à prendre en compte pour prédire si Git sera en mesure de gérer correctement un dépôt.

Bien qu'il soit clair que la simple taille du dépôt est insuffisante, Git ne fournit en soi aucun outil offrant à l'utilisateur une vue d'ensemble claire de ces indicateurs. Les utilisateurs sont contraints de s'appuyer sur des outils tiers comme git-sizer(1) pour combler cette lacune. Cet outil fait un excellent travail pour afficher ces informations, mais il ne fait pas partie de Git et doit donc être installé séparément.

L'observabilité des composants internes d'un dépôt est essentielle chez GitLab. C'est pourquoi nous avons introduit une nouvelle sous-commande git repo structure dans Git 2.52 pour afficher les indicateurs du dépôt, que nous avons étendue dans Git 2.53 pour afficher les tailles décompressées et sur disque des objets par type.

Dans Git 2.54, nous itérons davantage sur cette commande afin de ne pas seulement afficher la taille globale, mais aussi les objets les plus volumineux par type :

      $ git clone https://gitlab.com/git-scm/git.git
$ cd git
$ git repo structure
Counting objects: 410445, done.
| Repository structure      | Value       |
| ------------------------- | ----------- |
| * References              |             |
|   * Count                 |    1.01 k   |
|     * Branches            |       1     |
|     * Tags                |    1.00 k   |
|     * Remotes             |       9     |
|     * Others              |       0     |
|                           |             |
| * Reachable objects       |             |
|   * Count                 |  410.45 k   |
|     * Commits             |   83.99 k   |
|     * Trees               |  164.46 k   |
|     * Blobs               |  161.00 k   |
|     * Tags                |    1.00 k   |
|   * Inflated size         |    7.46 GiB |
|     * Commits             |   57.53 MiB |
|     * Trees               |    2.33 GiB |
|     * Blobs               |    5.07 GiB |
|     * Tags                |  737.48 KiB |
|   * Disk size             |  181.37 MiB |
|     * Commits             |   33.11 MiB |
|     * Trees               |   40.58 MiB |
|     * Blobs               |  107.11 MiB |
|     * Tags                |  582.67 KiB |
|                           |             |
| * Largest objects         |             |
|   * Commits               |             |
|     * Maximum size    [1] |   17.23 KiB |
|     * Maximum parents [2] |      10     |
|   * Trees                 |             |
|     * Maximum size    [3] |   58.85 KiB |
|     * Maximum entries [4] |    1.18 k   |
|   * Blobs                 |             |
|     * Maximum size    [5] | 1019.51 KiB |
|   * Tags                  |             |

|     * Maximum size    [6] |    7.13 KiB |

[1] f6ecb603ff8af608a417d7724727d6bc3a9dbfdf
[2] 16d7601e176cd53f3c2f02367698d06b85e08879
[3] 203ee97047731b9fd3ad220faa607b6677861a0d
[4] 203ee97047731b9fd3ad220faa607b6677861a0d
[5] aa96f8bc361fd84a1459440f1e7de02ab0dc3543
[6] 07e38db6a5a03690034d27104401f6c8ea40f1fc

    

Avec ces informations, nous sommes désormais presque au niveau de parité fonctionnelle avec git-sizer(1). Nous n'avons cependant pas encore terminé : nous prévoyons à terme d'ajouter des fonctionnalités supplémentaires telles que :

  • Des niveaux de gravité tels qu'ils existent dans git-sizer(1)
  • Des graphes affichant la distribution des tailles d'objets
  • La possibilité de scanner les objets accessibles via un sous-ensemble de références

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

Nouvelle infrastructure pour la maintenance des dépôts

Chaque fois que vous écrivez des données dans un dépôt Git, vous ajoutez généralement de nouveaux objets libres. Sans intervention, vous obtiendrez un grand nombre de fichiers distincts dans votre répertoire .git/objects/, ce qui ralentit plusieurs opérations nécessitant l'accès à de nombreux objets simultanément. Git compresse donc régulièrement ces objets dans des fichiers d'empaquetage pour garantir de bonnes performances.

Ce n'est pas la seule structure de données susceptible de perdre en efficacité au fil du temps : la mise à jour des références peut créer des références libres, les reflogs doivent être allégés, les arbres de travail peuvent devenir obsolètes et les caches comme les graphes de commits doivent être actualisés régulièrement.

Historiquement, toutes ces tâches étaient gérées par git-gc(1). Cependant, cet outil possède une architecture monolithique, exécutant essentiellement toutes les tâches requises dans un ordre séquentiel. Cette base est difficile à étendre et n'offre pas à l'utilisateur beaucoup de flexibilité s'il souhaite modifier légèrement la façon dont la maintenance est effectuée.

Le projet Git a introduit le nouvel outil git-maintenance(1) dans Git 2.29. Contrairement à git-gc(1), git-maintenance(1) n'est pas monolithique mais est structuré autour de tâches. Ces tâches sont librement configurables par l'utilisateur, ce qui lui offre un contrôle beaucoup plus précis sur la maintenance du dépôt.

Au bout du compte, Git a migré vers git-maintenance(1) par défaut. Mais au départ, la seule tâche activée par défaut était la tâche git-gc(1) qui, comme vous l'aurez deviné, exécute simplement git gc. Pour lancer manuellement la maintenance avec cette nouvelle commande, il suffit d'exécuter git maintenance run, mais Git sait l'exécuter automatiquement à la suite de plusieurs autres commandes.

Au cours des dernières releases, nous avons implémenté toutes les tâches individuelles prises en charge par git-gc(1) dans git-maintenance(1) afin de garantir la parité fonctionnelle entre ces deux outils.

De plus, nous avons implémenté une nouvelle tâche qui utilise l'architecture moderne de Git pour le rempaquetage d'objets avec le compactage géométrique. Le compactage géométrique est bien mieux adapté aux grands monorepos, et grâce à nos efforts, intégrés dans Git 2.53, pour le faire fonctionner avec les clones partiels, il constitue désormais un remplacement complet de notre précédente stratégie de rempaquetage dans Git.

Avec Git 2.54, nous avons franchi une autre étape importante : au lieu d'utiliser la stratégie basée sur git-gc(1) par défaut, nous utilisons désormais le rempaquetage géométrique avec des tâches de maintenance individuelles et granulaires. Outre son efficacité accrue pour les grands monorepos, il offre également une base plus facile à partir de laquelle itérer.

L'infrastructure de git-maintenance(1) a été initialement implémentée par Derrick Stolee, et la maintenance géométrique a été introduite par Taylor Blau. L'effort d'introduction des nouvelles tâches granulaires et de migration vers la nouvelle stratégie de maintenance a été mené par Patrick Steinhardt.

Pour en savoir plus

Cet article n'a mis en évidence que quelques-unes des contributions apportées par GitLab et la communauté Git pour cette dernière release. Vous pouvez en apprendre davantage dans l'annonce de release officielle du projet Git. Consultez également nos articles de blog précédents sur les releases de Git pour découvrir d'autres contributions des membres de l'équipe GitLab.

Donnez-nous votre avis

Cet article de blog vous a plu ? Vous avez des questions ou des retours à nous faire ? Donnez votre avis en créant un nouveau sujet sur le forum de la communauté GitLab.

Faites-nous part de vos commentaires

Commencez à développer plus rapidement dès aujourd'hui

Découvrez ce que votre équipe peut accomplir avec la plateforme d'orchestration intelligente pour le DevSecOps.