Was ist der Sinn von 'git submodule init'?

72

Hintergrund

Um die Submodule eines Repositorys zu füllen, wird normalerweise Folgendes aufgerufen :

git submodule init
git submodule update

In dieser Verwendung git submodule initscheint nur eines zu tun: .git/configmit Informationen füllen, die bereits in sind .gitmodules.

Was ist der Sinn davon?

Konnten Sie git submodule updatedie Informationen von nicht einfach verwenden .gitmodules? Dies würde beides vermeiden:

  • ein unnötiger Befehl ( git submodule init); und
  • eine unnötige Vervielfältigung von Daten ( .gitmodulesInhalt in .git/config).

Frage

Entweder:

  • Es gibt Anwendungsfälle git submodule init, die ich nicht kenne (in diesem Fall klären Sie mich bitte auf!). oder aber
  • git submodule init ist Cruft, die in Git ohne Schaden veraltet sein könnte.

Welche davon ist wahr?


quelle

Antworten:

59

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 abrufen. git initfunktioniert gut dafür, denn sobald Sie den Befehl git initfür diese beiden Submodule ausführen , git submodule update --remotegilt dies nur für sie.


Demo mit zwei Workflows angehängt.

Workflow1: Submodule sind Bibliotheken, die von mehreren Projekten verwendet werden.

Ich denke, dies 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, code1.jsder auf lib1 und lib2 verweist, umgestalten, 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

Nun wollen wir den Inhalt von sehen .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 etwas 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 code1.jsohne Importfehler umgestalten .

Submodule sind nur Verweise auf bestimmte Commits. Wenn Sie 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 benötigten Submodule zu initialisieren.

Workflow 2: Jedes Submodul 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 mit dem Namen "shared" sehen. In diesem Workflow gibt es eine Regel: Wenn Sie gemeinsam genutzte Codes des Hauptprojekts in Ihrem Projekt verwenden möchten, müssen Sie das Projekt als Submodul des Hauptprojekts erstellen.

Ich möchte Entitätsklassen wie unten beschrieben in ein freigegebenes Verzeichnis stellen.

Geben Sie hier die Bildbeschreibung ein

Zurück zum Submodul-Workflow sieht der Inhalt von .gitmodules wie folgt aus.

[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 Sie wissen, dass nur Unterprojekt1 und Unterprojekt2 auf gemeinsam genutzten Code verweisen. Dies bedeutet, dass Sie Unterprojekt3 und Unterprojekt nicht klonen und auschecken müssen project4. Führen Sie 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 git submodule update --remotein diesem Fall tun ? Oder muss ich überhaupt Submodule initiieren und aktualisieren, um den Code im freigegebenen Verzeichnis umzugestalten? Ja, da Sie nach dem Refactoring des freigegebenen Codes Tests in Submodulen ausführen müssen und wenn während des Refactorings ein Update der Submodule festgeschrieben und in das Remote-Repository übertragen wird, müssen Sie es abrufen git submodule update --remote.

Nigiri
quelle
Vielen Dank für den Hinweis, dass git submodule initdies in diesem Anwendungsfall hilfreich sein könnte. Ich habe es noch nicht ausprobiert, aber ich habe Ihre Antwort positiv bewertet, damit ich breiter über Git-Submodul-Workflows nachdenke :) 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, dass du mein Englisch korrigiert hast. Ich habe zwei Workflows hinzugefügt. Ich bin mir nicht sicher, ob dies jemandem hilft.
Nigiri
Wenn Sie andere Submodule haben und nur bestimmte Submodule initiieren und aktualisieren möchten, lautet der Workflow: [git submodule init - ./lib1 ./lib2] und [git submodule update --remote --recursive - ./lib1. / lib2]. Sie können auch [--merge] oder [--rebase] mit dem Update-Befehl verwenden, aber zuerst lesen, was sie tun, da sie ein Auschecken des getrennten Kopfes vermeiden können, da das Risiko besteht, dass der Verlauf möglicherweise beschädigt wird, wenn sich HEAD während des Updates nicht im richtigen Zweig befindet . Im Moment können Sie den Status des abgetrennten Kopfes mit [Git-Submodul für jeden "Git-Checkout-Master && Git-Pull"] (Submodule, die so lustig und einfach zu bedienen sind xD)
beheben
20

Beim Lesen der git submodule Dokumentation gibt es einen Anwendungsfall, der angeblich die Existenz git submodule initeines eigenständigen Befehls rechtfertigt .

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

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

quelle
1
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/itist einfacher als das Bearbeiten der Datei und git submodule update --initeinfacher als das zweistufige Bearbeiten, wenn Sie mit den Standardeinstellungen zufrieden sind.
Bis zum