Wie kann ich meine Änderungen auf ein Git-Submodul zurücksetzen?

268

Ich habe ein Git-Submodul (RestKit), das ich meinem Repo hinzugefügt habe.

Ich habe dort versehentlich einige Dateien geändert und möchte zur Quellversion zurückkehren. Um das zu tun, habe ich versucht zu rennen

Mac:app-ios user$ git submodule update RestKit

Aber wie Sie hier sehen können, hat dies nicht funktioniert, da es sich immer noch um "modifizierten Inhalt" handelt:

Mac:app-ios user$ git status
...
#   modified:   RestKit (modified content)

Sogar

Mac:app-ios user$ git submodule update -f RestKit 

setzt lokal geänderte Dateien nicht zurück.
Wie setze ich den Inhalt dieses Submoduls zurück?

Eric
quelle
Wenn git reset --harddies nicht funktioniert, geben Sie zuerst den Remote-Zweig mit an git reset --hard origin/<branch_name>.
Jerry K.

Antworten:

208

Wechseln Sie in das Verzeichnis des Submoduls und führen Sie dann a aus git reset --hard, um alle geänderten Dateien auf ihren letzten festgeschriebenen Status zurückzusetzen. Beachten Sie, dass dadurch alle nicht festgeschriebenen Änderungen verworfen werden.

Jamie Penney
quelle
6
Das Git-Submodul-Update (auch ohne --init) hat für mich funktioniert, um die "Änderungen" des Submoduls aufzugeben, wenn ich eigentlich nichts geändert hatte. Wenn Sie in das Submodulverzeichnis wechseln und der Git-Status leer ist, versuchen Sie dies anstelle des Zurücksetzens.
Eklektische DNA
16
git submodule update --initarbeitete für mich; ohne --inites hat überhaupt nicht funktioniert.
Per Lundberg
Hervorragend!! Ich habe das Submodul in einem Repo von mir geändert, in das ich es importiert habe. Und dies brachte es wieder auf das zurück, was es sein sollte.
Noitidart
2
reset --hard hat bei mir nicht funktioniert, mein Submodul konnte wegen lokaler Änderungen immer noch nicht deinit werden.
Malhal
33
zusätzlich zu @markshiz git submodule update -f --initfür meinen Fall.
otiai10
279

Wenn Sie dies für alle Submodule tun möchten, ohne die Verzeichnisse ändern zu müssen, können Sie dies ausführen

git submodule foreach git reset --hard

Sie können das rekursive Flag auch verwenden, um es auf alle Submodule anzuwenden:

git submodule foreach --recursive git reset --hard

der Rabe
quelle
7
Dies funktioniert für die Automatisierung viel besser als der Versuch, in jedes Submodulverzeichnis zu cd.
Travis Castillo
4
Beachten Sie, dass Sie möglicherweise auch möchtengit submodule foreach --recursive git clean -x -f -d
yoyo
1
Auf meinem Computer (Windows mit Git 2.22.0) benötige ich einfache Anführungszeichen um den zweiten git-Befehl, wenn ich das Flag --recursive verwende, sonst funktioniert es nicht: git-Submodul foreach --recursive 'git clean -x -f -d'
Am
196

Eine ausfallsichere Methode als alle vorherigen Antworten:

git submodule deinit -f .
git submodule update --init

Der erste Befehl "löst" alle Submodule vollständig, der zweite führt dann eine neue Überprüfung durch.
Es dauert länger als die anderen Methoden, funktioniert jedoch unabhängig vom Status Ihrer Submodule.

qwertzguy
quelle
1
Leider hat dies in meinem Fall nicht funktioniert (mit geänderten lokalen Dateien in einem Git-Submodul), der Befehl "update --init" spuckterror: Your local changes to the following files would be overwritten by checkout
rogerdpack
Um ein bestimmtes Submodul zu aktualisieren, gehen Sie wie folgt vor: $ git submodule deinit -f - <submodule_path> und dann $ git submodule update --init - <submodule_path>
Priyank
Ich habe alle oben genannten Methoden ausprobiert, bis ich zu dieser kam. Für mich ist dies der einzige, bei dem mein Idiot "sauber" aussah (ohne den *in meinem PS1, der git status -unoes nicht erklären konnte).
Guy Rapaport
60

Gut für mich zu haben

git reset --hard

Setzen Sie das Submodul einfach auf den Status zurück, in dem es ausgecheckt wurde. Dies ist für das Repo-referenzierte Commit / den Status des Main nicht erforderlich. Ich werde immer noch "geänderte Inhalte" haben, wie OP sagte. Um das Submodul wieder auf das korrekte Commit zu bringen, führe ich Folgendes aus:

git submodule update --init

Wenn ich das tue git status, ist es auf dem Submodul sauber.

Prüfsumme
quelle
Leider submodule update --initscheint es in meinem Fall ohnehin nicht möglich zu sein, lokale Änderungen rückgängig zu machen: |
Rogerdpack
48

Führen Sie 4 Schritte nacheinander aus:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f
jiahut
quelle
2
Der einzige, der mir auch geholfen hat.
Victor Sergienko
Frage: Wenn das Submodul neu ist, befindet sich in diesem Verzeichnis keine .git-Datei. Richtig? Sprudelt der Befehl git zum übergeordneten Repo?
Santiago Aristi
1
@jiahut Auch danach habe ich noch "(neue Commits") neben meinem Submodul, wenn ich 'git status' vom Elternteil mache?
David Doria
1
@ DavidDoria git submodule updatewar das, was das (new commits)für mich behoben hat.
Ubershmekel
31

Dies hat bei mir funktioniert, auch rekursiv in Submodule (vielleicht hat Ihr -f deshalb nicht funktioniert, weil Sie ein Submodul innerhalb des Submoduls geändert haben):

git submodule update -f --recursive
Sergiu Todirascu
quelle
11

Versuchen Sie dies zuerst, wie andere gesagt haben:

git submodule update --init

Wenn dies nicht funktioniert, wechseln Sie in das Submodulverzeichnis und verwenden Sie den folgenden Befehl, um festzustellen, ob Änderungen am Submodul vorgenommen wurden:

git status

Wenn sich Änderungen an Ihrem Submodul ergeben, entfernen Sie diese. Stellen Sie sicher, dass Sie keine Änderungen sehen können, wenn Sie "git status" ausführen.

Kehren Sie als Nächstes zum Haupt-Repository zurück und führen Sie "git submodule update --init" erneut aus.

Jean Libera
quelle
9

Seit Git 2.14 (Q3 2017) müssen Sie nicht mehr in jedes Submodul gehen, um ein git reset(wie in git submodule foreach git reset --hard) zu erstellen.

Das liegt daran, dass Git Reset selbst jetzt weiß, wie man rekursiv in Submodule geht.

Siehe Commit 35b96d1 (21. April 2017) und Commit f2d4899 , Commit 823bab0 , Commit cd279e2 (18. April 2017) von Stefan Beller ( stefanbeller) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 5f074ca , 29. Mai 2017)

eingebaut / zurückgesetzt: Schalter --recurse-submodules hinzufügen

git-reset ist ein weiterer funktionierender Baummanipulator, der über Submodule unterrichtet werden sollte.

Wenn ein Benutzer git-reset verwendet und die Rekursion in Submodule anfordert, werden die Submodule auf den im Superprojekt aufgezeichneten Objektnamen zurückgesetzt, wodurch die HEADs getrennt werden.

Warnung : der Unterschied zwischen:

  • git reset --hard --recurse-submodule und
  • git submodule foreach git reset --hard

Ersteres setzt auch den Haupt-Repo-Arbeitsbaum Ihres Elternteils zurück, da Letzteres nur den Arbeitsbaum der Submodule zurücksetzt.
Also mit Vorsicht verwenden.

VonC
quelle
7

Für git <= 2.13 sollten diese beiden Befehle zusammen Ihre Repos mit rekursiven Submodulen zurücksetzen:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init
cmcginty
quelle
3

Dies funktioniert mit unseren Bibliotheken unter GIT v1.7.1, in denen wir ein DEV-Paket-Repo und ein LIVE-Paket-Repo haben. Die Repositorys selbst sind nichts anderes als eine Shell zum Packen der Assets für ein Projekt. alle Submodule.

Das LIVE wird niemals absichtlich aktualisiert, es können jedoch Cache-Dateien oder Unfälle auftreten, die das Repo verschmutzen. Neue Submodule, die dem DEV hinzugefügt wurden, müssen ebenfalls in LIVE initialisiert werden.

Paket-Repository in DEV

Hier möchten wir alle Upstream-Änderungen abrufen, die uns noch nicht bekannt sind, und dann unser Paket-Repository aktualisieren.

# Recursively reset to the last HEAD
git submodule foreach --recursive git reset --hard

# Recursively cleanup all files and directories
git submodule foreach --recursive git clean -fd

# Recursively pull the upstream master
git submodule foreach --recursive git pull origin master

# Add / Commit / Push all updates to the package repo
git add .
git commit -m "Updates submodules"
git push   

Paket-Repository in LIVE

Hier möchten wir die Änderungen abrufen, die in das DEV-Repository übernommen wurden, aber keine unbekannten Upstream-Änderungen.

# Pull changes
git pull

# Pull status (this is required for the submodule update to work)
git status

# Initialize / Update 
git submodule update --init --recursive
David H.
quelle
2

Wenn Sie alle Änderungen im gesamten Repository zusammen mit den Untermodulen verwerfen möchten, können Sie verwenden

git restore . --recurse-submodules

Dadurch werden alle im Repository und in den Submodulen vorgenommenen Änderungen rückgängig gemacht.

Nitin Garg
quelle
0

meine Art, alle Submodule zurückzusetzen (OHNE ihren "Master" -Zweig zu trennen und zu behalten):

git submodule foreach 'git checkout master && git reset --hard $ sha1'

alex_1948511
quelle