Zusammenführen: Hg / Git vs. SVN

144

Ich habe oft gelesen, dass Hg (und Git und ...) besser zusammengeführt werden können als SVN, aber ich habe noch nie praktische Beispiele dafür gesehen, wo Hg / Git etwas zusammenführen kann, wo SVN fehlschlägt (oder wo SVN manuell eingegriffen werden muss). Könnten Sie ein paar Schritt-für-Schritt-Listen mit Verzweigungs- / Änderungs- / Festschreibungs- / ... Operationen veröffentlichen, die zeigen, wo SVN fehlschlagen würde, während Hg / Git glücklich weitergeht? Praktische, nicht sehr außergewöhnliche Fälle bitte ...

Einige Hintergrundinformationen: Wir haben ein paar Dutzend Entwickler, die mit SVN an Projekten arbeiten, wobei sich jedes Projekt (oder eine Gruppe ähnlicher Projekte) in einem eigenen Repository befindet. Wir wissen, wie man Release- und Feature-Zweige anwendet, damit wir nicht sehr oft auf Probleme stoßen (dh wir waren dort, aber wir haben gelernt, Joels Probleme zu überwinden, dass "ein Programmierer dem gesamten Team ein Trauma verursacht"). oder "sechs Entwickler für zwei Wochen benötigen, um einen Zweig wieder zu integrieren"). Wir haben Release-Zweige, die sehr stabil sind und nur zum Anwenden von Bugfixes verwendet werden. Wir haben Trunks, die stabil genug sein sollten, um innerhalb einer Woche eine Veröffentlichung erstellen zu können. Und wir haben Feature-Zweige, an denen einzelne Entwickler oder Gruppen von Entwicklern arbeiten können. Ja, sie werden nach der Wiedereingliederung gelöscht, damit das Repository nicht überfüllt ist. ;)

Deshalb versuche ich immer noch, die Vorteile von Hg / Git gegenüber SVN zu finden. Ich würde gerne praktische Erfahrungen sammeln, aber es gibt noch keine größeren Projekte, die wir auf Hg / Git umstellen könnten. Daher spiele ich nur mit kleinen künstlichen Projekten, die nur wenige zusammengesetzte Dateien enthalten. Und ich suche nach einigen Fällen, in denen Sie die beeindruckende Kraft von Hg / Git spüren können, da ich bisher oft darüber gelesen habe, sie aber selbst nicht gefunden habe.

stmax
quelle
2
Ich denke, Sie sollten auf genaue Duplikate achten : stackoverflow.com/questions/43995/… stackoverflow.com/questions/459891/…
P Shved
11
Ich hatte bereits den ersten gelesen, der andere war neu. Aber sie sind bereits 1-2 Jahre alt und scheinen sich hauptsächlich mit Problemen vor SVN-1.5 zu befassen (bei denen SVN noch kein Merge-Tracking hatte).
stmax
2
Nur ein Kommentar, den Sie Bazaar auch mit git / hg als einem anderen DVCS zusammenfassen können, das die folgenden Probleme korrekt behandelt. Und da Sie erwähnt haben, dass Sie versuchen, Vorteile zu finden: Ein einfacher logistischer Vorteil von git / hg / bzr ist, dass Zweige nicht global sind wie bei svn. Sie müssen nicht 67 Filialen sehen, wenn sich nur ein paar für Sie bewerben. Jeder erledigt seine Arbeit in "privaten" Filialen und nutzt dann die hervorragende Zusammenführungsfunktion, um wieder zusammenzuführen, ohne zu schwitzen, ob die Zusammenführung in 99% der Fälle funktionieren wird.
Wadesworld
5
@wade: sehen Sie "private" Filialen als Vorteil in einem Unternehmensumfeld? Ich mache mir Sorgen um Backups. Ich habe oft Feature-Zweige, die 1-2 Monate vor der Wiedereingliederung leben ..
stmax
9
@stmax: Ein berechtigtes Anliegen. Was Sie jedoch in vielen Unternehmensumgebungen mit Subversion feststellen, ist, dass die Leute beim Einchecken warten, bis ihr Code perfekt ist, und Sie dort die gleiche Gefährdung haben.
Wadesworld

Antworten:

91

Ich verwende Subversion nicht selbst, aber aus den Versionshinweisen für Subversion 1.5: Merge-Tracking (grundlegend) geht hervor, dass es die folgenden Unterschiede zur Funktionsweise von Merge-Tracking in Voll- DAG- Versionskontrollsystemen wie Git oder Mercurial gibt.

  • Das Zusammenführen von Trunk zu Branch unterscheidet sich vom Zusammenführen von Branch zu Trunk: Aus irgendeinem Grund erfordert das Zusammenführen von Trunk zu Branch die --reintegrateOption to svn merge.

    In verteilten Versionskontrollsystemen wie Git oder Mercurial gibt es keinen technischen Unterschied zwischen Trunk und Branch: Alle Zweige werden gleich erstellt (es kann jedoch soziale Unterschiede geben). Das Zusammenführen in beide Richtungen erfolgt auf die gleiche Weise.

  • Sie müssen eine neue -g( --use-merge-history) Option für die Zusammenführungsverfolgung bereitstellen svn logund svn blamediese berücksichtigen.

    In Git und Mercurial wird das Merge-Tracking automatisch berücksichtigt, wenn Verlauf (Protokoll) und Schuld angezeigt werden. In Git können Sie anfordern, dem ersten Elternteil nur mit zu folgen --first-parent(ich denke, eine ähnliche Option gibt es auch für Mercurial), um Zusammenführungs-Tracking-Informationen in "zu verwerfen" git log.

  • svn:mergeinfoSoweit ich weiß, speichert Eigenschaft Informationen pro Pfad über Konflikte (Subversion basiert auf Änderungssätzen), während in Git und Mercurial einfach Objekte festgeschrieben werden, die mehr als ein übergeordnetes Element haben können.

  • Der Unterabschnitt "Bekannte Probleme" für die Zusammenführungsverfolgung in Subversion weist darauf hin, dass die wiederholte / zyklische / reflektierende Zusammenführung möglicherweise nicht ordnungsgemäß funktioniert. Dies bedeutet, dass bei den folgenden Historien die zweite Zusammenführung möglicherweise nicht das Richtige bewirkt ('A' kann Stamm oder Zweig sein, und 'B' kann Zweig oder Stamm sein):

    * --- * --- x --- * --- y --- * --- * --- * --- M2 <- A.
             \ \ /
              - * ---- M1 --- * --- * --- / <- B.
    

    In dem Fall, dass die obige ASCII-Grafik beschädigt wird: Zweig 'B' wird bei der Revision 'x' aus Zweig 'A' erstellt (gegabelt), später wird Zweig 'A' bei Revision 'y' in Zweig 'B' als zusammengeführt füge 'M1' zusammen und schließlich wird Zweig 'B' als Zweig 'M2' in Zweig 'A' zusammengeführt.

    * --- * --- x --- * ----- M1 - * --- * --- M2 <- A.
             \ / / 
              \ - * --- y --- * --- * --- / <- B.
    

    In dem Fall, dass die obige ASCII-Grafik beschädigt wird: Zweig 'B' wird bei der Revision 'x' aus Zweig 'A' erstellt (gegabelt), bei 'y' als 'M1' und später in Zweig 'A' zusammengeführt wieder in Zweig 'A' als 'M2' zusammengeführt.

  • Die Subversion unterstützt möglicherweise nicht den fortgeschrittenen Fall einer kreuz und quer verlaufenden Zusammenführung .

    * --- b ----- B1 - M1 - * --- M3
         \ \ / /
          \ X /
           \ / \ /
            \ - B2 - M2 - *
    

    Git bewältigt diese Situation in der Praxis mit der "rekursiven" Zusammenführungsstrategie. Ich bin mir bei Mercurial nicht sicher.

  • In "Bekannte Probleme" wird gewarnt, dass das Merge-Tracking möglicherweise nicht mit dem Umbenennen von Dateien funktioniert, z. B. wenn eine Seite die Datei umbenennt (und möglicherweise ändert) und die zweite Seite die Datei ohne Umbenennen ändert (unter altem Namen).

    Sowohl Git als auch Mercurial behandeln diesen Fall in der Praxis einwandfrei: Git mit Umbenennungserkennung , Mercurial mit Umbenennungsverfolgung .

HTH

Jakub Narębski
quelle
Irgendwie (Fehler im Markdown-Parser?) wird der Teil nach dem <pre>...</pre>Block nicht so eingerückt, wie er sein sollte ...
Jakub Narębski
1
+1 für die vielen detaillierten Beispiele. Ich verstehe noch nicht, warum das Beispiel in der ersten ASCII-Kunst Probleme verursachen könnte. Es sieht aus wie die Standardmethode zur Behandlung von Feature-Zweigen: Angenommen, A ist der Trunk, B ist ein Feature-Zweig. Sie führen wöchentlich von A nach B zusammen und wenn Sie mit der Funktion fertig sind, führen Sie alles von B nach A zusammen und löschen dann B. Das hat bei mir immer funktioniert. Habe ich das Diagramm falsch verstanden?
stmax
1
Beachten Sie, dass ich nicht weiß (ich habe nicht überprüft), dass die oben angegebenen Beispiele wirklich Probleme bei Subversion verursachen . Umbenennungen und Cross-Cross-Merge sind in SVN ein echtes Problem, denke ich.
Jakub Narębski
2
Das Zusammenführen von Zusammenführungen ist eine spezielle Option, um Ihnen im häufigsten Fall beim Zusammenführen zu helfen - es gibt auch keinen technischen Unterschied zwischen Zweigen und Stamm in svn. Ich neige dazu, es nie zu verwenden und bleibe bei der Standard-Zusammenführungsoption. Das einzige Problem bei svn merge ist jedoch, dass ein Verschieben / Umbenennen als Löschen + Hinzufügen behandelt wird.
Gbjbaanb
--reintegrateist veraltet.
naught101
120

Ich habe auch nach einem Fall gesucht, in dem Subversion beispielsweise einen Zweig nicht zusammenführt und Mercurial (und Git, Bazaar, ...) das Richtige tut.

Das SVN-Buch beschreibt, wie umbenannte Dateien falsch zusammengeführt werden . Dies gilt für Subversion 1.5 , 1.6 , 1.7 und 1.8 ! Ich habe versucht, die folgende Situation wiederherzustellen:

cd / tmp
rm - rf svn - repo svn - checkout
svnadmin create svn - repo
svn checkout datei : /// tmp / svn - repo svn - checkout
cd svn - Kasse
mkdir Stammzweige
Echo 'Auf Wiedersehen, Welt!' > Kofferraum / Hallo . TXT 
svn Stammzweige hinzufügen
svn commit - m 'Erstimport.' 
svn copy '^ / trunk' '^ / branch / rename' - m 'Branch erstellen.' 
SVN-Schalter '^ / Trunk' . 
Echo 'Hallo Welt!' > Hallo . TXT    
svn commit - m 'Update auf Trunk.' 
svn switch '^ / branches / rename' . 
svn umbenennen hallo . txt hallo . en . TXT 
svn commit - m 'In Zweig umbenennen.' 
SVN-Schalter '^ / Trunk'  . 
Svn merge - Reintegrieren '^ / branches / Umbenennungs'

Laut dem Buch sollte die Zusammenführung sauber abgeschlossen sein, jedoch mit falschen Daten in der umbenannten Datei, da das Update trunkvergessen wurde. Stattdessen erhalte ich einen Baumkonflikt (dies ist mit Subversion 1.6.17, der neuesten Version in Debian zum Zeitpunkt des Schreibens):

--- Unterschiede zwischen Repository-URLs in '.' Zusammenführen:
Ein hallo.de.txt
   C hello.txt
Zusammenfassung der Konflikte:
  Baumkonflikte: 1

Es sollte überhaupt keinen Konflikt geben - das Update sollte mit dem neuen Namen der Datei zusammengeführt werden. Während Subversion fehlschlägt, behandelt Mercurial dies korrekt:

rm -rf /tmp/hg-repo
hg init /tmp/hg-repo
cd /tmp/hg-repo
echo 'Goodbye, World!' > hello.txt
hg add hello.txt
hg commit -m 'Initial import.'
echo 'Hello, World!' > hello.txt
hg commit -m 'Update.'
hg update 0
hg rename hello.txt hello.en.txt
hg commit -m 'Rename.'
hg merge

Vor dem Zusammenführen sieht das Repository folgendermaßen aus (von hg glog ):

@ Änderungssatz: 2: 6502899164cc
| Tag: Tipp
| Eltern: 0: d08bcebadd9e
| Benutzer: Martin Geisler
| Datum: Do 01. April 12:29:19 2010 +0200
| Zusammenfassung: Umbenennen.
|
| o Änderungssatz: 1: 9d06fa155634
| / Benutzer: Martin Geisler 
| Datum: Do 01. April 12:29:18 2010 +0200
| Zusammenfassung: Update.
|
o Änderungssatz: 0: d08bcebadd9e
   Benutzer: Martin Geisler 
   Datum: Do 01. April 12:29:18 2010 +0200
   Zusammenfassung: Erstimport.

Die Ausgabe der Zusammenführung lautet:

Zusammenführen von hello.en.txt und hello.txt zu hello.en.txt
0 Dateien aktualisiert, 1 Dateien zusammengeführt, 0 Dateien entfernt, 0 Dateien ungelöst
(Zweig zusammenführen, nicht vergessen zu verpflichten)

Mit anderen Worten: Mercurial hat die Änderung aus Revision 1 übernommen und mit dem neuen Dateinamen aus Revision 2 ( hello.en.txt) zusammengeführt. Die Behandlung dieses Falls ist natürlich wichtig, um das Refactoring zu unterstützen, und Refactoring ist genau das, was Sie in einem Zweig tun möchten.

Martin Geisler
quelle
+1 für ein detailliertes Beispiel kann man auf die Tastatur tippen und selbst sehen, was passiert. Als Mercurial Noob frage ich mich, ob die hg-Version dieses Beispiels auf offensichtliche Weise Zeile für Zeile folgt.
DarenW
4
@DarenW: Ich habe die entsprechenden Mercurial-Befehle hinzugefügt, ich hoffe, es macht die Dinge klarer!
Martin Geisler
17

Ohne über die üblichen Vorteile zu sprechen (Offline-Commits, Veröffentlichungsprozess , ...) zu , hier ein Beispiel für das Zusammenführen, das mir gefällt:

Das Hauptszenario, das ich immer wieder sehe, ist ein Zweig, in dem ... zwei nicht zusammenhängende Aufgaben tatsächlich entwickelt werden
(es begann mit einem Feature, führte aber zur Entwicklung dieses anderen Features.
Oder es begann mit einem Patch, aber es führte zu der Entwicklung eines anderen Merkmals).

Wie können Sie nur eine der beiden Funktionen im Hauptzweig zusammenführen?
Oder Wie isolieren Sie die beiden Features in ihren eigenen Zweigen?

Sie könnten versuchen, eine Art Patches zu generieren. Das Problem dabei ist, dass Sie sich nicht mehr sicher sind, welche funktionalen Abhängigkeiten bestehen könnten zwischen:

  • die in Ihren Patches verwendeten Commits (oder Revisionen für SVN)
  • Der andere Commit ist nicht Teil des Patches

Git (und vermutlich auch Mercurial) schlagen die Option rebase --onto vor, um einen Teil eines Zweigs neu zu gründen (die Wurzel des Zweigs zurückzusetzen):

Von Jefromis Post

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)

Sie können diese Situation, in der Sie Patches für die Version 2 sowie eine neue WSS-Funktion haben, entwirren:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)

, so dass Sie:

  • Testen Sie jeden Zweig einzeln, um zu überprüfen, ob alles wie beabsichtigt kompiliert / funktioniert
  • füge nur das zusammen, was du pflegen willst.

Das andere Feature, das mir gefällt (das das Zusammenführen beeinflusst), ist die Fähigkeit, Commits zu quetschen (in einem Zweig, der noch nicht in ein anderes Repo verschoben wurde) zu quetschen, um Folgendes zu präsentieren:

  • eine sauberere Geschichte
  • Commits, die kohärenter sind (anstelle von Commit1 für Funktion1, Commit2 für Funktion2, Commit3 erneut für Funktion1 ...)

Dies stellt Zusammenführungen sicher, die viel einfacher und mit weniger Konflikten sind.

VonC
quelle
svn hat keine Offline-Commits? rofl? Wie kann jemand überhaupt in Betracht ziehen, es zu verwenden, wenn es so ist?
o0 '.
@Lohoris Als SVN herauskam, gab es keine weit verbreiteten Open-Source-DVCSs. An diesem Punkt denke ich, dass es meistens Trägheit ist, dass die Leute es immer noch benutzen.
Max Nanasy
@ MaxNanasy eine sehr schlechte Art von Trägheit ... trotzdem wäre es einfach dumm , es jetzt zu wählen .
o0 '.
@ Lohoris Online-Commits (genauer gesagt, zentralisiert) sind in einem kleinen Team, in dem sich das Repository einfach auf einem gemeinsam genutzten lokalen Server befinden kann, keine so große Sache. DVCSes wurden hauptsächlich für große, geografisch verteilte Teams (sowohl Git als auch Mercurial sollten den Linux-Kernel-Code verwalten) und Open Source-Projekte (daher die Popularität von GitHub) erfunden. Trägheit kann auch als Bewertung der Risiken und Vorteile einer Änderung eines Tools angesehen werden, das für den Workflow eines Teams von zentraler Bedeutung ist.
IMSoP
1
@Lohoris Ich denke, Sie haben meinen Standpunkt zu DB, Firewall usw. falsch verstanden: Es macht wenig Sinn, mich auf meinem Heimcomputer festschreiben zu können, wenn ich diesen Code nicht zuerst ausführen kann. Ich könnte blind arbeiten, aber die Tatsache, dass ich irgendwo keine Dinge begehen kann, würde mich nicht abschrecken.
IMSoP
8

Wir sind kürzlich von SVN zu GIT migriert und hatten die gleiche Unsicherheit. Es gab viele anekdotische Beweise dafür, dass GIT besser war, aber es war schwierig, Beispiele zu finden.

Ich kann Ihnen jedoch sagen, dass GIT beim Zusammenführen VIEL BESSER ist als SVN. Dies ist offensichtlich anekdotisch, aber es gibt eine Tabelle, der man folgen muss.

Hier sind einige der Dinge, die wir gefunden haben:

  • SVN hat in Situationen, in denen es nicht so schien, viele Baumkonflikte ausgelöst. Wir sind dem nie auf den Grund gegangen, aber es passiert nicht in GIT.
  • GIT ist zwar besser, aber wesentlich komplizierter. Verbringen Sie einige Zeit mit dem Training.
  • Wir waren es gewohnt, SVN zu quälen, was uns gefiel. Tortoise GIT ist nicht so gut und das kann Sie abschrecken. Allerdings benutze ich jetzt die GIT-Kommandozeile, die ich lieber als Tortoise SVN oder eine der GIT-GUIs.

Bei der Bewertung von GIT haben wir die folgenden Tests durchgeführt. Diese zeigen GIT als Gewinner, wenn es um das Zusammenführen geht, aber nicht so sehr. In der Praxis ist der Unterschied viel größer, aber ich denke, wir haben es nicht geschafft, die Situationen zu replizieren, mit denen SVN schlecht umgeht.

Bewertung der Zusammenführung von GIT und SVN

cedd
quelle
5

Andere haben die theoretischeren Aspekte davon behandelt. Vielleicht kann ich eine praktischere Perspektive geben.

Ich arbeite derzeit für ein Unternehmen, das SVN in einem Entwicklungsmodell für "Feature Branch" verwendet. Das ist:

  • Am Kofferraum können keine Arbeiten durchgeführt werden
  • Jeder Entwickler kann seine eigenen Zweige erstellen
  • Zweige sollten für die Dauer der durchgeführten Aufgabe bestehen bleiben
  • Jede Aufgabe sollte einen eigenen Zweig haben
  • Zusammenführungen zurück zum Trunk müssen autorisiert werden (normalerweise über Bugzilla)
  • In Zeiten, in denen ein hohes Maß an Kontrolle erforderlich ist, kann ein Gatekeeper Zusammenführungen durchführen

Im Allgemeinen funktioniert es. SVN kann für einen solchen Fluss verwendet werden, ist aber nicht perfekt. Es gibt einige Aspekte von SVN, die das menschliche Verhalten stören und beeinflussen. Das gibt ihm einige negative Aspekte.

  • Wir hatten einige Probleme mit Leuten, die von Punkten abzweigen, die niedriger sind als ^/trunk . Dies führt zu Zusammenführungsinformationsdatensätzen im gesamten Baum und unterbricht schließlich die Zusammenführungsverfolgung. Es treten falsche Konflikte auf und es herrscht Verwirrung.
  • Das Aufnehmen von Änderungen vom Stamm in einen Zweig ist relativ einfach. svn mergemacht was du willst. Das Zurückführen Ihrer Änderungen erfordert (wie uns mitgeteilt wurde) --reintegrateden Befehl zum Zusammenführen. Ich habe diesen Schalter nie wirklich verstanden, aber es bedeutet, dass der Zweig nicht wieder mit dem Trunk zusammengeführt werden kann. Dies bedeutet, dass es sich um einen toten Zweig handelt und Sie einen neuen erstellen müssen, um die Arbeit fortzusetzen. (Siehe Anmerkung)
  • Das gesamte Geschäft mit Operationen auf dem Server über URLs beim Erstellen und Löschen von Zweigen verwirrt und erschreckt die Menschen wirklich. Also vermeiden sie es.
  • Das Wechseln zwischen Zweigen kann leicht falsch sein, wenn ein Teil eines Baumes auf Zweig A blickt, während ein anderer Teil auf Ast B blickt. Daher bevorzugen die Menschen es, ihre gesamte Arbeit in einem Ast zu erledigen.

In der Regel erstellt ein Ingenieur am ersten Tag eine Niederlassung. Er beginnt seine Arbeit und vergisst sie. Einige Zeit später kommt ein Chef und fragt, ob er seine Arbeit im Kofferraum freigeben kann. Der Ingenieur hat diesen Tag gefürchtet, weil Wiedereingliederung bedeutet:

  • Zusammenführen seines langlebigen Zweigs zurück in den Stamm, Lösen aller Konflikte und Freigeben von nicht verwandtem Code, der sich in einem separaten Zweig befinden sollte, dies aber nicht war.
  • Zweig löschen
  • Neuen Zweig erstellen
  • Umstellung seiner Arbeitskopie auf den neuen Zweig

... und weil der Ingenieur dies so wenig wie möglich tut, kann er sich nicht an die "magische Beschwörung" erinnern, die für jeden Schritt erforderlich ist. Es kommt zu falschen Schaltern und URLs, und plötzlich sind sie durcheinander und holen sich den "Experten".

Irgendwann beruhigt sich alles und die Leute lernen, mit den Mängeln umzugehen, aber jeder neue Starter hat die gleichen Probleme. Die letztendliche Realität (im Gegensatz zu dem, was ich zu Beginn dargelegt habe) ist:

  • Am Kofferraum werden keine Arbeiten durchgeführt
  • Jeder Entwickler hat eine Hauptniederlassung
  • Zweige dauern so lange, bis die Arbeit freigegeben werden muss
  • Ticketed Bugfixes erhalten in der Regel eine eigene Filiale
  • Zusammenführungen zurück zum Trunk werden durchgeführt, wenn dies autorisiert ist

...aber...

  • Manchmal schafft es die Arbeit zum Kofferraum, wenn es nicht sein sollte, weil es sich in derselben Branche befindet wie etwas anderes.
  • Menschen vermeiden jegliches Verschmelzen (auch einfache Dinge), so dass Menschen oft in ihren eigenen kleinen Blasen arbeiten
  • Große Verschmelzungen treten häufig auf und verursachen ein begrenztes Chaos.

Zum Glück ist das Team klein genug, um damit fertig zu werden, aber es würde nicht skalieren. Nichts davon ist ein Problem mit CVCS, aber mehr noch, weil Zusammenführungen nicht so wichtig sind wie in DVCS, sind sie nicht so glatt. Diese "Zusammenführungsreibung" verursacht Verhalten, was bedeutet, dass ein "Feature Branch" -Modell zusammenbricht. Gute Zusammenführungen müssen ein Merkmal aller VCS sein, nicht nur von DVCS.


Nach dieser gibt es nun einen --record-onlySchalter , die verwendet werden, um das zu lösen --reintegrateProblem, und anscheinend v1.8 wählt , wenn automatisch eine reintegrate zu tun, und es der Zweig nicht dazu führt , danach tot zu sein

Paul S.
quelle
Soweit ich weiß, teilt die Option --reintegrate svn mit, dass Sie bereits widersprüchliche Änderungen beim Zusammenführen mit dem Feature-Zweig behoben haben. Anstatt es als Patch zu behandeln, werden ganze Dateien mit der Verzweigungsversion überschrieben, nachdem bereits im Zusammenführungsverlauf überprüft wurde, dass alle Trunk-Revisionen in der Verzweigung zusammengeführt wurden.
IMSoP
@IMSoP: Möglicherweise macht das Sinn. Das erklärt mir nicht, warum es notwendig war oder warum es weitere Zusammenschlüsse aus diesem Zweig unmöglich machte. Hat nicht geholfen, dass die Option auch weitgehend undokumentiert war.
Paul S
Ich habe es bisher nur über TortoiseSVN verwendet, wo es in der Merge-Benutzeroberfläche immer prominent erklärt wurde. Ich glaube, SVN 1.8 wählt automatisch die richtige Strategie und benötigt keine separate Option, aber ich weiß nicht, ob sie den normalen Zusammenführungsalgorithmus korrigiert haben, um mit einem Zweig, der auf diese Weise zurückgesetzt wurde, korrekt umzugehen.
IMSoP
3

Vor Subversion 1.5 (wenn ich mich nicht irre) hatte Subversion einen erheblichen Nachteil, da sie sich nicht an den Zusammenführungsverlauf erinnern konnte.

Schauen wir uns den von VonC skizzierten Fall an:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - A - x (v2-only)
           \
             x - B - x (wss)

Beachten Sie die Revisionen A und B. Angenommen, Sie haben Änderungen von Revision A im Zweig "wss" in den Zweig "nur v2" in Revision B (aus welchem ​​Grund auch immer) zusammengeführt, aber beide Zweige weiterhin verwendet. Wenn Sie versuchen würden, die beiden Zweige erneut mit mercurial zusammenzuführen, werden Änderungen erst nach den Revisionen A und B zusammengeführt. Bei Subversion müssten Sie alles zusammenführen, als hätten Sie zuvor keine Zusammenführung durchgeführt.

Dies ist ein Beispiel aus meiner eigenen Erfahrung, bei der das Zusammenführen von B nach A aufgrund des Codevolumens mehrere Stunden dauerte: Es wäre ein echtes Problem gewesen, es noch einmal durchzugehen , was bei Subversion vor 1.5 der Fall gewesen wäre.

Ein weiterer, wahrscheinlich relevanterer Unterschied im Zusammenführungsverhalten von Hginit: Subversion Umerziehung :

Stellen Sie sich vor, Sie und ich arbeiten an einem Code, und wir verzweigen diesen Code, und wir gehen jeweils in unsere separaten Arbeitsbereiche und nehmen viele, viele Änderungen an diesem Code separat vor, sodass sie ziemlich unterschiedlich sind.

Wenn wir zusammenführen müssen, versucht Subversion, beide Revisionen - meinen geänderten Code und Ihren geänderten Code - zu betrachten und zu erraten, wie sie in einem großen, unheiligen Durcheinander zusammengeschlagen werden können. Es schlägt normalerweise fehl und erzeugt Seiten und Seiten mit „Zusammenführungskonflikten“, die keine wirklichen Konflikte sind, sondern nur Orte, an denen Subversion nicht herausgefunden hat, was wir getan haben.

Im Gegensatz dazu war Mercurial, während wir separat in Mercurial arbeiteten, damit beschäftigt, eine Reihe von Änderungssätzen zu verwalten. Wenn wir also unseren Code zusammenführen möchten, hat Mercurial tatsächlich viel mehr Informationen: Es weiß, was jeder von uns geändert hat, und kann diese Änderungen erneut anwenden, anstatt nur das Endprodukt zu betrachten und zu erraten, wie es zu setzen ist zusammen.

Kurz gesagt, Mercurials Methode zur Analyse von Unterschieden ist (war?) Der von Subversion überlegen.

Tomislav Nakic-Alfirevic
quelle
5
Ich habe Hginit gelesen. Schade, dass es keine praktischeren Beispiele dafür gibt, wo hg besser abschneidet als svn. Im Grunde sagt es dir, du sollst Joel vertrauen, dass hg einfach besser ist. Die einfachen Beispiele, die er gezeigt hat, könnten wahrscheinlich auch mit svn gemacht werden. Deshalb habe ich diese Frage geöffnet.
stmax
1
Basierend darauf, wie dies gesagt wird, stellt sich die naive Frage: Was wäre, wenn der Merge-Algorithmus von Mercurial in Subversion integriert würde? Wäre svn dann so gut wie hg? Nein, denn der Vorteil von hg liegt in der Organisation auf höherer Ebene, nicht in der Textmathematik auf niedriger Ebene beim Zusammenführen von Zeilen aus Dateien. Das ist die neuartige Idee, die wir svn-Benutzer brauchen, um zu groken.
DarenW
@stmax: Ich kann sehen, was du meinst. Die Meinung von Joel oder anderen spielt jedoch keine Rolle: Eine Technologie ist entweder besser als die andere (für eine Reihe von Anwendungsfällen) oder nicht. @DarenW und @stmax: Aus meiner persönlichen Erfahrung gewinnt Hg zweifellos aufgrund seines verteilten Betriebs (ich bin nicht immer verbunden), seiner Leistung (viele lokale Vorgänge) und seiner äußerst intuitiven Verzweigung, die von einem überlegenen Zusammenführungsalgorithmus unterstützt wird. HG-Rollback, Vorlagenprotokollausgabe, HG-Glog, einzelner .hg-Ordner ... Ich könnte einfach weiter und weiter und weiter ... alles andere als vielleicht Git und Basar fühlt sich wie eine Zwangsjacke an.
Tomislav Nakic-Alfirevic
Der über "Changesets" zitierte hg-Kommentar erscheint mir eher ungenau. SVN weiß genau, welche Änderungen zusammengeführt werden (ein Änderungssatz ist im Grunde der Unterschied zwischen zwei Schnappschüssen und umgekehrt, oder?) Und kann sie nacheinander anwenden, wenn dies gewünscht wird. muss sicher nichts "erraten". Wenn es "ein großes unheiliges Durcheinander" macht, dann ist das ein Implementierungsproblem, nichts grundlegendes für das Design. Das Hauptproblem, das zusätzlich zum aktuellen Architekturdesign schwer zu lösen ist, ist das Verschieben / Kopieren / Umbenennen von Dateien.
IMSoP