Nach meinem Verständnis ist SVN einfach zu verzweigen. Schwer zu verschmelzen. Warum das? Gibt es einen Unterschied, wie sie verschmelzen?
Nach meinem Verständnis ist SVN einfach zu verzweigen. Schwer zu verschmelzen. Warum das? Gibt es einen Unterschied, wie sie verschmelzen?
Antworten:
In meiner Antwort zum Stapelüberlauf finden Sie eine sehr konkrete Situation, in der Mercurial (und Git) problemlos zusammengeführt werden und in der Subversion einen falschen Konflikt darstellt. Die Situation ist ein einfaches Refactoring, das in einem Zweig ausgeführt wird, in dem Sie einige Dateien umbenennen.
In Bezug auf die Antwort des Hammers gibt es dort eine Reihe von Missverständnissen:
Subversion, Mercurial und Git verfolgen alle repository-weiten Snapshots des Projekts. Die Bezeichnung " Versionen" , " Überarbeitungen" oder " Änderungssätze" macht keinen Unterschied. Sie sind alle logisch atomare Schnappschüsse einer Reihe von Dateien.
Die Größe Ihrer Commits spielt beim Zusammenführen keine Rolle. Alle drei Systeme werden mit dem Standard-Drei-Wege-Zusammenführungsalgorithmus zusammengeführt, und die Eingaben für diesen Algorithmus sind
Es spielt keine Rolle, wie die beiden Zweigversionen erstellt wurden. Sie können seit der Vorgängerversion 1000 kleine Commits verwendet haben, oder Sie können 1 Commit verwendet haben. Alles, was zählt, ist die endgültige Version der Dateien. (Ja, das ist überraschend! Ja, viele DVCS-Guides verstehen das fürchterlich falsch.)
Er bringt auch einige gute Punkte zu den Unterschieden vor:
Subversion hat einige „Voodoo“ , wo Sie verschmelzen können /trunk
in, sagen wir, /branches/foo
. Mercurial und Git verwenden dieses Modell nicht - Verzweigungen werden stattdessen direkt in der Historie modelliert. Die Geschichte wird daher zu einem gerichteten azyklischen Graphen, anstatt linear zu sein. Dies ist ein viel einfacheres Modell als das von Subversion verwendete, und dies erspart eine Reihe von Eckfällen.
Sie können eine Zusammenführung leicht verzögern oder sogar jemand anderem überlassen, damit umzugehen. Wenn hg merge
Sie eine Menge Konflikte haben, können Sie Ihren Kollegen darum bitten hg pull
, und dann hat er genau den gleichen Zustand. Er kann also hg merge
Konflikte besser lösen als Sie.
Dies ist bei Subversion sehr schwierig, da Sie ein Update durchführen müssen, bevor Sie ein Commit durchführen können. Sie können die Änderungen auf dem Server nicht einfach ignorieren und weiterhin in Ihrer eigenen anonymen Filiale festschreiben. Im Allgemeinen zwingt Subversion Sie, mit einer schmutzigen Arbeitskopie herumzuspielen, wenn Sie svn update
. Dies ist riskant, da Sie Ihre Änderungen nicht an einem sicheren Ort gespeichert haben. Mit Git und Mercurial können Sie zuerst ein Commit durchführen und dann nach Bedarf aktualisieren und zusammenführen.
Der wahre Grund, warum Git und Mercurial besser miteinander verschmelzen als Subversion, ist eine Frage der Implementierung. Es gibt Umbenennungskonflikte, mit denen Subversion einfach nicht umgehen kann, obwohl klar ist, wie die richtige Antwort lautet. Mercurial und Git erledigen das problemlos. Aber es gibt keinen Grund, warum Subversion diese Probleme nicht lösen könnte - eine Zentralisierung ist sicherlich nicht der Grund.
trunk
in SVN arbeiten. Mit einem DVCS können Sie ein Commit durchführen, ohne es zu teilen. In SVN wirkt sich dies svn commit
jedoch direkt auf andere aus, die an demselben Zweig arbeiten. Selbst wenn wir beide in einer Filiale in SVN arbeiten, kann ich meine Arbeit nicht aufgeben, ohne mich sofort mit Ihrer Arbeit verbinden zu müssen. Das macht Commits etwas beängstigend - was eine beängstigende Eigenschaft für ein Versionskontrollsystem ist! :-)
Das Hauptproblem liegt in der Art und Weise, wie diese Systeme eine versionierte Verzeichnisstruktur darstellen.
Das Grundkonzept von Subversion, um das sich das gesamte System dreht, ist das einer Version (oder, in svn lingo, "Revision"): eine Momentaufnahme einer Datei zu einem bestimmten Zeitpunkt. Solange der Verlauf perfekt linear ist, ist alles in Ordnung. Wenn Sie jedoch Änderungen aus zwei unabhängigen Entwicklungslinien zusammenführen müssen, muss svn die aktuellen Versionen von beiden vergleichen und dann einen Drei-Wege-Vergleich zwischen der letzten gemeinsam genutzten Version durchführen und die beiden Kopfversionen. Linien, die in einem der Köpfe, aber nicht im anderen, geändert erscheinen, können leicht aufgelöst werden. Linien, die in beiden Köpfen genau gleich stark voneinander abweichen, sind schwieriger, aber normalerweise machbar. Zeilen, die auf unterschiedliche Weise abweichen, sind das, was svn sagen lässt: "Ich kann das nicht herausfinden, Mensch, bitte lösen Sie das für mich."
Im Gegensatz dazu werden Git- und Mercurial-Tracks eher als Versionen geändert . Das gesamte Repository ist eine Baumstruktur von Änderungssätzen, die jeweils von einem übergeordneten Element abhängt, wobei ein übergeordnetes Änderungssatz eine beliebige Anzahl von untergeordneten Elementen haben kann und der Baumstamm ein leeres Verzeichnis darstellt. Mit anderen Worten, git / hg sagt "zuerst hatte ich nichts, dann wurde dieser Patch angewendet, dann dieser Patch usw.". Wenn Sie zwei Entwicklungslinien zusammenführen müssen, weiß git / hg nicht nur, wie jeder Kopf aktuell aussieht und wie die letzte gemeinsame Version aussah, sondern auch, wie der Übergang stattgefunden hat, was eine viel intelligentere Zusammenführung ermöglicht.
Eine andere Sache, die das Zusammenführen in einem DVCS erleichtert, ist eine indirekte Folge der Trennung der Konzepte von Festschreiben und Pushund alle Arten von Cross-Merges zwischen zwei beliebigen Klonen desselben Repositorys zu jeder Zeit zuzulassen. Bei svn neigen die Benutzer dazu, große Änderungsmengen mit häufig nicht zusammenhängenden Änderungen festzuschreiben, da ein Festschreiben auch eine Aktualisierung des zentralen Repositorys darstellt, die alle anderen Teammitglieder betrifft. Wenn du eine kaputte Version begehst, werden alle sauer auf dich sein. Da die meisten Setups einen vernetzten SVN-Server beinhalten, werden beim Festschreiben auch Daten über das Netzwerk gepumpt. Dies bedeutet, dass der Workflow durch das Festschreiben erheblich verzögert wird (insbesondere, wenn Ihre Arbeitskopie veraltet ist und Sie zuerst ziehen müssen). Bei git und mercurial findet das Festschreiben lokal statt, und da beide sehr effizient mit lokalen Dateisystemen umgehen, wird es normalerweise sofort beendet. Infolgedessen nehmen die Leute (sobald sie sich daran gewöhnt haben) kleine inkrementelle Änderungen vor und wenn es dann funktioniert, Push ein Dutzend oder so begeht auf einmal. Wenn dann die Zeit für die Zusammenführung gekommen ist, verfügt der SCM über viel detailliertere Informationen und kann Konflikte sicher und automatisch besser lösen.
Und dann sind da noch die netten Details, die die Sache noch einfacher machen:
hg mv
oder hg addremove --similarity...
), Git verwendet Heuristik, aber beide behandeln Umbenennungen . Ich kann sogar mit 1 String Unterschied in zusammengeführten Dateien einen Baumkonflikt bekommen! Sie müssen einige Subversion-Aspekte noch einmal lernen, sorry.
rename a b
wie copy a b; remove a
und beide tun es in einem Atom begehen. Der Unterschied im Zusammenführungsverhalten ergibt sich aus der unterschiedlichen Behandlung von Eckfällen und aus Subversion, die mehr Zusammenführungen als Mercurial und Git zulässt. Schließlich erkennt Git Umbenennungen beim Zusammenführen und Protokollieren - wir denken darüber nach, dies auch in Mercurial hinzuzufügen.