Git-Untermodule
Mit Git-Untermodulen kannst du ein Git-Repository als Unterverzeichnis eines anderen Git-Repositorys führen. Git-Untermodule sind einfach ein Verweis auf ein anderes Repository zu einem bestimmten Zeitpunkt. Git-Untermodule ermöglichen einem Git-Repository, den Versionsverlauf von externem Code zu integrieren und zu verfolgen.
Was ist ein Git-Untermodul?
Oft hängt ein Code-Repository von externem Code ab. Dieser externe Code kann auf verschiedene Arten aufgenommen werden. Der externe Code kann direkt kopiert und in das Haupt-Repository eingefügt werden. Diese Methode hat den Nachteil, dass alle Upstream-Änderungen am externen Repository verloren gehen. Eine weitere Methode zur Integration von externem Code ist die Verwendung des Paketverwaltungssystems einer Sprache wie Ruby Gems oder NPM. Diese Methode hat den Nachteil, dass eine Installation und Versionsverwaltung an allen Stellen erforderlich ist, an denen der ursprüngliche Code bereitgestellt wird. Bei beiden vorgeschlagenen Einarbeitungsmethoden gibt es keine Möglichkeit, Änderungen am externen Repository nachzuverfolgen.
Ein Git-Untermodul ist ein Datensatz in einem Host-Git-Repository, der auf einen bestimmten Commit in einem anderen externen Repository verweist. Untermodule sind sehr statisch und verfolgen nur bestimmte Commits. Untermodule verfolgen keine Git-Refs oder Branches und werden nicht automatisch aktualisiert, wenn das Host-Repository aktualisiert wird. Beim Hinzufügen eines Untermoduls zu einem Repository wird eine neue .gitmodules- Datei erstellt. Die .gitmodules-Datei enthält Metadaten über die Zuordnung zwischen der URL des Untermodul-Projekts und dem lokalen Verzeichnis. Wenn das Host-Repository über mehrere Untermodule verfügt, enthält die .gitmodules- Datei einen Eintrag für jedes Untermodul.
Wann solltest du ein Git-Untermodul verwenden?
Wenn du eine strikte Versionsverwaltung über deine externen Abhängigkeiten pflegen musst, kann es sinnvoll sein, Git-Untermodule zu verwenden. Im Folgenden sind einige der besten Verwendungszwecke für Git-Untermodule aufgeführt.
- Wenn eine externe Komponente oder ein Unterprojekt sich zu schnell ändert oder bevorstehende Änderungen nicht mit der API kompatibel sind, kannst du zur eigenen Sicherheit den Code für einen bestimmten Commit sperren.
- Wenn eine Komponente nicht sehr oft aktualisiert wird und du sie als Anbieterabhängigkeit verfolgen möchtest.
- Wenn du einen Teil des Projekts an eine Drittpartei delegierst und du deren Arbeit zu einem bestimmten Zeitpunkt oder in ein bestimmtes Release integrieren möchtest. Wie erwähnt funktioniert dies, wenn Updates nicht zu oft stattfinden.
Zugehöriges Material
Verschieben eines vollständigen Git-Repositorys
Lösung anzeigen
Git kennenlernen mit Bitbucket Cloud
Gängige Befehle für Git-Untermodule
Git-Untermodul hinzufügen
Der Befehl git submodule add
wird verwendet, um ein neues Untermodul zu einem vorhandenen Repository hinzuzufügen. Im Folgenden Beispiel werden ein leeres Repository erstellt und Git-Untermodule untersucht.
$ mkdir git-submodule-demo
$ cd git-submodule-demo/
$ git init
Initialized empty Git repository in /Users/atlassian/git-submodule-demo/.git/
Diese Befehlsfolge erstellt ein neues Verzeichnis namens git-submodule-demo
, gibt dieses Verzeichnis ein und initialisiert es als neues Repository. Als Nächstes fügen wir diesem neuen Repository ein Untermodul hinzu.
$ git submodule add https://bitbucket.org/jaredw/awesomelibrary
Cloning into '/Users/atlassian/git-submodule-demo/awesomelibrary'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
Der Befehl git submodule add
verwendet einen URL-Parameter, der auf ein Git-Repository verweist. Hier haben wir awesomelibrary
als Untermodul hinzugefügt. Git klont das Untermodul sofort. Wir können jetzt den aktuellen Status des Repository mithilfe von git status
überprüfen.
$ git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitmodules
new file: awesomelibrary
Es gibt jetzt zwei neue Dateien im .gitmodules
-Repository und im awesomelibrary
-Verzeichnis. Ein Blick auf den Inhalt von .gitmodules
zeigt das neue Untermodul-Mapping.
[submodule "awesomelibrary"]
path = awesomelibrary
url = https://bitbucket.org/jaredw/awesomelibrary
$ git add .gitmodules awesomelibrary/
$ git commit -m "added submodule"
[main (root-commit) d5002d0] added submodule
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 awesomelibrary
Git-Untermodule klonen
git clone /url/to/repo/with/submodules
git submodule init
git submodule update
Git-Untermodul-Init
Das Standardverhalten von git submodule init
ist das Kopieren des Mappings aus der .gitmodules
-Datei in die lokale ./.git/config
-Datei. Dies mag überflüssig erscheinen und dazu führen, dass die Nützlichkeit von git submodule init
infrage gestellt wird. git submodule init
hat ein erweitertes Verhalten, in dem es eine Liste expliziter Modulnamen akzeptiert. Dies ermöglicht einen Workflow, bei dem nur bestimmte Untermodule aktiviert werden, die für die Arbeit am Repository benötigt werden. Dies kann hilfreich sein, wenn es in einem Repository viele Untermodule gibt, die jedoch nicht alle für deine Arbeit abgerufen werden müssen.
Untermodul-Workflows
Sobald Untermodule in einem übergeordneten Repository ordnungsgemäß initialisiert und aktualisiert wurden, können sie genau wie eigenständige Repositorys verwendet werden. Das bedeutet, dass Untermodule ihre eigenen Branches und Verläufe haben. Wenn du Änderungen an einem Untermodul vornimmst, ist es wichtig, Änderungen an Untermodulen zu veröffentlichen und dann die Referenz des übergeordneten Repositorys auf das Untermodul zu aktualisieren. Fahren wir mit dem Beispiel der awesomelibrary
fort und nehmen einige Änderungen vor:
$ cd awesomelibrary/
$ git checkout -b new_awesome
Switched to a new branch 'new_awesome'
$ echo "new awesome file" > new_awesome.txt
$ git status
On branch new_awesome
Untracked files:
(use "git add <file>..." to include in what will be committed)
new_awesome.txt
nothing added to commit but untracked files present (use "git add" to track)
$ git add new_awesome.txt
$ git commit -m "added new awesome textfile"
[new_awesome 0567ce8] added new awesome textfile
1 file changed, 1 insertion(+)
create mode 100644 new_awesome.txt
$ git branch
main
* new_awesome
Hier haben wir das Verzeichnis in das Untermodul awesomelibrary geändert. Wir haben eine neue Textdatei namens new_awesome.txt
mit etwas Inhalt erstellt und diese neue Datei zum Untermodul hinzugefügt und committet. Ändern wir nun die Verzeichnisse zurück zum übergeordneten Repository und überprüfen den aktuellen Status des übergeordneten Repositorys.
$ cd ..
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: awesomelibrary (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
Das Ausführen von git status
zeigt uns, dass das übergeordnete Repository die neuen Commits für das Untermodul awesomelibrary
kennt. Die Ausgabe geht nicht detailliert auf einzelne Aktualisierungen ein, da dies in der Verantwortung der Untermodul-Repositorys liegt. Das übergeordnete Repository befasst sich nur mit dem Anheften des Untermoduls an einen Commit. Jetzt können wir das übergeordnete Repository erneut aktualisieren, indem wir git add
und git commit
für das Untermodul ausführen. Dadurch wird alles mit den lokalen Inhalten in einen guten Zustand versetzt. Wenn du in einer Teamumgebung arbeitest, ist es wichtig, dass du git push
dann auf die Untermodul-Aktualisierungen und die Aktualisierungen des übergeordneten Repositorys anwendest.
Bei der Arbeit mit Untermodulen ist eine häufige Fehlerquelle, dass vergessen wird, Aktualisierungen für Remote-Benutzer zu pushen. Wenn wir uns die Arbeit an awesomelibrary
von gerade eben noch einmal ansehen, haben wir nur die Aktualisierungen in das übergeordnete Repository übertragen. Ein anderer Entwickler würde einen Pull auf das neueste übergeordnete Repository durchführen, das auf einen Commit von awesomelibrary
zeigen würde, für den er keinen Pull durchführen konnte, weil wir vergessen hatten, das Untermodul zu pushen. Dies würde das lokale Repository der Remote-Entwickler zerstören. Um dieses Fehlerszenario zu vermeiden, musst du immer daran denken, das Untermodul und das übergeordnete Repository zu committen und zu pushen.
Fazit
Git-Untermodule sind eine leistungsstarke Möglichkeit, Git als externes Tool zur Verwaltung von Abhängigkeiten zu nutzen. Wäge die Vor- und Nachteile von Git-Untermodulen ab, bevor du sie verwendest, da sich deine Teammitglieder möglicherweise in diese erweiterte Funktion erst einarbeiten müssen.
Diesen Artikel teilen
Nächstes Thema
Lesenswert
Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.