Was bedeutet "Verzweigen ist kostenlos" in Git?

27

Was bedeutet "Verzweigen ist kostenlos" in Git?

Ich höre dies oft, wenn Git im Vergleich zu anderen Versionskontrollsystemen erwähnt wird.

Ich hatte nicht die Gelegenheit (?), Mich mit anderen zu befassen ( SVN usw.). Wie ist die Verzweigung bei anderen "teuer"?

laggingreflex
quelle

Antworten:

28

Die Behauptung , dass „Verzweigung ist frei in git“ ist eine Vereinfachung der Tatsachen , weil es nicht „frei“ per se ist. Wenn man unter die Haube schaut, könnte man eher behaupten, dass das Verzweigen redonkulös billig ist , da es sich bei den Verzweigungen im Grunde um Verweise auf Commits handelt . Ich definiere "Billigkeit" hier als je weniger Overhead desto billiger.

Lassen Sie uns herausfinden, warum Git so "billig" ist, indem wir untersuchen, welche Art von Overhead es hat:

Wie werden Branches in Git implementiert?

Das Git-Repository .gitbesteht hauptsächlich aus Verzeichnissen mit Dateien, die von Git verwendete Metadaten enthalten. Wann immer Sie einen Zweig in Git erstellen git branch {name_of_branch}, passieren zum Beispiel einige Dinge:

  • Ein Verweis auf die lokale Niederlassung wird erstellt unter: .git/refs/heads/{name_of_branch}
  • Für die lokale Niederlassung wird ein Verlaufsprotokoll erstellt unter: .git/logs/refs/heads/{name_of_branch}

Im Grunde genommen werden ein paar Textdateien erstellt. Wenn Sie die Referenz als Textdatei öffnen, ist der Inhalt die ID des Commits, auf das der Zweig zeigt. Beachten Sie, dass für die Verzweigung keine Festschreibungen erforderlich sind, da es sich um eine andere Art von Objekt handelt. Sowohl Filialen als auch Commits sind in git "erstklassige Bürger". Eine Möglichkeit besteht darin, die Beziehung zwischen Filialen und Commits als Aggregation und nicht als Komposition zu betrachten. Wenn Sie einen Zweig entfernen, bleiben die Commits als "Dangling" erhalten. Wenn Sie versehentlich einen Zweig entfernt haben, können Sie immer versuchen, das Commit mit git-lost-foundoder zu finden git-fsck --lost-foundund einen Zweig auf der Sha-ID zu erstellen, die Sie als hängen gelassen haben (und solange git noch keine Garbage Collection durchgeführt hat).

Wie kann git also nachverfolgen, an welchem ​​Zweig Sie arbeiten? Die Antwort ist mit der .git/HEADDatei, die ungefähr so ​​aussieht, wenn Sie im masterZweig sind.

ref: refs/heads/master

Beim Wechseln der Zweige wird lediglich der Verweis in der .git/HEADDatei geändert, und anschließend werden die Inhalte Ihres Arbeitsbereichs mit den im Festschreiben definierten Inhalten geändert.

Wie ist dies in anderen Versionskontrollsystemen zu vergleichen?

In Subversion sind Zweige virtuelle Verzeichnisse im Repository . Am einfachsten ist es also, mit einem Einzeiler aus der Ferne zu verzweigen svn copy {trunk-url} {branch-url} -m "Branched it!". Was SVN tun wird, ist das Folgende:

  • Kopieren Sie das Quellverzeichnis, zB trunkin ein Zielverzeichnis,
  • Übernehmen Sie die Änderungen, um die Kopieraktion abzuschließen.

Sie sollten diese Aktion remote auf dem Server ausführen, da das lokale Erstellen dieser Kopie eine Operation in linearer Zeit ist, bei der Dateien kopiert und mit Symbolen verknüpft werden. Dies ist eine sehr langsame Operation, während dies auf dem Server eine konstante Zeitoperation ist. Beachten Sie, dass Subversion auch beim Ausführen der Verzweigung auf dem Server beim Verzweigen eine Festschreibung erfordert, während dies bei git nicht der Fall ist. Dies ist ein wesentlicher Unterschied. Das ist eine Art Overhead, der SVN etwas billiger macht als Git.

Der Befehl zum Umschalten von Zweigen in SVN , dh svn switch, ist wirklich das svn updateVersteckte. Dank des Konzepts des virtuellen Verzeichnisses ist der Befehl in svn etwas flexibler als in git. Unterverzeichnisse in Ihrem Arbeitsbereich können ausgeschaltet werden, um eine andere Repository-URL zu spiegeln. Am nächsten wäre es, dies zu verwenden, git-submoduleaber es unterscheidet sich semantisch stark von der Verzweigung. Leider ist dies auch eine Entwurfsentscheidung, die das Umschalten in SVN etwas langsamer macht als in Git, da in jedem Arbeitsbereichsverzeichnis überprüft werden muss, welche Remote-URL gespiegelt wird. Nach meiner Erfahrung ist Git schneller beim Wechseln von Zweigen als SVN.

Die Verzweigung von SVN ist mit Kosten verbunden, da Dateien kopiert werden und immer öffentlich verfügbar sein müssen. In git sind Zweige, wie oben erläutert, "nur Referenzen" und können in Ihrem lokalen Repository aufbewahrt und nach Ihrem Ermessen veröffentlicht werden. Nach meiner Erfahrung ist SVN jedoch immer noch bemerkenswert billiger und performanter als zB ClearCase.

Es ist nur ein Mist, dass SVN nicht dezentralisiert ist. Sie können mehrere Repositorys für einige Quellrepositorys spiegeln, aber das Synchronisieren unterschiedlicher Änderungen mehrerer SVN-Repositorys ist nicht möglich, da SVN keine eindeutigen Bezeichner für Commits hat (git hat Bezeichner, die auf dem Inhalt des Commits basieren). Der Grund, warum ich persönlich angefangen habe, Git über SVN zu verwenden, ist, dass das Initiieren eines Repositorys in Git bemerkenswert einfacher und billiger ist . Im Hinblick auf das Software-Konfigurationsmanagement ist jede abweichende Kopie eines Projekts (Klon, Gabel, Arbeitsbereich oder was auch immer) eine "Verzweigung", und angesichts dieser Terminologie ist das Erstellen einer neuen Kopie in SVN nicht so billig wie bei Git, wo letzteres der Fall ist Zweige "eingebaut".

In Mercurial begann die Verzweigung ein wenig anders als bei DVCS, und das Erstellen / Zerstören benannter Verzweigungen erforderte separate Festschreibungen. Mercurial Entwickler implementiert später in der Entwicklung von Lesezeichen zu imitieren , obwohl gleichen Verzweigungsmodell git headsgenannt tipsund branchessind bookmarksstattdessen in Quecksilber-Terminologie.

Spoike
quelle
Wow. Vielen Dank für die "teure" Erklärung.
Laggingreflex
2
Aus Ihrer eigenen Quelle: This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.- Das Erstellen der Verzweigung ist in SVN trivial, es sei denn, Sie erstellen explizit eine Kopie jeder Datei.
Bobson
@ Bobson Ich habe überlegt, die Teile beim Verzweigen umzuschreiben, da ich diesbezüglich viel Handwinken mache, aber mein Standpunkt ist immer noch, dass ein Commit erforderlich ist , um einen Zweig zu erstellen, während dies in Git nicht der Fall ist . In meiner bescheidenen Erfahrung habe ich immer noch das Gefühl, dass das Wechseln zwischen Zweigen in SVN langsamer ist als in Git, aber ich kann keinen bestimmten Grund angeben, warum.
Spoike
2
@Spoike - Wechseln, sicher. Und ein Commit ist definitiv erforderlich. Ich habe eine Änderung vorgenommen, um das Problem zu klären. Sie können es jederzeit zurücksetzen, wenn Sie es vorziehen.
Bobson
20

Die tatsächlichen Kosten einer Niederlassung verschmelzen. Git macht dies einfacher als einige andere Versionsverwaltungssysteme. Siehe Stapelüberlauf Frage Wie und / oder warum ist das Zusammenführen in Git besser als in SVN? .

dan_waterworth
quelle
5
Streng genommen macht Git es nur einfacher als einige andere SCMs.
Donal Fellows
10

In Git bezieht sich eine Verzweigung lediglich auf ein Commit für das lokale Repo. Es ist sehr billig, überhaupt kein Netzwerk. Nicht ganz frei (man muss einen Befehl eingeben), aber verdammt nahe.

Das Verzweigen ist in SVN nicht besonders teuer - es ist nur eine Kopie, was ein sehr billiges Commit ist. SVN hat ein zentrales Repository-Modell, es ist also ein Netzwerkzugriff, aber kein schrecklicher.

Im ehrwürdigen CVS hingegen ist die Verzweigung SEHR teuer. Grundsätzlich wird in CVS-Zweigen ein Tag hinzugefügt. In CVS bedeutet dies jedoch, dass JEDE BETROFFENE DATEI geändert werden muss. Jede Datei wird neu geschrieben, um das neue Tag aufzunehmen. Das ist furchtbar teuer. Und wenn Ihr Repository groß ist, ist es auch schrecklich langsam. In der Tat, wenn Sie an einem großen Projekt arbeiten, ist es langsam genug, dass manche Leute es vermeiden, Zweige zu machen, wenn sie können.

Michael Kohne
quelle
4
Mit Git ist es noch weniger als ein Commit - ein Zweig ist nur ein Label. Und SVN klingt so teuer wie CVS, da beide alle Dateien kopieren.
Izkata
8
@Izkata: Wenn wir aus Anwendersicht sehen - ja, alle Dateien werden kopiert, aus Sicht der Implementierung (und Leistung) - nein, es wird nur eine Aufzeichnung über die Kopie hinzugefügt.
maxim1000
@ Izkata zu viel zu kommentieren - siehe meine Antwort.
gbjbaanb
6
@Izkata SVN erstellt Zeiger und Referenzen, es wird nicht alles kopiert.
Aaron McIver
2
Ein Git-Zweig ist kein Commit, sondern lediglich eine Referenz auf ein Commit, das frei auf andere Commits verschoben werden kann. Stellen Sie sich ein Git-Repo als einen Baum von Commits vor und Zweige als Haftnotizen, die sich frei auf verschiedene Commits in diesem Baum verschieben lassen.
40XUserNotFound
5

Die Verzweigung von SVN ist so kostenlos wie die von Git. Es sind nur ein paar Housekeeping-Daten, aus denen hervorgeht, wo die Verzweigung beginnt, und keine Änderungen an den gespeicherten Dateien. Eine 'Kopie' in SVN ist wie das Hinzufügen eines Symlinks zu einem Unix-Verzeichnis. Beachten Sie, dass der SVN-Zweig keine Netzwerkauslösung erfordert, bis Sie Ihre Änderungen an der Arbeitskopie festschreiben (aber es hat nicht viel Sinn, einen SCM zu haben, wenn Sie nicht zu einem bestimmten Zeitpunkt eine Off-Local-Festschreibung durchführen).

Beachten Sie, dass eine Git-Verzweigung auch einen gewissen Verwaltungsaufwand mit sich bringt - wie das interne Hinzufügen dieses Tags -, der beim Festschreiben irgendwo gespeichert werden muss. Es ist überhaupt keine große Sache, weshalb es "kostenlos" genannt wird.

gbjbaanb
quelle
5

Es ist 'kostenlos' (in diesem Zusammenhang bedeutet 'kostenlos' wirklich schnell und einfach und beansprucht keinen Platz), da in einigen älteren Versionskontrollsystemen eine Verzweigung zu diesem Zeitpunkt eine vollständige Kopie des Codes war, weshalb Verzweigungen viel Zeit in Anspruch nahmen Platz und es war leicht, mit vielen verschiedenen Vollversionen der Software zu enden, die dann das Management übernahmen. In anderen Fällen handelte es sich nicht um eine vollständige Kopie des Codes, aber jede Datei musste noch für ein Tag geändert werden, so dass dies langsam und schmerzhaft ("kostspielig") war.

Die Zweige von git sind im Wesentlichen Labels, die auf ein Commit zeigen, und vermeiden daher die oben genannten Probleme.

Michael Durrant
quelle
1

Ein weiterer Aspekt von "kostenlos / billig / teuer" besteht darin, wie viel Entwicklerressourcen kosten, um die nachgelagerten Folgen der Verzweigung zu bewältigen. dh der Prozess des Zusammenführens ändert sich von Zweigen.

Und hier ist das Zusammenführen von Zweigen in DVCS-Systemen wie Git und Mercurial einfacher als in älteren Systemen. dh wo vorher eine Verzweigung stattgefunden hat, ist eine Verschmelzung aufgetreten. Dies macht Zusammenführungen genauer, reduziert unnötige Konflikte und ... macht das Zusammenführen für die beteiligten Entwickler subjektiv "einfacher" oder "weniger beängstigend".

Stephen C
quelle