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 .git
besteht 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-found
oder zu finden git-fsck --lost-found
und 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/HEAD
Datei, die ungefähr so aussieht, wenn Sie im master
Zweig sind.
ref: refs/heads/master
Beim Wechseln der Zweige wird lediglich der Verweis in der .git/HEAD
Datei 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
trunk
in 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 update
Versteckte. 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-submodule
aber 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 heads
genannt tips
und branches
sind bookmarks
stattdessen in Quecksilber-Terminologie.