1141 Stimmen

Git-Submodul auf die letzte Übergabe auf Origin aktualisieren

Ich habe ein Projekt mit einem Git-Submodul. Es ist von einer ssh://... URL und befindet sich auf Commit A. Commit B wurde zu dieser URL gepusht, und ich möchte, dass das Submodul den Commit abruft und zu ihm wechselt.

Ich gehe davon aus, dass git submodule update sollte dies tun, tut es aber nicht. Es tut sich nichts (keine Ausgabe, kein Erfolgs-Exit-Code). Hier ist ein Beispiel:

$ mkdir foo
$ cd foo
$ git init .
Initialized empty Git repository in /.../foo/.git/
$ git submodule add ssh://user@host/git/mod mod
Cloning into mod...
user@host's password: hunter2
remote: Counting objects: 131, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 131 (delta 54), reused 0 (delta 0)
Receiving objects: 100% (131/131), 16.16 KiB, done.
Resolving deltas: 100% (54/54), done.
$ git commit -m "Hello world."
[master (root-commit) 565b235] Hello world.
 2 files changed, 4 insertions(+), 0 deletions(-)
 create mode 100644 .gitmodules
 create mode 160000 mod
# At this point, ssh://user@host/git/mod changes; submodule needs to change too.
$ git submodule init
Submodule 'mod' (ssh://user@host/git/mod) registered for path 'mod'
$ git submodule update
$ git submodule sync
Synchronizing submodule url for 'mod'
$ git submodule update
$ man git-submodule 
$ git submodule update --rebase
$ git submodule update
$ echo $?
0
$ git status
# On branch master
nothing to commit (working directory clean)
$ git submodule update mod
$ ...

Ich habe auch versucht git fetch mod , das scheinbar einen Fetch durchführt (was aber nicht möglich ist, da es nicht nach einem Passwort fragt), aber git log y git show die Existenz neuer Commits leugnen. Bis jetzt habe ich nur rm -Modul zu entfernen und neu hinzuzufügen, aber das ist sowohl im Prinzip falsch als auch in der Praxis mühsam.

1860voto

Jason Punkte 18038

El git submodule update teilt Git mit, dass die Untermodule jeweils den bereits im Index des Superprojekts angegebenen Commit auschecken sollen. Wenn Sie möchten, dass Update Ihre Submodule auf den letzten verfügbaren Commit zu aktualisieren, müssen Sie dies direkt in den Submodulen tun.

Zusammengefasst:

# Get the submodule initially
git submodule add ssh://bla submodule_dir
git submodule init

# Time passes, submodule upstream is updated
# and you now want to update

# Change to the submodule directory
cd submodule_dir

# Checkout desired branch
git checkout master

# Update
git pull

# Get back to your project root
cd ..

# Now the submodules are in the state you want, so
git commit -am "Pulled down update to submodule_dir"

Oder, wenn Sie ein vielbeschäftigter Mensch sind:

git submodule foreach git pull origin master

673voto

David Z Punkte 121773

Git 1.8.2 bietet eine neue Option, --remote , die genau dieses Verhalten ermöglicht. Ausführen

git submodule update --remote --merge

holt die letzten Änderungen von Upstream in jedem Submodul, fügt sie ein und checkt die letzte Revision des Submoduls aus. Als die Dokumentation drückt es aus:

--Remote

Diese Option ist nur für den Befehl update gültig. Anstatt den aufgezeichneten SHA-1 des Superprojekts zu verwenden, um das Submodul zu aktualisieren, verwenden Sie den Status des Remote-Tracking-Zweigs des Submoduls.

Dies ist gleichbedeutend mit der Ausführung von git pull in jedem Submodul, was im Allgemeinen genau das ist, was Sie wollen.

168voto

pinux Punkte 4200

Führen Sie in Ihrem übergeordneten Projektverzeichnis aus:

git submodule update --init

Oder wenn Sie rekursive Untermodule ausführen lassen:

git submodule update --init --recursive

Manchmal funktioniert das trotzdem nicht, weil Sie irgendwie lokale Änderungen im lokalen Submodulverzeichnis haben, während das Submodul aktualisiert wird.

In den meisten Fällen ist die lokale Änderung nicht diejenige, die Sie vornehmen möchten. Dies kann z.B. durch das Löschen einer Datei in Ihrem Submodul geschehen. Wenn dies der Fall ist, setzen Sie Ihr lokales Submodul-Verzeichnis und Ihr übergeordnetes Projekt-Verzeichnis zurück und führen Sie es erneut aus:

git submodule update --init --recursive

88voto

Mark Longair Punkte 412179

Ihr Hauptprojekt verweist auf einen bestimmten Commit, bei dem das Submodul sein sollte. git submodule update versucht, diese Übergabe in jedem Submodul, das initialisiert wurde, zu überprüfen. Das Submodul ist eigentlich ein unabhängiges Repository - es reicht nicht aus, eine neue Übergabe im Submodul zu erstellen und diese zu pushen. Sie müssen die neue Version des Submoduls auch explizit in das Hauptprojekt einfügen.

In Ihrem Fall sollten Sie also die richtige Übergabe im Submodul finden - nehmen wir an, das ist die Spitze von master :

cd mod
git checkout master
git pull origin master

Gehen Sie nun zurück zum Hauptprojekt, erstellen Sie das Submodul und übertragen Sie es:

cd ..
git add mod
git commit -m "Updating the submodule 'mod' to the latest version"

Veröffentlichen Sie nun Ihre neue Version des Hauptprojekts:

git push origin master

Wenn von nun an jemand anderes sein Hauptprojekt aktualisiert, dann git submodule update für sie aktualisiert das Submodul, vorausgesetzt, es ist initialisiert worden.

32voto

VonC Punkte 1117238

Beachten Sie, während die moderne Form der Aktualisierung von Submodul-Commits wäre:

git submodule update --recursive --remote --merge --force

Die ältere Form war:

git submodule foreach --quiet git pull --quiet origin

Nur... diese zweite Form ist nicht wirklich "leise".

Siehe a282f5a übergeben (12 Apr 2019) von Nguyen Thái Ngoc Duy ( pclouds ) .
(Zusammengefasst von Junio C. Hamano -- gitster -- in Übergabe f1c9f6c , 25. Apr 2019)

submodule foreach : fix " <command> --quiet " nicht respektiert werden

Robin berichtet, dass

git submodule foreach --quiet git pull --quiet origin

ist nicht mehr wirklich ruhig.
Es sollte ruhig sein, bevor fc1b924 ( submodule : Hafen submodule Unterbefehl ' foreach ' von Shell nach C, 2018-05-10, Git v2.19.0-rc0), weil parseopt können dann nicht versehentlich Optionen essen.

" git pull " verhält sich, als ob --quiet ist nicht gegeben.

Dies geschieht, weil parseopt in submodule--helper wird versuchen, die beide --quiet Optionen, als ob sie die Optionen von foreach wären, nicht git-pull 's.
Die geparsten Optionen werden aus der Befehlszeile entfernt. Wenn wir also ziehen, führen wir später nur dies aus

git pull origin

Beim Aufruf von Submodul-Helfern ist der Zusatz " -- " vor " git pull " wird stoppen parseopt für das Parsen von Optionen, die eigentlich nicht zu submodule--helper foreach .

PARSE_OPT_KEEP_UNKNOWN wird als Sicherheitsmaßnahme entfernt. parseopt sollte nie unbekannte Optionen sehen oder etwas ist schief gelaufen. Außerdem gibt es ein paar Verwendungsstrings aktualisiert, während ich sie mir ansehe.

Wenn ich schon dabei bin, füge ich auch " -- " an andere Unterbefehle weitergeben, die " $@ " zu submodule--helper . " $@ " sind in diesen Fällen Wege und weniger wahrscheinlich --something-like-this .
Aber der Punkt bleibt bestehen, git-submodule hat analysiert und klassifiziert, was Optionen sind und was Pfade sind.
submodule--helper sollte niemals Pfade berücksichtigen, die von git-submodule Optionen zu sein, auch wenn sie so aussehen.


Und Git 2.23 (Q3 2019) behebt ein weiteres Problem: " git submodule foreach " schützte die Kommandozeilenoptionen, die an den in jedem Submodul auszuführenden Befehl übergeben wurden, nicht korrekt, wenn die " --recursive " war in Gebrauch.

Siehe 30db18b festlegen (24. Juni 2019) von Morianisches Sonett ( momoson ) .
(Zusammengefasst von Junio C. Hamano -- gitster -- in 968eecb übertragen , 09. Juli 2019)

submodule foreach : Rekursion von Optionen beheben

Anrufe:

git submodule foreach --recursive <subcommand> --<option>

führt zu einer Fehlermeldung, die besagt, dass die Option --<option> ist unbekannt für submodule--helper .
Das gilt natürlich nur, wenn <option> ist keine gültige Option für git submodule foreach .

Der Grund dafür ist, dass der obige Aufruf intern in eine Aufruf zum Submodul-Helfer übersetzt wird:

git submodule--helper foreach --recursive \
   -- <subcommand> --<option>

Dieser Aufruf beginnt mit der Ausführung des Unterbefehls mit seiner Option innerhalb der Submodul der ersten Ebene und fährt mit dem Aufruf der nächsten Iteration von der submodule foreach aufrufen

git --super-prefix <submodulepath> submodule--helper \
  foreach --recursive <subcommand> --<option>

innerhalb des Submoduls der ersten Ebene. Beachten Sie, dass der doppelte Bindestrich vor dem dem Unterbefehl fehlt.

Dieses Problem tritt erst seit kurzem auf, da die PARSE_OPT_KEEP_UNKNOWN Flagge für das Parsen der Argumente von git submodule foreach wurde im Commit entfernt a282f5a .
Daher wird jetzt die unbekannte Option beanstandet, da die Argumentanalyse nicht ordnungsgemäß durch den Doppelstrich beendet wird.

Dieser Commit behebt das Problem, indem er den doppelten Bindestrich vor dem Unterbefehl während der Rekursion hinzufügt.


Beachten Sie, dass vor Git 2.29 (Q4 2020), " git submodule update --quiet " ( man ) die zugrunde liegenden Befehle "rebase" und "pull" nicht unterdrückt.

Siehe 3ad0401 festlegen (30. September 2020) von Theodore Dubois ( tbodt ) .
(Zusammengefasst von Junio C. Hamano -- gitster -- in 300cd14 übertragen , 05. Oktober 2020)

submodule update : Stille zugrundeliegende Zusammenführung/Wiederverwendung mit " --quiet "

Abgezeichnet von: Theodore Dubois

Befehle wie

$ git pull --rebase --recurse-submodules --quiet  

eine nicht-geräuschlose Ausgabe des Merge oder Rebase erzeugen.
Pass die --quiet beim Aufrufen der Option " rebase " und " merge ".

Außerdem wurde das Parsing von git submodule update ( man ) -v.

Wenn e84c3cf3 (" git-submodule.sh : Akzeptieren Sie das Verbose-Flag in cmd_update to be non-quiet", 2018-08-14, Git v2.19.0-rc0 -- zusammenführen ) lehrte " git submodule update " ( man ) zu nehmen " --quiet ", wusste sie offenbar nicht, wie ${GIT_QUIET :+--quiet} funktioniert, und die Rezensenten scheinen übersehen zu haben, dass das Setzen der Variable auf "0", anstatt sie zu deaktivieren, immer noch zu " --quiet " an die zugrunde liegenden Befehle weitergegeben werden.


Mit Git 2.38 (Q3 2022), git-submodule.sh ist darauf vorbereitet, in ein builtin umgewandelt zu werden, was bedeutet, dass die submodule--helper die die oben beschriebenen Probleme aufweist, wird ausgeblendet.

Siehe commit 5b893f7 , 2eec463 übertragen , Übergabe 8f12108 , Commit 36d4516 , Commit 6e556c4 , 0d68ee7 übergeben , Übergabe d9c7f69 , committen da3aae9 , Übergabe 757d092 , 960fad9 übertragen , Übergabe 8577525 (28. Juni 2022) von Ævar Arnfjörð Bjarmason ( avar ) .
Siehe Übergabe b788fc6 (28. Juni 2022) von Glen Choo ( chooglen ) .
(Zusammengefasst von Junio C. Hamano -- gitster -- in 361cbe6 übertragen , 14. Juli 2022)

git-submodule.sh " verwenden $quiet ", nicht " $GIT_QUIET"

Abgezeichnet von: Ævar Arnfjörð Bjarmason

Entfernen Sie die Verwendung des "$GIT_QUIET" Variable zu Gunsten unserer eigenen " $quiet ", seitdem b3c5f5c (" submodule : Kern bewegen cmd_update() Logik nach C", 2022-03-15, Git v2.36.0-rc0 -- zusammenführen ) haben wir die Funktion "say" nicht in git-sh-setup.sh was das Einzige ist, das von der Verwendung von "" betroffen ist. GIT_QUIET" .

Wir wollen weiterhin unterstützen --quiet für unseren eigenen Gebrauch zu verwenden, aber lassen Sie uns dafür unsere eigene Variable verwenden.
Jetzt ist es offensichtlich, dass wir uns nur für das Bestehen von " --quiet " zu git submodule--helper und nicht die Ausgabe eines " say Aufforderung".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X