L’avenir du contrôle de version
(bramcohen.com)- Manyana est un prototype de contrôle de version basé sur les CRDT développé par Bram Cohen, qui propose une nouvelle approche pour éliminer les conflits de fusion et préserver structurellement l’historique
- En s’appuyant sur les CRDT (Conflict-Free Replicated Data Type), la fusion réussit toujours, et les conflits sont traités comme de simples indications d’information, ce qui permet aux utilisateurs de comprendre clairement les modifications
- Les principes clés sont la persistance de l’ordre des lignes, les fusions non bloquantes et l’intégration de l’historique dans la structure ; même lors d’un rebase, les enregistrements existants ne sont pas détruits
- Il s’agit d’une implémentation de démonstration écrite en environ 470 lignes de Python, dont l’intégralité du code et du document de conception est publiée sur GitHub dans le domaine public
- Un exemple expérimental qui propose un modèle de contrôle de version de nouvelle génération sans échec de fusion, au-delà des limites de Git
Manyana : une vision cohérente pour l’avenir du contrôle de version
- Manyana est un prototype de système de contrôle de version basé sur les CRDT publié par Bram Cohen, qui cherche à résoudre le problème des conflits de fusion des systèmes existants
- Les CRDT garantissent que la fusion réussit toujours et traitent les conflits comme des indications informatives, afin que l’utilisateur puisse voir clairement les modifications réelles
- Cette approche repose sur trois caractéristiques essentielles : la persistance de l’ordre des lignes, la gestion non bloquante des conflits et l’intégration de l’historique dans la structure
- Même lors du rebase, l’historique existant est conservé, et des structures de fusion complexes sans ancêtre commun unique peuvent être traitées de manière fiable
- Manyana est une implémentation de démonstration d’environ 470 lignes de Python, dont le document de conception et le code sont publiés sur GitHub dans le domaine public
Les points clés de l’approche basée sur les CRDT
- Les CRDT offrent une fusion toujours réussie et une cohérence éventuelle (eventual consistency) garantissant le même résultat quel que soit l’ordre des fusions
- Même si plusieurs utilisateurs fusionnent des branches développées indépendamment dans un ordre quelconque, le résultat reste identique
- Grâce à la persistance de l’ordre des lignes, une fois que l’ordre du code inséré au même endroit est déterminé, il reste ensuite inchangé
- Cela évite que les zones en conflit soient résolues différemment selon les branches
- Les conflits sont traités uniquement comme des marqueurs d’information, sans bloquer la fusion
- Le résultat de la fusion est toujours produit, et les conflits sont signalés comme des « parties modifiées simultanément à proximité »
- En suivant l’auteur et l’action de chaque modification, le système fournit des indications de conflit utiles
- L’historique est intégré dans la structure
- L’état est représenté par une structure de « weave » contenant toutes les lignes du fichier, avec pour chaque ligne des métadonnées sur son ajout et sa suppression
- Lors d’une fusion, il suffit d’entrer deux états, sans rechercher d’ancêtre commun ni parcourir un DAG, pour obtenir systématiquement le bon résultat
Un affichage des conflits amélioré
- Les systèmes de contrôle de version traditionnels se contentent souvent d’afficher deux blocs de code côte à côte en cas de conflit, obligeant l’utilisateur à déduire lui-même les différences
- Manyana indique explicitement chaque zone de conflit par « supprimé », « ajouté », etc., et précise qui a effectué quelle modification
- Par exemple, si un utilisateur supprime une fonction tandis qu’un autre ajoute une ligne à l’intérieur de cette fonction, Manyana distingue clairement la structure de chaque modification
- Au lieu de comparer deux blocs, l’utilisateur peut ainsi saisir immédiatement le sens et le contexte des changements
Redéfinir le rebase
- Dans un système basé sur les CRDT, le rebase ne détruit pas l’historique
- Le rebase traditionnel réempile des commits sur une nouvelle base et crée ainsi un historique fictif
- Avec Manyana, on obtient le même effet tout en conservant l’intégralité de l’historique d’origine
- Pour cela, il suffit d’ajouter au DAG une annotation d’« ancêtre principal » (primary ancestor)
- Cette méthode fonctionne de manière fiable même avec des structures de fusion sans ancêtre commun, et permet d’éviter les échecs des fusions 3-way traditionnelles
État actuel du projet
- Manyana n’est pas un système de contrôle de version complet, mais une implémentation de démonstration fonctionnant à l’échelle du fichier individuel
- Elle est composée d’environ 470 lignes de code Python
- Les fonctionnalités de cherry-pick et d’undo local ne sont pas encore implémentées, mais le README présente les orientations prévues
- Le projet montre qu’un contrôle de version basé sur les CRDT peut résoudre des problèmes d’UX et produire de meilleurs résultats que les outils existants
- L’ensemble du code est distribué dans le domaine public (public domain), et l’intégralité du document de conception figure dans le README GitHub
Résumé des réactions de la communauté
- Un utilisateur estime que, même si Git est utilisé depuis plus de dix ans, un nouveau paradigme de contrôle de version est nécessaire, et mentionne positivement la tentative de Manyana
- Il souligne que l’idée d’une fusion qui réussit toujours n’est pas intuitive et demande davantage d’exemples et d’explications
- Il se dit intéressé par l’idée d’améliorer le rebase et indique utiliser, dans ses projets personnels, une méthode de gestion des fusions via des branches intermédiaires
- Il pointe certaines limites de Git, notamment la gestion des fichiers binaires, la confusion entre branches gauche et droite, et le manque de synthèse pour les changements de code à grande échelle
- Il suggère que les futurs systèmes de contrôle de version pourraient prendre en charge une approche token-aware ou des plugins par langage et par format de fichier
- Un autre utilisateur demande si Manyana repose sur des bases similaires à Pijul ou Darcs, et souhaite une comparaison avec les problèmes de performance de Darcs et l’état actuel de Pijul
Conclusion
- Manyana est une démo concrète appliquant les CRDT au contrôle de version, qui repense en profondeur la gestion des conflits et la question du rebase
- Une structure sans échec de fusion, la transformation des conflits en information et l’intégration structurelle de l’historique dessinent une direction de conception qui dépasse les limites du modèle Git actuel
- Ce n’est pas encore un système complet, mais c’est un point de départ significatif comme plan de conception pour les systèmes de contrôle de version de nouvelle génération
1 commentaires
Avis sur Hacker News
Je pense que la façon d’afficher les merges est un problème distinct de la représentation de l’historique
Moi aussi, je n’aime pas l’UI de merge par défaut de Git, donc j’utilise p4merge. C’est un outil qui affiche quatre panneaux (gauche, droite, base commune, résultat), ce qui permet de voir d’un coup d’œil l’origine du conflit et la manière de le résoudre
Je ne pense pas qu’il soit nécessaire de changer le VCS lui-même
merge.conflictStylede Git en"diff3"ou"zdiff3", la version de base s’affiche aussiCela permet de déduire, en regardant uniquement les marqueurs de conflit, quel côté a ajouté le nouveau code
J’ai été surpris, dans un podcast il y a quelque temps, d’entendre un invité ayant créé un nouveau VCS mal comprendre le mode de stockage des diff de Git. Voir quelqu’un travailler pendant des années sur un projet sans même vérifier les concepts de base m’a rappelé que l’esprit NIH (réinventer la roue) est toujours bien vivant
En revanche, le fait de le gérer au niveau du SCM a l’avantage de pouvoir mémoriser l’historique des choix de merge de l’utilisateur. Git a quelques cas limites sur ce point
Je ne suis pas certain que le fait qu’un merge n’échoue jamais soit une bonne chose
Un échec de merge n’indique pas seulement un conflit de position, c’est souvent aussi un signal de conflit sémantique. Dans ce cas, il faut intervenir manuellement
Je pense que les CRDT ne sont pas adaptés au contrôle de version
Les conflits sont au cœur du contrôle de version. Quand deux développeurs modifient le code dans des directions différentes, il faut au final faire un choix sémantique. Les CRDT risquent alors de produire du code aberrant
Il existe déjà beaucoup d’outils qui apportent une meilleure UX de merge au-dessus de Git, et la facilité de
cherry-pickou derevertreste l’un des avantages de GitPar exemple, si une branche supprime une constante et qu’une autre l’utilise, le code casse
Comme les conflits de Git sont le plus souvent des problèmes syntaxiques, une approche plus intelligente de semantic merge ou de type CRDT pourrait quand même aider
Par exemple, pour suivre des noms de fichiers, des propriétés ou des hashes, on peut utiliser un OR-set(https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type).
En revanche, la résolution des conflits doit toujours être traitée dans une interface externe
Je ne comprends pas très bien pourquoi l’accent est mis sur les CRDT
Le problème sémantique des conflits reste entier. En plus, les changements risquent d’apparaître entrelacés (interleave), ce qui peut être encore plus déroutant
Je suis un partisan du tout-rebase. Il faut éviter les commits de merge, et chaque commit devrait être une unité autonome. Je considère Gitflow comme un antipattern
Jujutsu et Gerrit résolvent bien le vrai problème de Git : la « gestion des chaînes de commits basées sur le feedback de review »
Git réapplique des snapshots, donc un même travail existe en quelque sorte deux fois. À l’inverse, Pijul fonctionne en unités de patch, ce qui produit le même résultat indépendamment de l’ordre. C’est, à mon sens, la vraie unité de travail indépendante
Il est possible d’annuler (undo) uniquement certains commits même dans un état conflictuel. On peut donc imaginer une structure plus flexible que Git
En pratique, seul le résultat final compte souvent. Mélanger intelligemment avec du squash merge est plus réaliste
Mais certains problèmes nécessitent intrinsèquement des conflits. Par exemple, dans les éditeurs collaboratifs où les caractères se mélangent, on peut même obtenir un résultat pire
Ce projet semble prolonger les idées de Codeville, créé autrefois par Bram
Codeville est apparu au début des années 2000, à l’époque du boom des DVCS, et utilisait un stockage et merge fondés sur le weave. C’est une idée antérieure aux CRDT d’une dizaine d’années, mais la filiation est naturelle
C’est agréable de voir que Bram continue de s’attaquer à ce problème avec de nouvelles tentatives
arxiv:2002.09511
Je ne suis pas d’accord avec l’affirmation « il n’existe pas encore de VCS fondé sur les CRDT »
Pijul existe déjà, et c’est un projet sur lequel des experts ont investi des milliers d’heures
Le projet est encore en phase expérimentale depuis 6 ans, et même après avoir moi-même ouvert un ticket il y a 4 ans, rien n’a encore été pris en compte
Pijul est un VCS développé avec lui-même, donc il n’utilise pas GitHub
pijul pull -a, et dans ce cas je reclone simplement. Je me demande s’il existe un pull pour mettre à jour le suivi sans çamanana.py est un code Python sans dépendances de 473 lignes
L’implémentation réelle ne fait qu’environ 240 lignes, le reste étant du code de test. C’est simple, mais impressionnant
Quand on pense à l’affaire left-pad dans l’écosystème JS, on se dit que Python aussi gagnerait à avoir davantage de petits packages responsables
Un système comme celui-ci devrait être conçu après avoir analysé la nature des conflits de merge selon la taille des équipes
Il faut regarder quels problèmes rencontrent respectivement des équipes de 1, 10, 100 ou 1000 personnes, et aussi comment le développement fondé sur des agents pourrait changer la donne
D’après mon expérience, entre 1 et 100 personnes, les équipes découpent généralement le code en sous-arbres, ce qui fait qu’il y a très peu de conflits.
Avec plus d’agents, 100 personnes pourraient peut-être se comporter comme 1000, mais pour l’instant, on a surtout l’impression que la solution arrive avant le problème réel
Aujourd’hui, il suffit souvent de laisser Codex gérer les conflits de merge, donc l’intérêt d’un nouveau VCS diminue
Git a été conçu pour les grandes équipes, et à l’ère des agents, l’automatisation des processus peut suffire comme réponse
Le vrai problème vient plutôt des goulots d’étranglement des bibliothèques partagées ou des politiques de restriction d’accès
Plus que les conflits, le vrai problème, c’est la scalabilité de Git
La taille des dépôts et le rythme des changements atteignent leurs limites. Il faut repenser l’ensemble du serveur, du client et du protocole
Personnellement, je ne vois pas très bien quel problème concret ce système résout
C’est intéressant sur le plan abstrait, mais en pratique, jj est bien plus utile que Git
Je pense que l’étape suivante ne sera pas un contrôle de version au niveau des fichiers, mais au niveau de l’AST.
Il y a déjà eu des tentatives comme LightTable ou Dark, et ce serait intéressant d’expérimenter ce type de VCS fondé sur des arbres