Warum ist das Verzweigen und Zusammenführen in Mercurial einfacher als in Subversion?

92

Das Behandeln mehrerer Zusammenführungen in Zweigen in Subversion oder CVS ist nur eines der Dinge, die erlebt werden müssen. Es ist außerordentlich einfacher, Zweige und Zusammenführungen in Mercurial (und wahrscheinlich jedem anderen verteilten System) zu verfolgen, aber ich weiß nicht warum. Weiß jemand anderes?

Meine Frage ergibt sich aus der Tatsache, dass Sie mit Mercurial eine ähnliche Arbeitspraxis wie das zentrale Repository von Subversions / CVS anwenden können und alles einwandfrei funktioniert. Sie können mehrere Zusammenführungen in demselben Zweig durchführen und benötigen keine endlosen Papierfetzen mit Festschreibungsnummern und Tag-Namen.

Ich weiß, dass die neueste Version von Subversion die Möglichkeit hat, Zusammenführungen zu Zweigen zu verfolgen, sodass Sie nicht den gleichen Aufwand haben, aber es war eine große und bedeutende Entwicklung auf ihrer Seite und es tut immer noch nicht alles, was das Entwicklungsteam tun würde mag es zu tun.

Es muss einen grundlegenden Unterschied in der Funktionsweise geben.

Nick Pierpoint
quelle

Antworten:

115

In Subversion (und CVS) ist das Repository in erster Linie. In Git und Mercurial gibt es nicht wirklich das Konzept eines Repository auf die gleiche Weise; Hier stehen Veränderungen im Mittelpunkt.

+1

Der Aufwand bei CVS / SVN beruht auf der Tatsache, dass sich diese Systeme nicht an die Elternschaft von Änderungen erinnern. In Git und Mercurial kann ein Commit nicht nur mehrere Kinder haben, sondern auch mehrere Eltern!

Dies kann leicht mit einem der grafischen Werkzeuge gitkoder beobachtet werden hg view. Im folgenden Beispiel wurde Zweig Nr. 2 bei Festschreibung A von Nr. 1 gegabelt und wurde seitdem einmal zusammengeführt (bei M, zusammengeführt mit Festschreibung B):

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

Beachten Sie, wie A und B zwei Kinder haben, während M zwei Eltern hat . Diese Beziehungen werden im Repository aufgezeichnet . Angenommen, der Betreuer von Zweig Nr. 2 möchte jetzt die neuesten Änderungen von Zweig Nr. 1 zusammenführen. Er kann einen Befehl wie den folgenden ausgeben:

$ git merge branch-1

und das Tool erkennt automatisch, dass die Basis B ist - da sie in Commit M, einem Vorfahren der Spitze von # 2, aufgezeichnet wurde - und dass alles, was zwischen B und C passiert ist, zusammengeführt werden muss. CVS zeichnet diese Informationen nicht auf , noch SVN vor Version 1.5. In diesen Systemen würde der Graph folgendermaßen aussehen:

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

wobei M nur ein gigantisches "gequetschtes" Commit von allem ist, was zwischen A und B passiert ist, das auf M angewendet wird. Beachten Sie, dass nach Abschluss der Tat keine Spur mehr übrig ist (außer möglicherweise in von Menschen lesbaren Kommentaren), wo M. stammte nicht davon, wie viele Commits zusammengebrochen waren, was die Geschichte viel undurchdringlicher machte.

Noch schlimmer ist, wird ein zweite merge Durchführung ein Albtraum: ein , was die Zusammenführung Basis zum Zeitpunkt der ersten Zusammenführung war , um herauszufinden , hat (und man hat zu wissen , dass es eine Zusammenführung in erster Linie gewesen!), Dann vorhanden , dass Informationen an das Tool, damit es nicht versucht, A..B über M wiederzugeben. All dies ist schwierig genug, wenn Sie in enger Zusammenarbeit arbeiten, aber in einer verteilten Umgebung einfach unmöglich.

Ein (verwandtes) Problem ist, dass es keine Möglichkeit gibt, die Frage zu beantworten: "Enthält X B?" Dabei ist B eine potenziell wichtige Fehlerbehebung. Warum also nicht einfach diese Informationen im Commit aufzeichnen, da sie zum Zeitpunkt der Zusammenführung bekannt sind ?

P.-S. - Ich habe keine Erfahrung mit SVN 1.5+ Merge-Aufnahmefähigkeiten, aber der Workflow scheint viel ausgefeilter zu sein als in den verteilten Systemen. Wenn dies tatsächlich der Fall ist, liegt dies wahrscheinlich daran, dass - wie im obigen Kommentar erwähnt - der Fokus eher auf der Organisation des Repositorys als auf den Änderungen selbst liegt.

Damien Diederen
quelle
6
SVN 1.5+ würde in der Tat eine SVN-Eigenschaft auf das Zusammenführungs-Commit M setzen, in der die darin enthaltenen zusammengeführten Commits aufgelistet sind, mit anderen Worten AB. Sie haben also die gleichen Informationen.
Simon D
So'ne Art. Technisch gesehen ähnelt das Merge-Tracking von SVN dem, was Git als „Cherry-Picking“ bezeichnet, mit zusätzlicher Magie, um es dem Benutzer zu erleichtern. Es unterscheidet sich semantisch von dem, was Git, Hg und Bzr beim Zusammenführen tun. Ich denke, es macht in der Praxis keinen großen Unterschied, solange Sie sich nicht für die DAG interessieren ( eagain.net/articles/git-for-computer-scientists ).
Damien Diederen
2
Wehe, dass es keine +100 Taste gibt. Vielen Dank.
Charlie Flowers
Ich gehe davon aus, dass die SVN 1.5-Funktion, über die Sie sprechen, die Verwendung der svn:mergeinfoEigenschaft ist.
MatrixFrog
@MatrixFrog: Ja, genau das svn:mergeinfomacht es.
Sleske
12

Weil Subversion (mindestens Version 1.4 und niedriger) nicht verfolgt, was zusammengeführt wurde. Bei Subversion ist das Zusammenführen im Grunde dasselbe wie jedes Festschreiben, während bei anderen Versionskontrollen wie Git die zusammengeführten Elemente gespeichert werden.

htanata
quelle
7

Unberührt von den bereits bereitgestellten Antworten bot Hg überlegene Zusammenführungsfunktionen, da beim Zusammenführen von Änderungen mehr Informationen verwendet werden ( hginit.com ):

Wenn ich beispielsweise eine Funktion ein wenig ändere und sie dann an einen anderen Ort verschiebe, erinnert sich Subversion nicht wirklich an diese Schritte. Wenn es also Zeit zum Zusammenführen wird, könnte es sein, dass eine neue Funktion aus heiterem Himmel auftaucht . Während Mercurial sich diese Dinge separat merken wird: Funktion geändert, Funktion verschoben, was bedeutet, dass wenn Sie diese Funktion auch ein wenig geändert haben, es viel wahrscheinlicher ist, dass Mercurial unsere Änderungen erfolgreich zusammenführt.

Natürlich ist es auch ein großer Gewinn, sich daran zu erinnern, was zuletzt zusammengeführt wurde (der Punkt, auf den sich die meisten Antworten hier beziehen).

Beide Verbesserungen sind jedoch fraglich, da Subversion 1.5+ zusätzliche Zusammenführungsinformationen in Form von Subversionseigenschaften speichert: Da diese Informationen verfügbar sind, gibt es keinen offensichtlichen Grund, warum Subversion Merge die Zusammenführung nicht so erfolgreich implementieren konnte wie Hg oder Git. Ich weiß zwar nicht, ob dies der Fall ist, aber es klingt sicherlich so, als ob Subversion-Entwickler auf dem Weg sind, dieses Problem zu umgehen.

Tomislav Nakic-Alfirevic
quelle
4

Ich nehme an, dies könnte teilweise daran liegen, dass Subversion die Idee eines zentralen Servers zusammen mit einer absoluten Zeitlinie von Revisionen hat. Mercurial ist wirklich verteilt und hat keinen solchen Bezug zu einer absoluten Zeitlinie. Auf diese Weise können Mercurial-Projekte kompliziertere Hierarchien von Zweigen bilden, um Funktionen und Testzyklen nach Unterprojekten hinzuzufügen. Die Teams müssen jedoch jetzt viel aktiver über Zusammenführungen auf dem Laufenden bleiben, um auf dem neuesten Stand zu bleiben, da sie nicht einfach auf "Aktualisieren" klicken und damit fertig werden können .

Der böse Andy
quelle
3

In Subversion (und CVS) ist das Repository in erster Linie. In Git und Mercurial gibt es nicht wirklich das Konzept eines Repository auf die gleiche Weise; Hier stehen Veränderungen im Mittelpunkt.

Ich habe auch nicht viel darüber nachgedacht, wie Sie es implementieren würden, aber mein Eindruck (basierend auf bitterer Erfahrung und viel Lesen) ist, dass dieser Unterschied das Zusammenführen und Verzweigen in nicht auf Repositorys basierenden Systemen so viel einfacher macht.

Stephen Darlington
quelle
1

Ich habe nur Erfahrung mit Subversion, aber ich kann Ihnen sagen, dass der Zusammenführungsbildschirm in TortoiseSVN schrecklich kompliziert ist. Zum Glück enthalten sie einen Trockenlaufknopf, damit Sie sehen können, ob Sie es richtig machen. Die Komplikation liegt in der Konfiguration dessen, was Sie wo zusammenführen möchten. Sobald Sie das für die Zusammenführung eingerichtet haben, geht die Zusammenführung im Allgemeinen gut. Anschließend müssen Sie alle Konflikte lösen und Ihre zusammengeführte Arbeitskopie in das Repository übertragen.

Wenn Mercurial die Konfiguration der Zusammenführung vereinfachen kann, kann ich sagen, dass dies die Zusammenführung zu 100% einfacher macht als Subversion.

RedWolves
quelle