Was ist der Sinn von ‘git submodule init’?

Lesezeit: 5 Minuten

Hintergrund

Um die Submodule eines Repositorys zu füllen, ruft man normalerweise auf:

git submodule init
git submodule update

Bei dieser Verwendung git submodule init scheint nur eines zu tun: bevölkern .git/config mit Informationen, die bereits vorhanden sind .gitmodules.

Was ist der Sinn davon?

Konnte nicht git submodule update Verwenden Sie einfach die Informationen von .gitmodules? Dies würde beides vermeiden:

  • ein unnötiger Befehl (git submodule init); und
  • eine unnötige Duplizierung von Daten (.gitmodules Inhalt hinein .git/config).

Frage

Entweder:

  • Es gibt Anwendungsfälle für git submodule init dass ich es nicht weiß (in diesem Fall klärt mich bitte auf!); oder aber
  • git submodule init ist Cruft, der in Git ohne Schaden als veraltet markiert werden könnte.

Welche davon ist wahr?

Benutzer-Avatar
Nigiri

Stellen Sie sich vor, das Repository hat 10 Submodule und Sie interessieren sich nur für zwei Submodule davon. In einem solchen Fall möchten Sie möglicherweise von Zeit zu Zeit nur Aktualisierungen von diesen beiden Submodulen aus dem Remote-Repository erhalten. git init funktioniert gut dafür, denn sobald Sie den Befehl ausführen git init für diese beiden Teilmodule git submodule update --remote gilt nur für sie.


Demo mit zwei Workflows angehängt.

Workflow1: Submodule sind Bibliotheken, die mehrere Projekte verwenden.

Ich denke, das ist einer der häufigsten Anwendungsfälle.

Sie haben gerade “my-project” geklont.

git clone https://example.com/demo/my-project

Und die Oberfläche seiner Struktur ist wie unten.

Geben Sie hier die Bildbeschreibung ein

Der Inhalt von .gitmodules

[submodule "lib1"]
    path = lib1
    url = https://example.com/demo/lib1
[submodule "lib2"]
    path = lib2
    url = https://example.com/demo/lib2
[submodule "lib3"]
    path = lib3
    url = https://example.com/demo/lib3
[submodule "lib4"]
    path = lib4
    url = https://example.com/demo/lib4

Sie möchten den Code umgestalten code1.js die auf lib1 und lib2 verweist, was bedeutet, dass Sie lib3 und lib4 nicht klonen und auschecken müssen. Sie führen also einfach den folgenden Befehl aus.

git submodule init lib1 lib2

Sehen wir uns nun den Inhalt von an .git/config

...
[submodule "lib1"]
    active = true
    url = https://example.com/demo/lib1
[submodule "lib2"]
    active = true
    url = https://example.com/demo/lib2

Dies bedeutet so viel wie „Bereit zum Aktualisieren von lib1 und lib2 von example.com/demo“.

Zu diesem Zeitpunkt sind die Verzeichnisse lib1 und lib2 leer. Sie können lib1 und lib2 mit einem Befehl klonen und auschecken:

git submodule update

Jetzt können Sie umgestalten code1.js ohne Importfehler.

Submodule sind nur Verweise auf bestimmte Commits. Wenn Sie also Bibliotheken auf neue Versionen aktualisieren möchten, müssen Sie die Referenzen aktualisieren. Sie können dies mit dem folgenden Befehl tun.

git submodule update --remote

Jetzt können Sie sehen, wie nützlich es ist, nur die Submodule zu initialisieren, die Sie benötigen.

Arbeitsablauf 2: Jedes Untermodul ist ein Projekt und ein Big-Top-Projekt enthält sie.

Ich bin ein Fan davon.

Sie klonen “Hauptprojekt”.

git clone https://example.com/demo/main-project

Und die Oberfläche seiner Struktur ist wie unten.

Geben Sie hier die Bildbeschreibung ein

Sie können ein Verzeichnis namens “shared” sehen. In diesem Arbeitsablauf gibt es eine Regel: Wenn Sie gemeinsam genutzte Codes des Hauptprojekts in Ihrem Projekt verwenden möchten, müssen Sie das Projekt als Untermodul des Hauptprojekts erstellen.

Ich mag es, Entitätsklassen wie unten in einem freigegebenen Verzeichnis abzulegen.

Geben Sie hier die Bildbeschreibung ein

Zurück zum Submodul-Workflow, der Inhalt von .gitmodules ist wie folgt.

[submodule "sub-project1"]
    path = sub-project1
    url = https://example.com/demo/sub-project1
[submodule "sub-project2"]
    path = sub-project2
    url = https://example.com/demo/sub-project2
[submodule "sub-project3"]
    path = sub-project3
    url = https://example.com/demo/sub-project3
[submodule "sub-project4"]
    path = sub-project4
    url = https://example.com/demo/sub-project4

Dieses Mal möchten Sie Code im freigegebenen Verzeichnis des Hauptprojekts umgestalten und wissen, dass nur Unterprojekt1 und Unterprojekt2 auf freigegebenen Code verweisen, was bedeutet, dass Sie Unterprojekt3 und Unterprojekt nicht klonen und auschecken müssen. Projekt4. Sie führen also einfach den folgenden Befehl aus.

git submodule init sub-project1 sub-project2

Und wie ich in Workflow1 erwähnt habe, müssen Sie den folgenden Befehl ausführen, um sie zu klonen und auszuchecken.

git submodule update

Würde ich tun git submodule update --remote in diesem Fall? Oder muss ich sogar Submodule initieren und aktualisieren, um Code im freigegebenen Verzeichnis umzugestalten? Ja, denn Sie müssen nach dem Refactoring des gemeinsam genutzten Codes Tests in Submodulen ausführen, und wenn während des Refactorings ein Update von Submodulen festgeschrieben und an das Remote-Repository gepusht wird, müssen Sie es durchziehen git submodule update --remote.

  • Danke für den Hinweis git submodule init könnte in diesem Anwendungsfall hilfreich sein. Ich habe es noch nicht ausprobiert, aber ich habe Ihre Antwort positiv bewertet, weil sie mich dazu gebracht hat, breiter über Git-Submodul-Workflows nachzudenken 🙂 Würde es Ihnen etwas ausmachen, einen Codeblock hinzuzufügen, der den von Ihnen angedeuteten Workflow veranschaulicht? Ich denke, dies würde zu einer Antwort führen, die für die Community noch wertvoller ist. Danke noch einmal 🙂

    Benutzer82216

    5. Oktober 2017 um 19:47 Uhr

  • Danke für die Korrektur meines Englisch. Ich habe zwei Workflows hinzugefügt. Ich bin mir nicht sicher, ob dies jemandem hilft.

    – Nigiri

    6. Oktober 2017 um 9:07 Uhr

  • Wenn Sie andere Submodule haben und nur einige bestimmte Submodule initialisieren und aktualisieren möchten, wird der Workflow wie folgt: [git submodule init — ./lib1 ./lib2] und [git submodule update –remote –recursive — ./lib1 ./lib2]. Könntest du auch verwenden [–merge] oder [–rebase] mit dem Update-Befehl, aber lesen Sie zuerst, was sie tun, weil sie ein getrenntes Head-Checkout auf die Gefahr hin vermeiden können, dass ihr Verlauf möglicherweise verstümmelt wird, wenn HEAD während des Updates nicht auf dem richtigen Zweig ist. Vorerst könnten Sie den abgetrennten Kopfzustand mit beheben [git submodule foreach “git checkout master && git pull”] (Submodule so lustig und einfach zu bedienen xD)

    – FocusedWolf

    30. September 2018 um 5:55 Uhr


Lesen der git submodule Dokumentationdort ist ein Anwendungsfall, der angeblich die Existenz rechtfertigt git submodule init als eigenständiger Befehl.

Wenn ein Benutzer, der ein Repository geklont hat, eine andere URL für ein Submodul verwenden möchte, als im Upstream-Repository angegeben ist, kann dieser Benutzer:

git submodule init
vim .git/config # Alter submodule URL as desired, without changing .gitmodules
                # or polluting history.
git submodule update

  • Zum Beispiel, wenn das Submodul groß ist und Sie es aus anderen Gründen bereits lokal haben. git config -f .gitmodules submodule.biglib.url=/path/to/it ist einfacher als die Bearbeitung der Datei, und git submodule update --init ist einfacher als die Zwei-Schritt-Methode, wenn Sie mit den Standardeinstellungen zufrieden sind.

    – jthill

    6. Oktober 2017 um 11:07 Uhr

1320720cookie-checkWas ist der Sinn von ‘git submodule init’?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy