Schließlich wird jedes interessante Softwareprojekt von einem anderen Projekt, einer Bibliothek oder einem anderen Framework abhängen. Git bietet Submodule, um dabei zu helfen. Mit Submodulen können Sie ein oder mehrere Repositorys als Unterordner in ein anderes Repository aufnehmen oder einbetten.
Für viele Projekte sind Submodule nicht die beste Antwort (mehr dazu unten), und selbst das Arbeiten mit Submodulen kann schwierig sein, aber schauen wir uns zunächst ein einfaches Beispiel an.,
Hinzufügen eines Submoduls
Angenommen, Sie arbeiten an einem Projekt namens Slingshot. Sie haben Code für y-shaped stick
und eine rubber-band
.
flickr-Foto geteilt von young@art unter einer Creative Commons ( BY ) license
Zur gleichen Zeit, in einem anderen repository, hast du ein anderes Projekt namens Rock—es ist nur ein generischer rock
Bibliothek, aber Sie denken, es wäre perfekt für Schleuder.
Sie können rock
als Submodul von slingshot
hinzufügen., Imslingshot
Repository:
Zu diesem Zeitpunkt haben Sie einen rock
Ordner in slingshot
, aber wenn Sie je nach Version von Git in diesen Ordner schauen würden, sehen Sie möglicherweise … nichts.,
Neuere Versionen von Git tun dies automatisch, aber ältere Versionen erfordern, dass Sie Git explizit anweisen, den Inhalt von rock
herunterzuladen:
Wenn alles gut aussieht, können Sie diese Änderung festschreiben und Sie haben eine rock
Ordner im slingshot
repository mit dem gesamten Inhalt aus dem rock
Repository.,
Auf GitHub hat das Ordnersymbol rock
einen kleinen Indikator, der anzeigt, dass es sich um ein Submodul handelt:
Und wenn Sie auf den Ordner rock
klicken, gelangen Sie zum Repository rock
.
Das war ‚ s! Sie haben das Repository rock
in das Repository slingshot
eingebettet. Sie können mit dem gesamten Inhalt von rock
interagieren, als wäre es ein Ordner in (weil dies der Fall ist).,
In der Befehlszeile funktionieren Git-Befehle, die von slingshot
(oder einem der anderen Ordner, rubber-band
und y-shaped-stick
) ausgegeben werden, auf dem „übergeordneten Repository“, slingshot
, aber Befehle, die Sie von der rock
Ordner funktioniert nur mit dem rock
Repository:
Beitreten zu einem Projekt mit Submodulen
Angenommen, Sie sind ein neuer Mitarbeiter, der an Project Slingshot teilnimmt., Zunächst führen Sie git clone
aus, um den Inhalt des slingshot
– Repositorys herunterzuladen. An diesem Punkt, wenn Sie in den rock
Ordner schauen würden, würden Sie sehen … nichts.
Auch hier erwartet Git, dass wir es explizit bitten, den Inhalt des Submoduls herunterzuladen., Sie können auch hier git submodule update --init --recursive
verwenden, aber wenn Sie slingshot
zum ersten Mal klonen, können Sie einen modifizierten clone
Befehl verwenden, um sicherzustellen, dass Sie alles herunterladen, einschließlich aller Submodule:
Wechseln zu Submodulen
Es kann es ist etwas schwierig, einen vorhandenen Unterordner in eine externe Abhängigkeit umzuwandeln. Schauen wir uns ein Beispiel an.
Sie sind dabei, ein neues Projekt zu starten—eine magische Rollback-Dose-die auch eine rubber-band
benötigt., Nehmen wir die rubber-band
, die Sie für slingshot
erstellt haben, teilen Sie sie in ein eigenständiges Repository auf und betten Sie sie dann über Submodule in beide Projekte ein.
Sie können alles aus dem rubber-band
– Ordner des Projekts Slingshot entnehmen und in ein neues Repository extrahieren und sogar den Commit-Verlauf beibehalten.
Beginnen wir mit dem Extrahieren des Inhalts des Ordners rubber-band
aus slingshot
., Sie können dazu git filter-branch
, sodass Sie nur die Commits für rubber-band
. Der Befehl git filter-branch
schreibt den Verlauf unseres Repositorys neu, sodass es so aussieht, als wäre der Ordner rubber-band
Es war die ganze Zeit ein eigenes Repository. Weitere Informationen zu git filter-branch
finden Sie in diesem Artikel.
Der erste Schritt besteht darin, eine Kopie von slingshot
zu erstellen—das Endziel ist, dass rubber-band
als eigenes Repository steht, also lassen Sie slingshot
unverändert., Sie können cp
mit -r
rekursiv den gesamten slingshot
Ordner in einen neuen Ordner rubber-band
kopieren.,
Es sieht aus wie rubber-band
ist nur eine andere slingshot
, aber jetzt, von der rubber-band
repository, run git filter-branch
:
An dieser Stelle haben Sie einen Ordner rubber-band
, ein Repository, das einer Projektschleuder ähnelt, aber nur die Dateien und den Commit-Verlauf aus dem Ordner rubber-band
.,
Da Sie dies von slingshot
kopiert haben, verfügt das neue Repository weiterhin über Remote-Tracking-Zweige, die Sie eingerichtet haben, als es slingshot
war. Sie möchten rubber-band
nicht zurück auf slingshot
drücken. Sie möchten dies in ein neues Repository verschieben.
Erstellen Sie ein neues Repository für rubber-band
auf GitHub und aktualisieren Sie dann die Fernbedienung für rubber-band
., Angenommen, Sie rufen die Remote – origin
, könnten Sie:
Dann können Sie das neue“ generische Gummibandmodul“mit git push
veröffentlichen.,
Nachdem Sie rubber-band
in ein eigenes Repository getrennt haben, müssen Sie den alten rubber-band
-Ordner aus dem slingshot
-Repository löschen:
Aktualisieren Sie dann slingshot
, um rubber-band
als Submodul:
Wie wir zuvor gesehen haben, als wir rock
hinzugefügt haben, haben wir jetzt ein Repository-in-a-repository., Tatsächlich drei Repositorys: das“ übergeordnete“Repository slingshot
sowie die beiden“ Sub“ – Repositorys rock
und rubber-band
.
Wenn wir zurück in die Geschichte von slingshot
eintauchen, sehen wir die Commits, die wir ursprünglich in rubber-band
gemacht haben, als es sich um einen Ordner handelte—das Löschen des Ordners löschte keinen der Historie., Dies kann manchmal etwas verwirrend sein-da dasrubber-band
„child“ Repository eine kopierte und modifizierte Version dieser altenslingshot
Commits hat, kann es manchmal das Gefühl haben, déja vu zu haben.
Leider hat jeder Mitarbeiter, der an dieser Stelleslingshot
zieht, einen leerenrubber-band
Ordner., Möglicherweise möchten Sie Ihre Mitarbeiter daran erinnern, diesen Befehl auszuführen, um sicherzustellen, dass sie über den gesamten Inhalt des Submoduls verfügen:
Sie möchten auch das hinzufügen rubber-band
Submodul zu magic roll-back can
. Glücklicherweise müssen Sie nur das gleiche Verfahren befolgen, das Sie zuvor verwendet haben, als Sie rock
zu slingshot
in „Hinzufügen eines Submoduls.“
Hinweise zur Verwendung von Submodulen (oder nicht)
- Bevor Sie ein Repository als Submodul hinzufügen, überprüfen Sie zunächst, ob eine bessere Alternative verfügbar ist., Git-Submodule funktionieren gut genug für einfache Fälle, aber heutzutage gibt es oft bessere Tools zum Verwalten von Abhängigkeiten als das, was Git-Submodule bieten können. Moderne Sprachen wie Go verfügen von Anfang an über freundliche, Git-fähige Abhängigkeitsmanagementsysteme. Andere, wie Rubys Rubygems, Knoten.js ‚ npm oder CocoaPods und Karthago von Cocoa wurden von der Programmiergemeinschaft hinzugefügt. Sogar Front-End-Entwickler verfügen über Tools wie Bower zum Verwalten von Bibliotheken und Frameworks für clientseitiges JavaScript und CSS.
- Denken Sie daran, dass Git standardmäßig keine Submodule-Inhalte herunterlädt., Wenn Sie einem vorhandenen Projekt ein Submodul hinzufügen, stellen Sie sicher, dass jeder, der an dem Projekt arbeitet, weiß, dass er Befehle wie
git submodule update
undgit clone --recursive
ausführen muss, um sicherzustellen, dass er alles erhält-dies schließt alle automatisierten Bereitstellungs – oder Testdienste ein, die möglicherweise an dem Projekt beteiligt sind! Wir empfehlen Ihnen, so etwas wie unsere „Scripts to Rule Them All“ zu verwenden, um sicherzustellen, dass alle Mitarbeiter und Dienste überall Zugriff auf dieselben Repository-Inhalte haben. - Submodule erfordern eine sorgfältige Abwägung von Konsistenz und Komfort., Das hier verwendete Setup bevorzugt die Konsistenz auf Kosten eines kleinen Komforts. Es ist im Allgemeinen am besten, die Submodule eines Projekts an eine bestimmte SHA zu sperren, damit alle Mitarbeiter denselben Inhalt erhalten. Dieses Setup macht es Entwicklern im „übergeordneten“ Repository jedoch auch schwer, Änderungen wieder in das Submodul-Repository einzubringen.
- Denken Sie daran, dass Mitarbeiter Aktualisierungen von Submodulen nicht automatisch sehen—wenn Sie ein Submodul aktualisieren, müssen Sie Ihre Kollegen möglicherweise daran erinnern,
git submodule update
auszuführen, oder sie werden wahrscheinlich seltsames Verhalten sehen., - Die Verwaltung dynamischer, sich schnell entwickelnder oder stark co-abhängiger Repositorys mit Submodulen kann schnell frustrierend werden. Dieser Beitrag konzentrierte sich auf einfache, relativ statische Eltern-Kind-Repository-Beziehungen. In einem zukünftigen Follow-up-Beitrag werden einige Strategien zur Verwaltung komplexerer Submodule-Workflows beschrieben.