Wie funktioniert das git submodule add -b
?
Nach dem Hinzufügen eines Submoduls mit einem bestimmten Zweig befindet sich ein neues geklontes Repository (nachher git submodule update --init
) in einem bestimmten Commit, nicht im Zweig selbst ( git status
im Submodul wird "Derzeit in keinem Zweig" angezeigt).
Ich kann keine Informationen über .gitmodules
oder .git/config
über den Zweig des Submoduls oder ein bestimmtes Commit finden. Wie findet Git das heraus?
Ist es auch möglich, ein Tag anstelle eines Zweigs anzugeben?
Ich verwende Version 1.6.5.2.
git
git-submodules
Ivan
quelle
quelle
Antworten:
Hinweis: Git 1.8.2 hat die Möglichkeit hinzugefügt, Zweige zu verfolgen. Sehen Sie einige der Antworten unten.
Es ist etwas verwirrend, sich daran zu gewöhnen, aber Submodule befinden sich nicht in einem Zweig. Sie sind, wie Sie sagen, nur ein Zeiger auf ein bestimmtes Commit des Repositorys des Submoduls.
Dies bedeutet, wenn jemand anderes Ihr Repository auscheckt oder Ihren Code abruft und das Git-Submodul aktualisiert, wird das Submodul für dieses bestimmte Commit ausgecheckt.
Dies ist ideal für ein Submodul, das sich nicht oft ändert, da dann jeder im Projekt das Submodul gleichzeitig festschreiben kann.
Wenn Sie das Submodul in ein bestimmtes Tag verschieben möchten:
Ein anderer Entwickler, der möchte, dass submodule_directory in dieses Tag geändert wird, führt dies aus
git pull
Änderungen, auf die das Submodulverzeichnis verweist, verweisen auf.git submodule update
führt tatsächlich den neuen Code zusammen.quelle
cd my_submodule; git checkout [ref in submodule's repository
ergibtfatal: reference is not a tree: ...
. Es ist, als würdegit
nur das übergeordnete Repository ausgeführt.git checkout v1.0
ein Zweig oder ein Tag?Ich möchte hier eine Antwort hinzufügen, die eigentlich nur ein Konglomerat anderer Antworten ist, aber ich denke, dass sie vollständiger sein kann.
Sie wissen, dass Sie ein Git-Submodul haben, wenn Sie diese beiden Dinge haben.
Ihr
.gitmodules
hat einen Eintrag wie folgt:Sie haben ein Submodul-Objekt (in diesem Beispiel SubmoduleTestRepo genannt) in Ihrem Git-Repository. GitHub zeigt diese als "Submodul" -Objekte an. Oder über
git submodule status
eine Befehlszeile. Git-Submodulobjekte sind spezielle Arten von Git-Objekten und enthalten die SHA-Informationen für ein bestimmtes Commit.Wann immer Sie a ausführen
git submodule update
, wird Ihr Submodul mit Inhalten aus dem Commit gefüllt. Es weiß aufgrund der Informationen in der, wo das Commit zu finden ist.gitmodules
.Jetzt
-b
müssen Sie nur noch eine Zeile in Ihre.gitmodules
Datei einfügen. Nach dem gleichen Beispiel würde es also so aussehen:Das Submodul-Objekt zeigt immer noch auf ein bestimmtes Commit. Das einzige, was die
-b
Option Ihnen kauft, ist die Möglichkeit, eine hinzuzufügen--remote
, Ihrem Update Flag gemäß Vogellas Antwort hinzuzufügen:Anstatt den Inhalt des Submoduls mit dem Commit zu füllen, auf das das Submodul verweist, ersetzt es dieses Commit durch das letzte Commit im Master-Zweig. DANN wird das Submodul mit diesem Commit gefüllt. Dies kann in zwei Schritten durch die Antwort von djacobs7 erfolgen. Da Sie jetzt das Commit aktualisiert haben, auf das das Submodulobjekt zeigt, müssen Sie das geänderte Submodulobjekt in Ihr Git-Repository übertragen.
git submodule add -b
ist keine magische Möglichkeit, mit einer Filiale alles auf dem neuesten Stand zu halten. Es fügt einfach Informationen zu einem Zweig in die.gitmodules
Datei ein und bietet Ihnen die Möglichkeit, das Submodulobjekt auf das neueste Commit eines angegebenen Zweigs zu aktualisieren, bevor Sie es füllen.quelle
.gitmodules
und danach habe$ git submodule update --init --remote TestModule
ich eine Fehlermeldung mitfatal: Needed a single revision
und erhaltenUnable to find current origin/TestTag revision in submodule path 'TestModule'
. Wenn es mit einem echten Zweig gemacht wird, funktioniert es. Gibt es überhaupt eine Möglichkeit, ein Tag anzugeben,.gitmodules
ohne das genaue Commit angeben zu müssen?.gitmodules
und bin gelaufengit submodule update
und nichts ist passiert?(Git 2.22, Q2 2019, wurde eingeführt
git submodule set-branch --branch aBranch -- <submodule_path>
)Beachten Sie Folgendes : Wenn Sie ein vorhandenes Submodul haben, das noch keinen Zweig verfolgt , dann ( wenn Sie Git 1.8.2+ haben ):
Stellen Sie sicher, dass das übergeordnete Repo weiß, dass sein Submodul jetzt einen Zweig verfolgt:
Stellen Sie sicher, dass sich Ihr Submodul tatsächlich auf dem neuesten Stand dieses Zweigs befindet:
(wobei 'origin' der Name des Upstream-Remote-Repos ist, von dem das Submodul geklont wurde.
Ein
git remote -v
Innere dieses Submoduls zeigt es an. Normalerweise ist es 'origin')Vergessen Sie nicht, den neuen Status Ihres Submoduls in Ihrem Eltern-Repo aufzuzeichnen:
Bei der nachfolgenden Aktualisierung dieses Submoduls muss die folgende
--remote
Option verwendet werden:Beachten Sie, dass Sie mit Git 2.10+ (Q3 2016) '
.
' als Filialnamen verwenden können :Aber wie von LubosD kommentiert
Das bedeutet Git 2.23 (August 2019) oder mehr.
Siehe " Verwirrt von
git checkout
"Wenn Sie alle Ihre Submodule nach einem Zweig aktualisieren möchten:
Beachten Sie, dass das Ergebnis für jedes aktualisierte Submodul fast immer ein abgetrennter KOPF ist , wie Dan Cameron in seiner Antwort feststellt .
( Clintm merkt in den Kommentaren an, dass, wenn Sie ausführen
git submodule update --remote
und das resultierende sha1 mit dem Zweig identisch ist, in dem sich das Submodul gerade befindet, es nichts tut und das Submodul immer noch "in diesem Zweig" und nicht im Status "Abgelöst" bleibt. )Um sicherzustellen, dass der Zweig tatsächlich ausgecheckt ist (und dadurch die SHA1 des speziellen Eintrags, der das Submodul für das übergeordnete Repo darstellt, nicht geändert wird), schlägt er vor:
Jedes Submodul verweist weiterhin auf dasselbe SHA1. Wenn Sie jedoch neue Commits vornehmen, können Sie diese verschieben, da sie von dem Zweig referenziert werden, den das Submodul verfolgen soll.
Vergessen Sie nach diesem Push innerhalb eines Submoduls nicht, zum übergeordneten Repo zurückzukehren, den neuen SHA1 für diese modifizierten Submodule hinzuzufügen, festzuschreiben und zu pushen.
Beachten Sie die Verwendung von
$toplevel
, empfohlen in den Kommentaren von Alexander Pogrebnyak .$toplevel
wurde im Mai 2010 in git1.7.2 eingeführt: commit f030c96 .dtmland
fügt in den Kommentaren hinzu :Der gleiche Befehl, aber leichter zu lesen:
umläute verfeinert den Befehl von dtmland mit einer vereinfachten Version in den Kommentaren :
mehrere Zeilen:
Vor Git 2.26 (Q1 2020) erzeugt ein Abruf, der angewiesen wird, Aktualisierungen in Submodulen rekursiv abzurufen, zwangsläufig Unmengen von Ausgaben, und es wird schwierig, Fehlermeldungen zu erkennen.
Dem Befehl wurde beigebracht, Submodule aufzulisten, bei denen am Ende des Vorgangs Fehler aufgetreten sind .
Siehe Commit 0222540 (16. Januar 2020) von Emily Shaffer (
nasamuffin
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit b5c71cc , 05. Februar 2020)quelle
foreach
Skript wird nicht davon abhängen , die fest einprogrammiert<path>
, wenn Sie ersetzen<path>
mit$toplevel/
.foreach
Skript kann Submodule, die keinem Zweig folgen, nicht auschecken. Dieser Befehl gibt Ihnen jedoch beide:git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch'
git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
git submodule update --remote --merge
odergit submodule update --remote --rebase
. Diese Befehle verfolgen den Remote-Zweig.Git 1.8.2 hat die Möglichkeit hinzugefügt, Zweige zu verfolgen.
Siehe auch Git-Submodule
quelle
.gitmodules
Datei aus?git submodule add -b tags/<sometag> <url>
dem Sie als Zeilebranch = tags/<sometag>
in.gitmodules
Ein Beispiel, wie ich Git-Submodule verwende.
Und das sieht ein bisschen so aus:
Vielleicht hilft es (obwohl ich ein Tag und keinen Zweig verwende)?
quelle
git reset --hard V3.1.2
? Ich bekomme nur ein "Nichts zum Festschreiben" mit einemgit status
der übergeordneten Verzeichnisse.Nach meiner Erfahrung führen das Wechseln von Zweigen im Superprojekt oder zukünftige Checkouts immer noch zu getrennten HEADs von Submodulen, unabhängig davon, ob das Submodul ordnungsgemäß hinzugefügt und verfolgt wird (dh @ djacobs7- und @Johnny Z-Antworten).
Und anstatt den richtigen Zweig manuell oder über ein Skript manuell auszuchecken, kann das Submodul foreach verwendet werden.
Dadurch wird die Submodul-Konfigurationsdatei auf die Verzweigungseigenschaft überprüft und der festgelegte Zweig ausgecheckt.
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'
quelle
Git-Submodule sind etwas seltsam - sie befinden sich immer im "Detached Head" -Modus - sie werden nicht wie erwartet auf das neueste Commit für einen Zweig aktualisiert.
Dies ist jedoch sinnvoll, wenn Sie darüber nachdenken. Sagen wir , ich Repository erstellen foo mit Submodul bar . Ich drücke meine Änderungen und fordere Sie auf, Commit a7402be aus dem Repository foo zu überprüfen .
Stellen Sie sich dann vor, dass jemand eine Änderung an der Repository- Leiste festlegt , bevor Sie Ihren Klon erstellen können.
Wenn Sie Commit a7402be aus dem Repository foo auschecken , erwarten Sie, dass Sie denselben Code erhalten, den ich gepusht habe. Aus diesem Grund werden Submodule erst aktualisiert, wenn Sie sie explizit anweisen und dann ein neues Commit durchführen.
Persönlich denke ich, dass Submodule der verwirrendste Teil von Git sind. Es gibt viele Orte, die Submodule besser erklären können als ich. Ich empfehle Pro Git von Scott Chacon.
quelle
git clone git://github.com/git/git.git
und schieben Sie diese Funktion ...? = DSo wechseln Sie den Zweig für ein Submodul (vorausgesetzt, Sie haben das Submodul bereits als Teil des Repositorys):
cd
zum Stammverzeichnis Ihres Repositorys mit den Submodulen.gitmodules
Zum Bearbeiten öffnenpath = ...
undurl = ...
das heißtbranch = your-branch
, für jedes Submodul; Datei speichern.gitmodules
.$ git submodule update --remote
... dies sollte die neuesten Commits für den angegebenen Zweig für jedes so modifizierte Submodul abrufen.
quelle
Ich habe dies in meiner .gitconfig-Datei. Es ist noch ein Entwurf, hat sich aber ab sofort als nützlich erwiesen. Es hilft mir, die Submodule immer wieder an ihren Zweig anzuschließen.
quelle
Wir verwenden Quack , um ein bestimmtes Modul aus einem anderen Git-Repository abzurufen. Wir müssen Code ohne die gesamte Codebasis des bereitgestellten Repositorys abrufen - wir benötigen ein sehr spezifisches Modul / eine sehr spezifische Datei aus diesem riesigen Repository und sollten jedes Mal aktualisiert werden, wenn wir ein Update ausführen.
So haben wir es erreicht:
Konfiguration erstellen
Mit der obigen Konfiguration wird ein Verzeichnis aus dem bereitgestellten GitHub-Repository erstellt, wie in der ersten Modulkonfiguration angegeben, und das andere besteht darin, eine Datei aus dem angegebenen Repository abzurufen und zu erstellen.
Andere Entwickler müssen nur laufen
Und es zieht den Code aus den obigen Konfigurationen.
quelle
Die einzige Auswirkung der Auswahl eines Zweigs für ein Submodul besteht darin, dass Sie immer dann, wenn Sie das übergeben
--remote
Option Option ingit submodule update
Git Befehlszeile übergeben, im getrennten HEAD- Modus (wenn das Standardverhalten--checkout
ausgewählt ist) das letzte Commit dieses ausgewählten Remote- Zweigs auscheckt .Sie müssen besonders vorsichtig sein, wenn Sie diese Remote Branch Branch-Funktion für Git-Submodule verwenden, wenn Sie mit flachen Klonen von Submodulen arbeiten. Der Zweig, den Sie zu diesem Zweck in den Einstellungen des Submoduls auswählen , wird NICHT während dieser Zeit geklont
git submodule update --remote
. Wenn Sie auch den--depth
Parameter übergeben und Git nicht anweisen, welchen Zweig Sie klonen möchten - und das können Sie eigentlich nicht in dergit submodule update
Befehlszeile !! - verhält es sich implizit wie in dergit-clone(1)
Dokumentation erläutert,git clone --single-branch
wenn der explizite--branch
Parameter fehlt, und klont daher nur den primären Zweig .Kein Wunder, dass nach der Klonphase von der
git submodule update
Befehl ausgeführten Klonphase endlich versucht wird, das letzte Commit für den Remote- Zweig zu überprüfen, den Sie zuvor für das Submodul eingerichtet haben. Wenn dies nicht der primäre Zweig ist, ist er nicht Teil von Ihr lokaler flacher Klon, und daher wird es mit scheiternquelle
Git-Submodul add -b Develop - Name Branch-Name - https: //branch.git
quelle