# Git-Submodule: Der umfassende Praxisleitfaden ## Inhalt - [Git-Submodule: Der umfassende Praxisleitfaden](#git-submodule-der-umfassende-praxisleitfaden) - [Inhalt](#inhalt) - [🔰 Was ist ein Git-Submodul?](#-was-ist-ein-git-submodul) - [🧱 Grundlagen](#-grundlagen) - [📌 `.gitmodules`](#-gitmodules) - [🧠 Merksatz](#-merksatz) - [🛠️ Submodul hinzufügen](#️-submodul-hinzufügen) - [🔄 Submodule aktualisieren](#-submodule-aktualisieren) - [📥 Klonen mit Submodulen](#-klonen-mit-submodulen) - [Methode 1: Inklusive Submodule](#methode-1-inklusive-submodule) - [Methode 2: Nachträglich initialisieren](#methode-2-nachträglich-initialisieren) - [🔃 Submodul-Synchronisation](#-submodul-synchronisation) - [📂 Weitere Remotes im Submodul](#-weitere-remotes-im-submodul) - [❗ Stolperfallen und Besonderheiten](#-stolperfallen-und-besonderheiten) - [🔄 Remote-URL wechseln](#-remote-url-wechseln) - [🚀 Push \& Pull Verhalten](#-push--pull-verhalten) - [🧼 Submodul löschen](#-submodul-löschen) - [🧰 Best Practices](#-best-practices) - [📎 Nützliche Kommandos](#-nützliche-kommandos) - [📑 Beispiel `.gitmodules` mit kommentierter Remote-Auswahl](#-beispiel-gitmodules-mit-kommentierter-remote-auswahl) - [🧭 Alternative: Subtree statt Submodul?](#-alternative-subtree-statt-submodul) - [📚 Fazit](#-fazit) - [🔗 Weiterführende Links](#-weiterführende-links) --- ## 🔰 Was ist ein Git-Submodul? Ein **Submodul** ist ein Git-Repository innerhalb eines anderen Git-Repositories. Es erlaubt, einen festen Commit eines externen Repositories als Teilprojekt einzubinden, ohne dessen Dateien direkt zu übernehmen. Beispielhafte Struktur: ```plaintext hauptprojekt/ ├── .gitmodules ├── modul1/ ← eingebundenes Submodul └── modul2/ ``` ## 🧱 Grundlagen ### 📌 `.gitmodules` Diese Datei beschreibt Pfad und Remote-URL aller eingebundenen Submodule: ```ini [submodule "modul1"] path = modul1 url = git@github.com:user/modul1.git ``` ### 🧠 Merksatz > Submodule sind **Pointer auf einen bestimmten Commit** eines anderen Repositories. ## 🛠️ Submodul hinzufügen ```bash git submodule add git commit -m "📦 Submodul hinzugefügt" ``` Beispiel: ```bash git submodule add git@github.com:user/libmath.git extern/libmath ``` Erzeugt: - `.gitmodules` - Verzeichniseintrag im Git-Index - Initialer Checkout des Submoduls (HEAD auf Remote-Commit) ## 🔄 Submodule aktualisieren ```bash cd extern/libmath git pull origin main cd ../.. git add extern/libmath git commit -m "🔄 Submodul libmath aktualisiert" ``` > Nur das **Hauptrepo speichert den Commit-Zeiger**, nicht den Submodul-Inhalt selbst. ## 📥 Klonen mit Submodulen ### Methode 1: Inklusive Submodule ```bash git clone --recurse-submodules ``` ### Methode 2: Nachträglich initialisieren ```bash git clone git submodule update --init ``` ## 🔃 Submodul-Synchronisation Wenn sich `.gitmodules` ändert (z. B. Remote-URL): ```bash git submodule sync ``` ## 📂 Weitere Remotes im Submodul ```bash cd modul1 git remote add backup git@backup.server:repo.git ``` > Diese Remotes sind **lokal**, nicht versioniert. `.gitmodules` kennt nur den Haupt-Remote. ## ❗ Stolperfallen und Besonderheiten | Problem | Erklärung | |--------|-----------| | Submodul wird nicht mitgeclont | `--recurse-submodules` vergessen | | Änderungen im Submodul nicht sichtbar | Submodul-Commit im Hauptrepo nicht geupdated | | `.gitmodules` zeigt nicht funktionierende URL | z. B. lokale URL nach GitHub-Push – muss angepasst werden | | Submodul zeigt „detached HEAD“ | normaler Zustand, wenn Submodul auf festen Commit gesetzt ist | ## 🔄 Remote-URL wechseln ```bash # In .gitmodules ändern oder per Befehl: git config -f .gitmodules submodule.modul1.url git@github.com:newuser/libmath.git git submodule sync ``` ## 🚀 Push & Pull Verhalten | Aktion | Wirkung | |---------------------|---------| | `git push` im Hauptrepo | Pusht nur Zeiger auf Submodul-Commit | | `git push` im Submodul | Muss separat erfolgen | | `git pull` im Hauptrepo | Holt *nicht* automatisch neuen Submodul-Stand | ## 🧼 Submodul löschen ```bash # Schritt 1: Entfernen git submodule deinit -f pfad/zum/modul git rm -f pfad/zum/modul rm -rf .git/modules/pfad/zum/modul git commit -m "❌ Submodul entfernt" ``` ## 🧰 Best Practices - **Nur stabile Submodul-Commits einchecken**, keine laufenden Branches. - **Submodule niemals blind aktualisieren** – Änderungen genau prüfen. - **Remote-Umschaltung dokumentieren oder automatisieren**, z. B. per Script. - **Submodule klein halten** – große, tief verschachtelte Strukturen vermeiden. - Für wiederverwendbare Bibliotheken oder Assets ideal (CAD, Snippets, Markdown, etc.). ## 📎 Nützliche Kommandos ```bash git submodule status # Überblick über alle Submodule git submodule update --init # Submodule initial holen git submodule update --remote # Auf neuesten Remote-Stand updaten git config -f .gitmodules ... # .gitmodules direkt bearbeiten ``` ## 📑 Beispiel `.gitmodules` mit kommentierter Remote-Auswahl ```ini [submodule "modul1"] path = modul1 url = ssh://git@local.example.com:2222/myorg/modul1.git # url = git@github.com:myorg/modul1.git ``` ## 🧭 Alternative: Subtree statt Submodul? Subtree ist einfacher zu verwalten, aber: - kein fester Commit-Zeiger, - kein Remote-Wechsel ohne Umweg, - gemergte Historie im Hauptrepo. **Submodul = getrennte Repos** **Subtree = eingemergter Inhalt** ## 📚 Fazit Git-Submodule sind mächtig, aber erfordern **Disziplin und Überblick**. Für wiederverwendbare Komponenten, zentral gepflegte Inhalte oder externe Bibliotheken sind sie oft die bessere Wahl als Duplikate oder Copy-Paste. ## 🔗 Weiterführende Links - [Git Book: Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) - [git-scm Doku: submodule](https://git-scm.com/docs/git-submodule) - [Vergleich Submodule vs. Subtree](https://www.atlassian.com/git/tutorials/git-submodule)