- Manyana ist ein von Bram Cohen entwickelter CRDT-basierter Prototyp für Versionsverwaltung, der einen neuen Ansatz präsentiert, um Merge-Konflikte zu eliminieren und die Historie strukturell zu bewahren
- Durch den Einsatz von CRDTs (Conflict-Free Replicated Data Types) gelingen Merges immer, und Konflikte werden lediglich als informative Markierungen behandelt, sodass Nutzer Änderungen klar erkennen können
- Im Mittelpunkt stehen Persistenz der Zeilenreihenfolge, nicht blockierende Merges und in die Struktur eingebettete Historie; selbst beim Rebase werden bestehende Aufzeichnungen nicht zerstört
- Es handelt sich um eine Demo-Implementierung mit rund 470 Zeilen Python-Code; der gesamte Code und die Designdokumentation sind als Public Domain auf GitHub veröffentlicht
- Ein experimentelles Beispiel für ein Versionsverwaltungsmodell der nächsten Generation ohne fehlgeschlagene Merges, das über die Grenzen von Git hinausgeht
Manyana: Eine konsistente Vision für die Zukunft der Versionsverwaltung
- Manyana ist ein von Bram Cohen veröffentlichtes CRDT-basiertes Prototypsystem für Versionsverwaltung, das versucht, das Merge-Konfliktproblem bestehender Systeme zu lösen
- CRDTs garantieren, dass Merges immer erfolgreich sind, und behandeln Konflikte als informative Markierungen, damit Nutzer die tatsächlichen Änderungen klar nachvollziehen können
- Dieser Ansatz hat drei Kerneigenschaften: Persistenz der Zeilenreihenfolge, nicht blockierende Konfliktbehandlung und Einbettung der Historie in die Struktur
- Selbst beim Rebase bleibt die bestehende Historie erhalten, und auch komplexe Merge-Strukturen ohne einen einzigen gemeinsamen Vorfahren lassen sich stabil verarbeiten
- Manyana ist eine Demo-Implementierung mit rund 470 Zeilen Python-Code; die Designdokumentation und der Code sind als Public Domain auf GitHub veröffentlicht
Kern des CRDT-basierten Ansatzes
- CRDTs sorgen dafür, dass Merges immer erfolgreich sind, und bieten eventual consistency, also dass unabhängig von der Reihenfolge der Merges immer dasselbe Ergebnis entsteht
- Selbst wenn mehrere Nutzer unabhängig voneinander erstellte Branches in beliebiger Reihenfolge zusammenführen, bleibt das Ergebnis identisch
- Durch die Persistenz der Zeilenreihenfolge bleibt die einmal festgelegte Reihenfolge von Code, der an derselben Stelle eingefügt wurde, auch später erhalten
- Dadurch wird verhindert, dass Konfliktbereiche je nach Branch unterschiedlich aufgelöst werden
- Konflikte dienen nur noch als informative Markierungen und blockieren den Merge nicht
- Ein Merge-Ergebnis wird immer erzeugt; Konflikte werden als „gleichzeitig an benachbarten Stellen geänderte Bereiche“ markiert
- Durch die Nachverfolgung von Urheber und Art jeder Änderung entstehen nützliche Konfliktmarkierungen
- Die Historie ist in die Struktur eingebettet
- Der Zustand wird über eine „weave“-Struktur dargestellt, die alle Zeilen einer Datei enthält und für jede Zeile Metadaten über den Zeitpunkt von Hinzufügung und Löschung speichert
- Beim Merge werden einfach zwei Zustände als Eingabe verwendet; ein gemeinsamer Vorfahre oder DAG-Traversierung ist nicht nötig, und dennoch entsteht immer das korrekte Ergebnis
Verbesserte Konfliktmarkierungen
- Bestehende Versionsverwaltungssysteme zeigen bei Konflikten meist nur zwei Codeblöcke nebeneinander, sodass Nutzer die Unterschiede selbst erschließen müssen
- Manyana kennzeichnet jeden Konfliktbereich explizit als „gelöscht“ oder „hinzugefügt“ und zeigt, wer welche Änderung vorgenommen hat
- Wenn zum Beispiel ein Nutzer eine Funktion löscht und ein anderer innerhalb dieser Funktion eine Zeile hinzufügt, trennt Manyana die Struktur dieser Änderungen klar voneinander
- Dadurch können Nutzer statt zweier Codeblöcke direkt Bedeutung und Kontext der Änderungen erfassen
Rebase neu definiert
- In einem CRDT-basierten System zerstört Rebase die Historie nicht
- Ein klassisches Rebase stapelt Commits auf einer neuen Basis neu und erzeugt dadurch eine fiktive Historie
- In Manyana wird derselbe Effekt erzielt, aber die gesamte ursprüngliche Historie bleibt erhalten
- Dafür genügt es, dem DAG lediglich eine Annotation für den „primären Vorfahren“ (primary ancestor) hinzuzufügen
- Dieser Ansatz funktioniert auch bei Merge-Strukturen ohne gemeinsamen Vorfahren stabil und vermeidet das Scheitern klassischer 3-Wege-Merges
Aktueller Stand des Projekts
- Manyana ist kein vollständiges Versionsverwaltungssystem, sondern eine Demo-Implementierung, die auf Ebene einzelner Dateien arbeitet
- Sie besteht aus rund 470 Zeilen Python-Code
- Cherry-pick und lokales Undo sind noch nicht implementiert, im README wird jedoch die geplante Richtung beschrieben
- Das Projekt belegt, dass CRDT-basierte Versionsverwaltung UX-Probleme lösen kann, und liefert bessere Ergebnisse als bestehende Werkzeuge
- Der gesamte Code wird als Public Domain veröffentlicht, und die vollständige Designdokumentation ist im GitHub-README enthalten
Zusammenfassung der Community-Reaktionen
- Ein Nutzer merkte positiv an, dass Git zwar seit mehr als zehn Jahren im Einsatz sei, es aber ein neues Paradigma für Versionsverwaltung brauche, und bewertete Manyanas Ansatz entsprechend wohlwollend
- Er wies darauf hin, dass die Idee immer erfolgreicher Merges nicht intuitiv sei, und bat um zusätzliche Beispiele und Erklärungen
- Er zeigte Interesse an den Rebase-Verbesserungen und erwähnte, dass er in einem privaten Projekt Merges über Zwischen-Branches verwaltet
- Als Grenzen von Git nannte er den Umgang mit Binärdateien, Verwirrung bei der Unterscheidung linker und rechter Branches sowie fehlende Zusammenfassungen großer Codeänderungen
- Er schlug vor, dass zukünftige Versionsverwaltung token-aware sein oder Plugins je nach Sprache und Dateiformat unterstützen könnte
- Ein weiterer Nutzer fragte, ob Manyana eine ähnliche Grundlage wie Pijul oder Darcs habe, und bat um einen Vergleich mit den Performance-Problemen von Darcs und dem aktuellen Stand von Pijul
Fazit
- Manyana ist eine praktische Demo zur Anwendung von CRDTs auf Versionsverwaltung und denkt Konfliktbehandlung und Rebase grundlegend neu
- Eine Struktur ohne fehlgeschlagene Merges, die Informatisierung von Konflikten und die strukturelle Einbettung der Historie zeigen eine Designrichtung, die über die Grenzen des bestehenden Git-Modells hinausgeht
- Es ist noch kein vollständiges System, aber ein bedeutender Ausgangspunkt als Blaupause für Versionsverwaltungssysteme der nächsten Generation
1 Kommentare
Hacker-News-Kommentare
Ich denke, die Art, wie Merges dargestellt werden, ist ein anderes Problem als die Darstellung der Historie
Ich mag auch die Standard-Merge-UI von Git nicht und nutze deshalb p4merge. Das Tool zeigt vier Panels (links, rechts, gemeinsame Basis, Ergebnis), sodass man Ursache des Konflikts und den Lösungsweg auf einen Blick sehen kann
Ich glaube nicht, dass man dafür gleich das VCS selbst wechseln muss
merge.conflictStyleauf"diff3"oder"zdiff3"zusätzlich die Basisversion anzeigen lassenSo kann man allein anhand der Konfliktmarker ableiten, welche Seite neuen Code hinzugefügt hat
Ich war einmal erstaunt, in einem Podcast zu hören, wie ein Gast, der ein neues VCS gebaut hatte, das Diff-Speicherverfahren von Git falsch verstanden hat. Wenn man selbst nach Jahren an Projekten nicht einmal die Grundkonzepte nachschlägt, merkt man, dass der NIH-Geist (Neuerfindung) noch sehr lebendig ist
Wenn man das allerdings auf SCM-Ebene verarbeitet, hat man den Vorteil, dass sich das System die Merge-Entscheidungen des Nutzers merken kann. Git hat in solchen Bereichen einige Edge Cases
Ich bin nicht sicher, ob es überhaupt gut ist, wenn Merges nie fehlschlagen
Ein fehlgeschlagener Merge ist oft nicht nur ein Positionskonflikt, sondern ein Signal für einen semantischen Konflikt. Solche Fälle muss man manuell behandeln
Ich denke nicht, dass CRDTs gut für Versionsverwaltung geeignet sind
Konflikte sind ein wesentlicher Bestandteil von Versionsverwaltung. Wenn zwei Entwickler Code in unterschiedliche Richtungen ändern, braucht es am Ende eine semantische Entscheidung. CRDTs erzeugen in solchen Situationen leicht unsinnigen Code
Es gibt bereits viele Tools, die auf Git aufsetzen und eine bessere Merge-UX bieten, und dass cherry-pick oder revert einfach sind, ist ebenfalls eine Stärke von Git
Wenn zum Beispiel in einem Branch eine Konstante gelöscht wird und ein anderer Branch diese Konstante verwendet, geht der Code kaputt
Die Konflikte von Git sind meist syntaktischer Natur, daher könnten intelligentere semantic merges oder ein CRDT-Ansatz hilfreich sein
Beispielsweise ließen sich für Dateinamen, Attribute oder Hashes OR-Sets(https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) verwenden.
Die eigentliche Konfliktauflösung müsste aber weiterhin über ein externes Interface erfolgen
Ich verstehe nicht ganz, warum der Fokus so stark auf CRDTs liegt
Das semantische Problem von Konflikten bleibt weiterhin bestehen. Im Gegenteil könnten Änderungen noch verwirrender ineinander verschachtelt (interleaved) erscheinen
Ich bin ein Rebase-Zentrist. Merge-Commits sollte man vermeiden, und jeder Commit sollte eine unabhängige Einheit sein. Gitflow halte ich für ein Antipattern
Jujutsu und Gerrit lösen das eigentliche Problem von Git, nämlich das „Verwalten von Commit-Ketten auf Basis von Review-Feedback“, deutlich besser
Git wendet Snapshots erneut an, daher existiert dieselbe Arbeit gewissermaßen zweimal. Pijul arbeitet dagegen auf Patch-Ebene und liefert unabhängig von der Reihenfolge dasselbe Ergebnis. Das ist für mich eine wirklich unabhängige Arbeitseinheit
Selbst in einem Zustand mit Konflikten kann man bestimmte Commits rückgängig machen (undo). So könnte man eine flexiblere Struktur als in Git bekommen
In der Praxis zählt oft nur das Endergebnis. Eine sinnvolle Mischung mit squash merge ist realistischer
Manche Probleme brauchen ihrem Wesen nach Konflikte. Wie beim Durcheinandergeraten von Zeichen in kollaborativen Editoren kann das Ergebnis sogar noch schlechter werden
Dieses Projekt wirkt auf mich wie eine Weiterentwicklung der Ideen aus Codeville, das Bram früher gebaut hat
Codeville entstand während des DVCS-Booms Anfang der 2000er und nutzte weave-basierte Speicherung und Merges. Das Konzept ist CRDTs um etwa zehn Jahre voraus, führt die Idee aber auf natürliche Weise weiter
Es freut mich, dass Bram sich immer noch mit diesem Problem beschäftigt und neue Ansätze ausprobiert
arxiv:2002.09511
Ich stimme der Aussage „Es gibt noch kein CRDT-basiertes VCS“ nicht zu
Pijul existiert bereits, und daran haben Experten tausende Stunden gearbeitet
Das Projekt ist seit 6 Jahren experimentell, und obwohl ich vor 4 Jahren selbst ein Issue eröffnet habe, wurde es noch nicht übernommen
Pijul ist ein VCS, das mit sich selbst entwickelt wird, und nutzt daher nicht GitHub
pijul pull -aKonflikte und klone dann einfach neu. Ich frage mich, ob es so etwas wie einen Pull für Tracking-Updates gibtmanana.py ist Python-Code ohne Abhängigkeiten mit 473 Zeilen
Die eigentliche Implementierung umfasst nur etwa 240 Zeilen, der Rest sind Tests. Einfach, aber beeindruckend
Wenn man an den left-pad-Vorfall im JS-Ökosystem denkt, sollte es in Python mehr solcher kleinen, verantwortungsvoll gepflegten Pakete geben
Solche Systeme sollte man anhand der Muster von Merge-Konflikten je nach Teamgröße entwerfen
Man müsste betrachten, welche Probleme Teams mit 1, 10, 100 oder 1000 Personen jeweils haben und wie agentenbasierte Entwicklung das verändert
Nach meiner Erfahrung gibt es in Teams mit 1 bis 100 Leuten kaum Konflikte, weil der Code in Subtrees pro Team aufgeteilt wird.
Mit mehr Agenten könnten 100 Menschen zwar wie 1000 wirken, aber im Moment fühlt es sich so an, als sei hier die Lösung vor dem eigentlichen Problem da
Heute reicht es oft schon, Codex einfach den Merge-Konflikt lösen zu lassen, sodass der Anreiz sinkt, ein neues VCS einzuführen
Git wurde für große Teams entworfen, und im Zeitalter der Agenten kann man vieles einfach mit Prozessautomatisierung abfangen
Probleme entstehen eher durch Bottlenecks bei Shared Libraries oder restriktive Zugriffsrichtlinien
Ein größeres Problem als Konflikte ist die Skalierbarkeit von Git
Repository-Größe und Änderungsrate stoßen an Grenzen. Man braucht eine Neugestaltung von Server, Client und Protokoll insgesamt
Ich persönlich verstehe nicht ganz, welches Problem dieses System eigentlich lösen soll
Als abstrakte Idee ist es interessant, aber in der Praxis ist jj viel nützlicher als Git
Der nächste Schritt wäre aus meiner Sicht ein System für Versionsverwaltung nicht auf Datei-, sondern auf AST-Ebene.
Es gab Ansätze wie LightTable oder Dark, und es wäre spannend, mit einem solchen baum-basierten VCS zu experimentieren