Wie und / oder warum ist das Zusammenführen in Git besser als in SVN?

400

Ich habe an einigen Stellen gehört, dass einer der Hauptgründe, warum verteilte Versionskontrollsysteme glänzen, das Zusammenführen viel besser ist als bei herkömmlichen Tools wie SVN. Liegt dies tatsächlich an inhärenten Unterschieden in der Funktionsweise der beiden Systeme oder haben bestimmte DVCS-Implementierungen wie Git / Mercurial nur cleverere Zusammenführungsalgorithmen als SVN?

Mr. Boy
quelle
Ich habe immer noch keine vollständige Antwort erhalten, als ich die großartigen Antworten hier gelesen habe. Reposted - stackoverflow.com/questions/6172037/…
ripper234
es hängt von Ihrem Modell ab. In einfacheren Fällen ist svn oft besser, weil es nicht versehentlich 2-Wege-Zusammenführungen aufruft, wie es Git tun kann, wenn Sie einen einzelnen Entwicklungszweig pushen / zusammenführen / ziehen / pushen. siehe: svnvsgit.com
Erik Aronesty

Antworten:

556

Die Behauptung, warum das Zusammenführen in einem DVCS besser ist als in Subversion, beruhte weitgehend darauf, wie das Verzweigen und Zusammenführen in Subversion vor einiger Zeit funktioniert hat. Subversion vor 1.5.0 speicherte keine Informationen darüber, wann Zweige zusammengeführt wurden. Wenn Sie also zusammenführen wollten, mussten Sie angeben, welcher Revisionsbereich zusammengeführt werden musste.

Warum also hat Subversion verschmilzt saugen ?

Denken Sie über dieses Beispiel nach:

      1   2   4     6     8
trunk o-->o-->o---->o---->o
       \
        \   3     5     7
b1       +->o---->o---->o

Wenn wir wollen fusionieren b1 die Änderungen in den Kofferraum wir den folgenden Befehl ausgeben würde, während auf einem Ordner stehen , die trunk ausgecheckt hat:

svn merge -r 2:7 {link to branch b1}

… Die versuchen, die Änderungen b1in Ihrem lokalen Arbeitsverzeichnis zusammenzuführen. Anschließend übernehmen Sie die Änderungen, nachdem Sie Konflikte gelöst und das Ergebnis getestet haben. Wenn Sie den Revisionsbaum festschreiben, sieht er folgendermaßen aus:

      1   2   4     6     8   9
trunk o-->o-->o---->o---->o-->o      "the merge commit is at r9"
       \
        \   3     5     7
b1       +->o---->o---->o

Diese Art der Angabe von Revisionsbereichen gerät jedoch schnell außer Kontrolle, wenn der Versionsbaum wächst, da die Subversion keine Metadaten darüber hatte, wann und welche Revisionen zusammengeführt wurden. Überlegen Sie, was später passiert:

           12        14
trunk  …-->o-------->o
                                     "Okay, so when did we merge last time?"
              13        15
b1     …----->o-------->o

Dies ist größtenteils ein Problem des Repository-Designs von Subversion. Um einen Zweig zu erstellen, müssen Sie ein neues virtuelles Verzeichnis im Repository erstellen, in dem eine Kopie des Trunks gespeichert ist, in dem jedoch keine Informationen darüber gespeichert sind, wann und was Dinge wurden wieder zusammengeführt. Das wird manchmal zu bösen Zusammenführungskonflikten führen. Was noch schlimmer war, ist, dass Subversion standardmäßig das bidirektionale Zusammenführen verwendet, was einige lähmende Einschränkungen beim automatischen Zusammenführen aufweist, wenn zwei Zweigköpfe nicht mit ihrem gemeinsamen Vorfahren verglichen werden.

Um diese Subversion zu mildern, werden jetzt Metadaten für die Verzweigung und Zusammenführung gespeichert. Das würde alle Probleme richtig lösen?

Und ach übrigens, Subversion ist immer noch scheiße ...

Auf einem zentralisierten System wie Subversion saugen virtuelle Verzeichnisse . Warum? Weil jeder Zugriff hat, um sie anzusehen… sogar die Müll-Experimental-Experimente. Verzweigung ist gut, wenn Sie experimentieren möchten, aber nicht alle und ihre Tanten experimentieren möchten . Dies ist ernstes kognitives Rauschen. Je mehr Zweige Sie hinzufügen, desto mehr Mist werden Sie sehen.

Je mehr öffentliche Filialen Sie in einem Repository haben, desto schwieriger wird es, die verschiedenen Filialen im Auge zu behalten. Die Frage, die Sie haben werden, ist also, ob sich der Zweig noch in der Entwicklung befindet oder ob er wirklich tot ist, was in einem zentralen Versionskontrollsystem schwer zu sagen ist.

Nach dem, was ich gesehen habe, verwendet eine Organisation die meiste Zeit ohnehin standardmäßig einen großen Zweig. Das ist eine Schande, denn es wird wiederum schwierig sein, die Test- und Release-Versionen im Auge zu behalten, und was auch immer gut ist, kommt von der Verzweigung.

Warum sind DVCS wie Git, Mercurial und Bazaar beim Verzweigen und Zusammenführen besser als Subversion?

Dafür gibt es einen sehr einfachen Grund: Verzweigung ist ein erstklassiges Konzept . Es gibt keine virtuellen Verzeichnisse , und Zweige sind harte Objekte in DVCS, die es sein muss, um einfach mit der Synchronisation von Repositorys (dh Push and Pull ) zu arbeiten.

Das erste, was Sie tun, wenn Sie mit einem DVCS arbeiten, ist das Klonen von Repositorys (Git clone, cloneHG und BZR branch). Das Klonen ist konzeptionell dasselbe wie das Erstellen eines Zweigs in der Versionskontrolle. Einige nennen dies Gabelung oder Verzweigung (obwohl letztere oft auch für am selben Ort befindliche Zweige verwendet wird), aber es ist genau das Gleiche. Jeder Benutzer führt ein eigenes Repository aus, was bedeutet, dass eine Verzweigung pro Benutzer stattfindet .

Die Versionsstruktur ist kein Baum , sondern ein Diagramm . Insbesondere ein gerichteter azyklischer Graph (DAG, dh ein Graph ohne Zyklen). Sie müssen sich wirklich nicht mit den Besonderheiten einer DAG befassen, außer dass jedes Commit eine oder mehrere übergeordnete Referenzen hat (auf denen das Commit basiert). Aus diesem Grund zeigen die folgenden Grafiken die Pfeile zwischen den Revisionen in umgekehrter Reihenfolge.

Ein sehr einfaches Beispiel für das Zusammenführen wäre dies; Stellen Sie sich ein zentrales Repository mit dem Namen originAlice vor, die das Repository auf ihren Computer klont.

         a…   b…   c…
origin   o<---o<---o
                   ^master
         |
         | clone
         v

         a…   b…   c…
alice    o<---o<---o
                   ^master
                   ^origin/master

Während eines Klons passiert, dass jede Revision genau so nach Alice kopiert wird, wie sie war (was durch die eindeutig identifizierbaren Hash-IDs bestätigt wird) und markiert, wo sich die Zweige des Ursprungs befinden.

Alice arbeitet dann an ihrem Repo, legt es in ihrem eigenen Repository fest und beschließt, ihre Änderungen voranzutreiben:

         a…   b…   c…
origin   o<---o<---o
                   ^ master

              "what'll happen after a push?"


         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                   ^origin/master

Die Lösung ist ziemlich einfach. Das einzige, was das originRepository tun muss, ist, alle neuen Revisionen aufzunehmen und seinen Zweig auf die neueste Revision zu verschieben (die Git als "Schnellvorlauf" bezeichnet):

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

         a…   b…   c…   d…   e…
alice    o<---o<---o<---o<---o
                             ^master
                             ^origin/master

Der Anwendungsfall, den ich oben dargestellt habe, muss nicht einmal etwas zusammenführen . Das Problem ist also nicht wirklich das Zusammenführen von Algorithmen, da der Drei-Wege-Zusammenführungsalgorithmus zwischen allen Versionskontrollsystemen ziemlich gleich ist. Es geht mehr um Struktur als um irgendetwas .

Wie wäre es, wenn Sie mir ein Beispiel zeigen, das eine echte Verschmelzung hat?

Zugegeben, das obige Beispiel ist ein sehr einfacher Anwendungsfall, also lassen Sie uns einen viel verdrehteren, wenn auch einen häufigeren machen. Erinnerst origindu dich, dass das mit drei Revisionen begann? Nun, der Typ, der sie gemacht hat, nennen wir ihn Bob , hat alleine gearbeitet und ein Commit für sein eigenes Repository gemacht:

         a…   b…   c…   f…
bob      o<---o<---o<---o
                        ^ master
                   ^ origin/master

                   "can Bob push his changes?" 

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

Jetzt kann Bob seine Änderungen nicht direkt in das originRepository übertragen. Das System erkennt dies, indem überprüft wird, ob die Revisionen von Bob direkt von denen originabweichen, was in diesem Fall nicht der Fall ist. Jeder Versuch zu pushen führt dazu, dass das System etwas sagt, das mit " Äh ... ich fürchte, Sie können das nicht tun, Bob ."

So Bob muss Einzugs- und dann die Änderungen verschmelzen (mit Git pulloder hg ist pullund mergeoder BZR ist merge). Dies ist ein zweistufiger Prozess. Zuerst muss Bob die neuen Revisionen abrufen, die sie so kopieren, wie sie aus dem originRepository stammen. Wir können jetzt sehen, dass der Graph divergiert:

                        v master
         a…   b…   c…   f…
bob      o<---o<---o<---o
                   ^
                   |    d…   e…
                   +----o<---o
                             ^ origin/master

         a…   b…   c…   d…   e…
origin   o<---o<---o<---o<---o
                             ^ master

Der zweite Schritt des Pull-Prozesses besteht darin, die divergierenden Spitzen zusammenzuführen und das Ergebnis festzuschreiben:

                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+
                             ^ origin/master

Hoffentlich kommt es bei der Zusammenführung nicht zu Konflikten (wenn Sie diese vorwegnehmen, können Sie die beiden Schritte manuell in git mit fetchund ausführen merge). Was später getan werden muss, ist, diese Änderungen erneut auf zu übertragen origin, was zu einer schnellen Zusammenführung führt, da das Zusammenführungs-Commit ein direkter Nachkomme der neuesten im originRepository ist:

                                 v origin/master
                                 v master
         a…   b…   c…   f…       1…
bob      o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

                                 v master
         a…   b…   c…   f…       1…
origin   o<---o<---o<---o<-------o
                   ^             |
                   |    d…   e…  |
                   +----o<---o<--+

Es gibt eine weitere Option zum Zusammenführen von git und hg, die Rebase , mit der Bobs Änderungen nach den neuesten Änderungen verschoben werden. Da will ich nicht diese Antwort mehr sein ausführliche ich Ihnen die lesen lasse git , Mercurial oder Basar docs darüber statt.

Versuchen Sie als Übung für den Leser herauszufinden, wie es mit einem anderen beteiligten Benutzer funktionieren wird. Dies geschieht ähnlich wie im obigen Beispiel mit Bob. Das Zusammenführen zwischen Repositorys ist einfacher als gedacht, da alle Revisionen / Commits eindeutig identifizierbar sind.

Es gibt auch das Problem, Patches zwischen den einzelnen Entwicklern zu senden. Dies war ein großes Problem bei Subversion, das in git, hg und bzr durch eindeutig identifizierbare Revisionen verringert wird. Sobald jemand seine Änderungen zusammengeführt hat (dh ein Zusammenführungs-Commit durchgeführt hat) und es an alle anderen im Team sendet, um es zu konsumieren, indem er entweder in ein zentrales Repository pusht oder Patches sendet, muss er sich keine Gedanken mehr über die Zusammenführung machen, da dies bereits geschehen ist . Martin Fowler nennt diese Arbeitsweise promiskuitive Integration .

Da sich die Struktur von Subversion unterscheidet und stattdessen eine DAG verwendet wird, können Verzweigungen und Zusammenführungen nicht nur für das System, sondern auch für den Benutzer einfacher durchgeführt werden.

Spoike
quelle
6
Ich bin nicht mit Ihren Zweigen einverstanden == Rauschargument. Viele Zweige verwirren die Leute nicht, weil der leitende Entwickler den Leuten sagen sollte, welchen Zweig sie für große Features verwenden sollen ... also könnten zwei Entwickler an Zweig X arbeiten, um "fliegende Dinosaurier" hinzuzufügen, 3 könnten an Y arbeiten, um "Sie werfen zu lassen" Autos bei Menschen "
Mr. Boy
16
John: Ja, für eine kleine Anzahl von Zweigen gibt es wenig Lärm und ist überschaubar. Aber kommen Sie zurück, nachdem Sie mehr als 50 Zweige und Tags oder so in Subversion oder klarem Fall gesehen haben, wo die meisten von ihnen nicht sagen können, ob sie aktiv sind oder nicht. Usability-Problem von den Tools beiseite; Warum haben Sie all diesen Müll in Ihrem Repository? Zumindest in p4 (da der "Arbeitsbereich" eines Benutzers im Wesentlichen ein Zweig pro Benutzer ist), git oder hg haben Sie die Möglichkeit, nicht alle über die vorgenommenen Änderungen zu informieren, bis Sie sie in den Upstream verschieben. Achten Sie darauf, wann die Änderungen für andere relevant sind.
Spoike
24
Ich verstehe auch nicht, dass "zu viele experimentelle Zweige ein Rauschargument sind, @Spoike. Wir haben einen" Benutzer "-Ordner, in dem jeder Benutzer seinen eigenen Ordner hat. Dort kann er so oft verzweigen, wie er möchte. Zweige sind in Subversion und kostengünstig Wenn Sie die Ordner der anderen Benutzer ignorieren (warum sollten Sie sich überhaupt um sie kümmern), sehen Sie kein Rauschen. Aber für mich ist das Zusammenführen in SVN nicht schlecht (und ich mache es oft, und nein, es ist nicht klein Projekt). Also vielleicht mache ich etwas falsch;) Trotzdem ist die Verschmelzung von Git und Mercurial überlegen und Sie haben es gut hervorgehoben.
John Smithers
11
In svn ist es einfach, inaktive Zweige zu töten, Sie löschen sie einfach. Die Tatsache, dass Menschen nicht verwendete Äste nicht entfernen, wodurch Unordnung entsteht, ist nur eine Frage der Haushaltsführung. Sie könnten genauso gut mit vielen temporären Zweigen in Git enden. An meinem Arbeitsplatz verwenden wir zusätzlich zu den Standardverzeichnissen ein Verzeichnis der obersten Ebene mit "temporären Zweigen". Dort werden persönliche Zweige und experimentelle Zweige angezeigt, anstatt das Verzeichnis der Zweige zu überladen, in dem "offizielle" Codezeilen gespeichert sind (wir tun dies nicht) Feature-Zweige verwenden).
Ken Liu
10
Bedeutet dies dann, dass ab Version 1.5 Subversion mindestens so gut zusammengeführt werden kann wie Git?
Sam
29

In der Vergangenheit konnte Subversion nur eine direkte bidirektionale Zusammenführung durchführen, da keine Zusammenführungsinformationen gespeichert wurden. Dazu müssen Sie eine Reihe von Änderungen vornehmen und auf einen Baum anwenden. Selbst bei Zusammenführungsinformationen ist dies immer noch die am häufigsten verwendete Zusammenführungsstrategie.

Git verwendet standardmäßig einen 3-Wege-Zusammenführungsalgorithmus, bei dem ein gemeinsamer Vorfahr für die zusammengeführten Köpfe gefunden und das Wissen genutzt wird, das auf beiden Seiten der Zusammenführung vorhanden ist. Dies ermöglicht es Git, Konflikte intelligenter zu vermeiden.

Git hat auch einen ausgeklügelten Code zum Umbenennen, was ebenfalls hilfreich ist. Es werden keine Änderungssätze oder Tracking-Informationen gespeichert. Es wird lediglich der Status der Dateien bei jedem Commit gespeichert und mithilfe von Heuristiken nach Bedarf umbenannt und umbenannt (der Speicher auf der Festplatte ist komplizierter als dieser, aber die Schnittstelle es präsentiert sich der Logikschicht und legt keine Verfolgung frei).

Andrew Aylett
quelle
4
Haben Sie ein Beispiel dafür, dass svn einen Zusammenführungskonflikt hat, Git jedoch nicht?
Gqqnbig
17

Einfach ausgedrückt ist die Merge-Implementierung in Git besser als in SVN . Vor 1.5 zeichnete SVN keine Zusammenführungsaktion auf, sodass zukünftige Zusammenführungen ohne Hilfe des Benutzers nicht möglich waren, der Informationen bereitstellen musste, die SVN nicht aufzeichnete. Mit 1.5 wurde es besser, und tatsächlich ist das SVN-Speichermodell etwas leistungsfähiger als die DAG von Git. Aber SVN hat die Zusammenführungsinformationen in einer ziemlich komplizierten Form gespeichert, sodass Zusammenführungen massiv länger dauern als in Git - ich habe Faktoren von 300 in der Ausführungszeit beobachtet.

Außerdem behauptet SVN, Umbenennungen zu verfolgen, um das Zusammenführen von verschobenen Dateien zu erleichtern. Tatsächlich werden sie jedoch immer noch als Kopie und separate Löschaktion gespeichert, und der Zusammenführungsalgorithmus stößt in Situationen zum Ändern / Umbenennen immer noch über sie, dh wenn eine Datei in einem Zweig geändert und in dem anderen umbenannt wird und diese Zweige es sind zusammengeführt werden. Solche Situationen führen immer noch zu falschen Zusammenführungskonflikten, und bei Umbenennungen von Verzeichnissen führt dies sogar zu einem stillen Verlust von Änderungen. (Die SVN-Leute neigen dann dazu, darauf hinzuweisen, dass die Änderungen noch in der Historie sind, aber das hilft nicht viel, wenn sie nicht in einem Zusammenführungsergebnis sind, wo sie erscheinen sollten.

Git hingegen verfolgt nicht einmal Umbenennungen, sondern findet sie nachträglich heraus (zum Zeitpunkt der Zusammenführung) und tut dies ziemlich magisch.

Die SVN-Zusammenführungsdarstellung weist ebenfalls Probleme auf. In 1.5 / 1.6 konnten Sie automatisch so oft wie gewünscht von Trunk zu Branch zusammenführen, aber eine Zusammenführung in die andere Richtung musste angekündigt werden ( --reintegrate), und der Zweig wurde in einem unbrauchbaren Zustand belassen. Viel später fanden sie heraus , dass dies tatsächlich nicht der Fall ist, und dass a) das --reintegrate kann automatisch herausgefunden werden, und b) wiederholt verschmilzt in beiden Richtungen möglich.

Aber nach all dem (was meiner Meinung nach ein Unverständnis darüber zeigt, was sie tun) wäre ich (OK, ich bin) sehr vorsichtig, SVN in jedem nicht trivialen Verzweigungsszenario zu verwenden, und würde idealerweise versuchen zu sehen, was Git davon hält das Zusammenführungsergebnis.

Andere Punkte in den Antworten, wie die erzwungene globale Sichtbarkeit von Zweigen in SVN, sind für die Zusammenführungsfunktionen nicht relevant (aber für die Benutzerfreundlichkeit). Auch die "Git speichert Änderungen, während SVN speichert (etwas anderes)" sind meistens falsch. Git speichert jedes Commit konzeptionell als separaten Baum (wie eine TAR- Datei) und verwendet dann einige Heuristiken, um dies effizient zu speichern. Die Berechnung der Änderungen zwischen zwei Commits ist von der Speicherimplementierung getrennt. Was wahr ist, ist, dass Git die Verlaufs-DAG in einer viel einfacheren Form speichert, als SVN seine Mergeinfo macht. Jeder, der versucht, Letzteres zu verstehen, wird wissen, was ich meine.

Kurz gesagt: Git verwendet ein viel einfacheres Datenmodell zum Speichern von Revisionen als SVN und könnte daher viel Energie in die eigentlichen Zusammenführungsalgorithmen stecken, anstatt zu versuchen, mit der Darstellung fertig zu werden => praktisch besseres Zusammenführen.

Andreas Krey
quelle
11

Eine Sache, die in den anderen Antworten nicht erwähnt wurde und die wirklich ein großer Vorteil eines DVCS ist, ist, dass Sie sich lokal festlegen können, bevor Sie Ihre Änderungen vornehmen. Wenn ich in SVN eine Änderung hatte, die ich einchecken wollte, und jemand in der Zwischenzeit bereits ein Commit für denselben Zweig durchgeführt hatte, bedeutete dies, dass ich ein Commit durchführen musste, svn updatebevor ich ein Commit durchführen konnte. Dies bedeutet, dass meine Änderungen und die Änderungen der anderen Person jetzt miteinander vermischt sind und es keine Möglichkeit gibt, die Zusammenführung abzubrechen (wie mit git resetoder hg update -C), da es keine Verpflichtung gibt, zu der ich zurückkehren kann. Wenn die Zusammenführung nicht trivial ist, bedeutet dies, dass Sie nicht weiter an Ihrer Funktion arbeiten können, bevor Sie das Zusammenführungsergebnis bereinigt haben.

Aber vielleicht ist das nur ein Vorteil für Leute, die zu dumm sind, um separate Zweige zu verwenden (wenn ich mich richtig erinnere, hatten wir nur einen Zweig, der für die Entwicklung in dem Unternehmen verwendet wurde, in dem ich SVN verwendet habe).

Daniel Kullmann
quelle
10

BEARBEITEN: Dies befasst sich hauptsächlich mit diesem Teil der Frage:
Liegt dies tatsächlich an inhärenten Unterschieden in der Funktionsweise der beiden Systeme, oder haben bestimmte DVCS-Implementierungen wie Git / Mercurial nur cleverere Zusammenführungsalgorithmen als SVN?
TL; DR - Diese spezifischen Tools verfügen über bessere Algorithmen. Die Verteilung hat einige Workflow-Vorteile, ist jedoch orthogonal zu den Vorteilen beim Zusammenführen.
END EDIT

Ich habe die akzeptierte Antwort gelesen. Es ist einfach falsch.

Das Zusammenführen von SVN kann schmerzhaft und auch umständlich sein. Aber ignorieren Sie für eine Minute, wie es tatsächlich funktioniert. Es gibt keine Informationen, die Git aufbewahrt oder ableiten kann, die SVN nicht auch aufbewahrt oder ableiten kann. Noch wichtiger ist, dass es keinen Grund gibt, warum Sie durch das Speichern separater (manchmal teilweiser) Kopien des Versionskontrollsystems aktuellere Informationen erhalten. Die beiden Strukturen sind völlig gleichwertig.

Angenommen, Sie möchten "etwas Kluges" tun, in dem Git "besser" ist. Und dein Ding ist in SVN eingecheckt.

Konvertieren Sie Ihre SVN in das entsprechende Git-Formular, führen Sie sie in Git aus und überprüfen Sie das Ergebnis in einigen zusätzlichen Zweigen, möglicherweise mithilfe mehrerer Commits. Wenn Sie sich einen automatisierten Weg vorstellen können, ein SVN-Problem in ein Git-Problem umzuwandeln, hat Git keinen grundlegenden Vorteil.

Am Ende des Tages lässt mich jedes Versionskontrollsystem

1. Generate a set of objects at a given branch/revision.
2. Provide the difference between a parent child branch/revisions.

Darüber hinaus ist es zum Zusammenführen auch nützlich (oder kritisch) zu wissen

3. The set of changes have been merged into a given branch/revision.

Mercurial , Git und Subversion (jetzt nativ, zuvor mit svnmerge.py) können alle drei Informationen bereitstellen. Um mit DVC etwas grundlegend Besseres zu demonstrieren, weisen Sie bitte auf eine vierte Information hin, die in Git / Mercurial / DVC verfügbar ist und in SVN / Centralized VC nicht verfügbar ist.

Das heißt nicht, dass sie keine besseren Werkzeuge sind!

Peter
quelle
1
Ja, ich habe die Frage im Detail beantwortet, nicht die Überschrift. SVN und Git haben Zugriff auf die gleichen Informationen (eigentlich typisch svn mehr hat), so SVN konnte tun , was git tut. Aber sie haben unterschiedliche Designentscheidungen getroffen, und das ist tatsächlich nicht der Fall. Der Beweis auf dem DVC / Centralized ist, dass Sie Git als Centralized VC ausführen können (möglicherweise mit einigen auferlegten Regeln) und dass Sie SVN verteilt ausführen können (aber es ist total beschissen). Dies ist jedoch für die meisten Menschen allzu akademisch - git und hg verzweigen und verschmelzen besser als svn. Das ist wirklich wichtig bei der Auswahl eines Werkzeugs :-).
Peter
5
Bis zur Version 1.5 hat Subversion nicht alle erforderlichen Informationen gespeichert. Bei SVN nach 1.5 sind die gespeicherten Informationen unterschiedlich: Git speichert alle übergeordneten Elemente eines Merge-Commits, während Subversion speichert, welche Revisionen bereits in einem Zweig zusammengeführt wurden.
Jakub Narębski
4
Ein Tool, das in einem SVN-Repository nur schwer erneut implementiert werden kann, ist git merge-base. Mit git können Sie "Zweige a und b bei Revision x teilen" sagen. Aber svn speichert "Dateien wurden von foo nach bar kopiert", daher müssen Sie mithilfe von Heuristiken herausfinden, dass beim Kopieren nach bar ein neuer Zweig erstellt wurde, anstatt Dateien innerhalb eines Projekts zu kopieren. Der Trick besteht darin, dass eine Revision in svn durch die Revisionsnummer und den Basispfad definiert wird . Obwohl es möglich ist, die meiste Zeit von "Stamm" auszugehen, beißt es, wenn es tatsächlich Zweige gibt.
Douglas
2
Betreff: "Es gibt keine Informationen, die git aufbewahrt oder ableiten kann, die svn nicht auch aufbewahrt oder ableiten kann." - Ich stellte fest, dass SVN sich nicht daran erinnerte, wann die Dinge zusammengeführt worden waren. Wenn Sie die Arbeit vom Stamm in Ihren Zweig ziehen und hin und her gehen möchten, kann das Zusammenführen schwierig werden. In Git weiß jeder Knoten in seinem Revisionsdiagramm, woher er stammt. Es hat bis zu zwei Eltern und einige lokale Veränderungen. Ich würde darauf vertrauen, dass Git mehr als SVN zusammenführen kann. Wenn Sie in SVN zusammenführen und den Zweig löschen, geht der Zweigverlauf verloren. Wenn Sie in GIT zusammenführen und den Zweig löschen, bleibt das Diagramm und damit das Plugin "Schuld" erhalten.
Richard Corfield
1
Ist es nicht so, dass Git und Mercurial lokal über alle erforderlichen Informationen verfügen, während svn sowohl lokale als auch zentrale Daten untersuchen muss, um die Informationen abzuleiten?
Warren Dew
8

SVN - Tracks Dateien während Git Tracks Inhalt ändert. Es ist klug genug, einen Codeblock zu verfolgen, der von einer Klasse / Datei in eine andere umgestaltet wurde. Sie verwenden zwei völlig unterschiedliche Ansätze, um Ihre Quelle zu verfolgen.

Ich benutze SVN immer noch stark, aber ich bin sehr zufrieden mit den wenigen Malen, die ich Git verwendet habe.

Eine schöne Lektüre, wenn Sie Zeit haben: Warum ich mich für Git entschieden habe

used2could
quelle
Das habe ich auch gelesen und darauf habe ich gezählt, aber in der Praxis funktioniert es nicht.
Rolf
Git verfolgt den Inhalt von Dateien, es zeigt nur den Inhalt als Änderungen
Ferrybig
6

Lies einfach einen Artikel in Joels Blog (leider seinen letzten). Hier geht es um Mercurial, aber es geht tatsächlich um die Vorteile verteilter VC-Systeme wie Git.

Bei der verteilten Versionskontrolle ist der verteilte Teil eigentlich nicht der interessanteste Teil. Der interessante Teil ist, dass diese Systeme in Änderungen denken, nicht in Versionen.

Lesen Sie den Artikel hier .

rubayeet
quelle
5
Das war einer der Artikel, über die ich nachgedacht habe, bevor ich hier gepostet habe. Aber "denkt in Veränderungen" ist ein sehr vager, nach Marketing klingender Begriff (denken Sie daran, dass Joels Firma jetzt DVCS verkauft)
Mr. Boy
2
Ich fand das auch vage ... Ich dachte immer, Änderungssätze seien ein wesentlicher Bestandteil von Versionen (oder eher Revisionen), was mich überrascht, dass einige Programmierer nicht an Änderungen denken.
Spoike
Für ein System, das wirklich "in Veränderungen denkt", schauen Sie sich Darcs
Max
@Max: Sicher, aber wenn es darauf ankommt, liefert Git, wo Darcs im Grunde genauso schmerzhaft ist wie Subversion, wenn es darum geht, tatsächlich zu verschmelzen.
Tripleee
Die drei Nachteile von Git sind: a) Es ist nicht so gut für Binärdateien wie die Dokumentenverwaltung, bei denen es sehr unwahrscheinlich ist, dass Benutzer verzweigen und zusammenführen möchten. B) Es wird davon ausgegangen, dass Sie ALLES klonen möchten. C) Es speichert sogar den Verlauf von allem im Klon für häufig wechselnde Binärdateien, die das Aufblähen von Klonen verursachen. Ich denke, ein zentrales VCS ist für diese Anwendungsfälle weitaus besser. Git ist weitaus besser für die regelmäßige Entwicklung geeignet, insbesondere zum Zusammenführen und Verzweigen.
Locka