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.
Antworten:
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
--reintegrate
Option tosvn 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 bereitstellensvn log
undsvn blame
diese 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:mergeinfo
Soweit 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):
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.
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 .
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
quelle
<pre>...</pre>
Block nicht so eingerückt, wie er sein sollte ...--reintegrate
ist veraltet.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:
Laut dem Buch sollte die Zusammenführung sauber abgeschlossen sein, jedoch mit falschen Daten in der umbenannten Datei, da das Update
trunk
vergessen wurde. Stattdessen erhalte ich einen Baumkonflikt (dies ist mit Subversion 1.6.17, der neuesten Version in Debian zum Zeitpunkt des Schreibens):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:
Vor dem Zusammenführen sieht das Repository folgendermaßen aus (von
hg glog
):Die Ausgabe der Zusammenführung lautet:
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.quelle
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:
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
Sie können diese Situation, in der Sie Patches für die Version 2 sowie eine neue WSS-Funktion haben, entwirren:
, so dass Sie:
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:
Dies stellt Zusammenführungen sicher, die viel einfacher und mit weniger Konflikten sind.
quelle
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:
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.
quelle
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:
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.
^/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.svn merge
macht was du willst. Das Zurückführen Ihrer Änderungen erfordert (wie uns mitgeteilt wurde)--reintegrate
den 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)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:
... 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:
...aber...
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-only
Schalter , die verwendet werden, um das zu lösen--reintegrate
Problem, und anscheinend v1.8 wählt , wenn automatisch eine reintegrate zu tun, und es der Zweig nicht dazu führt , danach tot zu seinquelle
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:
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 :
Kurz gesagt, Mercurials Methode zur Analyse von Unterschieden ist (war?) Der von Subversion überlegen.
quelle