Wie kann ein Git-Submodul-Zeiger auf das im enthaltenen Repository gespeicherte Commit zurückgesetzt werden?

128

Ich habe ein Git-Submodul in meinem Haupt-Git-Repo. Soweit ich weiß, speichert das Haupt-Repo einen SHA-Wert (irgendwo ...), der auf das spezifische Commit des Submoduls verweist, mit dem es "verknüpft" ist.

Ich ging in mein Submodul und tippte git checkout some_other_branch. Ich habe keine Ahnung, von welchem ​​Commit ich gekommen bin.

Ich möchte diesen Zeiger zurücksetzen, damit das Haupt-Repo und das Submodul wieder synchron sind.

Mein erster (wahrscheinlich naiver) Instinkt war zu sagen git reset --hard- das scheint für alles andere zu funktionieren. Zu meiner Überraschung hat es in diesem Szenario nicht funktioniert.

Also habe ich herausgefunden, dass ich tippen git diff, die SHA-ID notieren kann , die der Submodulzeiger früher hatte, und dann in das Submodul gehen und git checkout [SHA ID]... aber es muss doch einen einfacheren Weg geben?

Da ich noch etwas über Git-Submodule lerne, können Sie meine Terminologie gerne korrigieren, wenn es Wörter für Konzepte gibt, die ich nicht kenne.

Smashery
quelle

Antworten:

167

Sie möchten Ihr Submodul so aktualisieren, dass es mit dem synchronisiert ist, was das übergeordnete Repository für richtig hält. Dies ist, wofür der Update-Befehl ist:

Aus der Submodul-Manpage:

Aktualisieren Sie die registrierten Submodule, dh klonen Sie fehlende Submodule und
Überprüfen Sie das im Index des enthaltenen Commits angegebene Commit
Repository. Dadurch werden die Submodule HEAD getrennt, es sei denn
--rebase oder --merge ist angegeben oder das Schlüssel-Submodul. $ name.update
ist auf Rebase oder Merge eingestellt.

Führen Sie dies aus und alles sollte gut sein:

git submodule update
Brian Riehman
quelle
4
Irgendwie musste ich für mich hinzufügen --init. Ohne sie würden die Submodule in einem Zustand mit bleiben (new commits). Obwohl meine Submodule bereits initialisiert wurden.
Ambidex
@Ambidex ja die --initOption ist dabei entscheidend. Ich wurde aufgefordert, Benutzername und Passwort einzugeben, da meine Submodule über https geklont wurden. Ich ging in beide Ordner und stellte die Fernbedienungen so ein, dass das sshProtokoll zum Auschecken verwendet wurde.
A-Dubb
1
funktioniert nicht, wenn der Submodul-Commit-Hash geändert und nicht bereitgestellt wurde
Tribbloid
kann hinzufügen - rekursiv, so dass Sie nicht zu allen Submodulen gehen müssen
Gaspa79
21

Um das Commit zu ändern, auf das ein Submodul verweist, müssen Sie diese Version im Submodul auschecken und dann zum enthaltenen Repo zurückkehren, diese Änderung hinzufügen und festschreiben.

Wenn Sie möchten, dass sich das Submodul in der Version befindet, auf die das Top-Repo verweist, tun Sie dies git submodule update --recursive. Fügen --initSie hinzu, wenn Sie gerade geklont haben.

Auch git submoduleohne ein Submodul Befehl wird Ihnen zeigen, die verpflichten Sie verweisen auf. Vor dem Commit steht ein - oder ein +, wenn es nicht synchron ist.

Wenn Sie sich einen Baum mit einem Submodul ansehen, können Sie sehen, dass das Submodul commitim Gegensatz zu den übrigen Blobs oder Bäumen als markiert ist .

Um zu sehen, was ein bestimmtes Commit für Submodule bedeutet, können Sie:

git ls-tree <some sha1, or branch, etc> Submodule/path

Sie können dann das Commit oder etwas anderes sehen, wenn Sie möchten, indem Sie es an das Protokoll usw. übergeben (mit der git-dirOption auf der Befehlsebene git können Sie überspringen, dass Sie eine CD zum Submodul herunterfahren müssen):

git --git-dir=Submodule/path log -1 $(<the above statement>)
Adam Dymitruk
quelle
Der folgende Befehl hat mir geholfen (ich wollte alle Änderungen im Submodul und auch in meinem Modul ignorieren): Git Submodul Update --init --recursive
Rajesh Goel
6

Ein anderer Fall, auf den ich gerade gestoßen bin, ist, wenn es eine nicht bereitgestellte Änderung im Submodul gibt, die Sie verwerfen möchten. Das Git-Submodul-Update entfernt diese Änderung nicht und setzt Git --hard im übergeordneten Verzeichnis nicht zurück. Sie müssen in das Submodul-Verzeichnis gehen und einen Git-Reset durchführen --hard. Wenn ich also nicht bereitgestellte Änderungen sowohl in meinem übergeordneten als auch in meinem Submodul vollständig verwerfen möchte, gehe ich wie folgt vor:

In Eltern:

git reset --hard

git submodule update

Im Submodul:

git reset --hard
Benjamin Noffsinger
quelle
5

Verwenden Sie git ls-tree HEADim Ordner "Superprojekt", um zu sehen, bei welchem ​​Commit sich Ihr Submodul ursprünglich befand. Wechseln Sie dann in das Submodulverzeichnis und verwenden Sie, um git log --oneline --decoratezu sehen, in welchem ​​Zweig sich das ursprüngliche Commit befindet. Schließlich git checkout original-commit-branch.

Unter Verwendung einiger von mir eingerichteter Testverzeichnisse könnten die Befehle folgendermaßen aussehen:

$ git --version
git version 1.7.4.1
$ git status
# On branch master
# 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:   sm2 (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-tree HEAD
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d    .gitmodules
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    main
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed  sm1
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337  sm2
$ cd sm2
$ git log --oneline --decorate
5b8d48f (HEAD, foo1) foo1.1
f68bed6 (origin/master, origin/HEAD, master) Initial commit.
$ git checkout master
Switched to branch 'master'
$ cd ..
$ git status
# On branch master
nothing to commit (working directory clean)

Das "Superprojekt" zeigt das sm2-Submodul beim f68bed6Festschreiben , aber sm2 hat seinen HEAD bei 5b8d48f. Das Submodul-Commit f68bed6enthält drei Zweige, die zum Auschecken im Submodulverzeichnis verwendet werden können.

Dan Cruz
quelle
DANKE DAN, PERFEKT!
Alec
1

Ich wollte alle Änderungen im Submodul und auch in meinem Modul ignorieren

Der folgende Befehl hat mir geholfen:

git submodule update --init --recursive
Rajesh Goel
quelle