Jak przywrócić moje zmiany do submodułu git?

268

Mam podmoduł git (RestKit), który dodałem do mojego repozytorium.

Przypadkowo zmieniłem niektóre pliki i chciałbym wrócić do wersji źródłowej. Aby to zrobić, próbowałem uruchomić

Mac:app-ios user$ git submodule update RestKit

Ale jak widać tutaj, to nie działało, ponieważ nadal jest to „zmodyfikowana treść”:

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

Parzysty

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

nie przywraca lokalnie zmodyfikowanych plików.
Jak zresetować zawartość tego podmodułu?

Eric
źródło
Jeśli git reset --hardnie działa, najpierw spróbuj określić gałąź zdalną za pomocą git reset --hard origin/<branch_name>.
Jerry K.

Odpowiedzi:

208

Przejdź do katalogu submodułu, a następnie wykonaj git reset --hardreset, aby zresetować wszystkie zmodyfikowane pliki do ich ostatniego zatwierdzonego stanu. Pamiętaj, że spowoduje to odrzucenie wszystkich niezaangażowanych zmian.

Jamie Penney
źródło
6
Aktualizacja podmodułu git (nawet bez opcji --init) pomogła mi porzucić „zmiany” podmodułu, gdy tak naprawdę nic nie zmieniłem. Jeśli przejdziesz do katalogu submodułu i status git pojawi się pusty, spróbuj tego zamiast resetowania.
Eklektyczny DNA
16
git submodule update --initpracował dla mnie; bez --inittego w ogóle nie działało.
Per Lundberg
Wspaniały!! Wprowadziłem zmiany do submodułu w moim repozytorium, do którego go zaimportowałem. I to przywróciło to z powrotem do tego, co miało być.
Noitidart
2
reset - twardy nie działał dla mnie, mojego modułu podrzędnego nadal nie można było deinitować z powodu lokalnych zmian.
malhal
33
oprócz @markshiz, git submodule update -f --initw moim przypadku.
otiai10
279

Jeśli chcesz to zrobić dla wszystkich podmodułów, bez konieczności zmiany katalogów, możesz wykonać

git submodule foreach git reset --hard

Możesz także użyć flagi rekurencyjnej, aby zastosować się do wszystkich podmodułów:

git submodule foreach --recursive git reset --hard

Kruk
źródło
7
działa to o wiele lepiej dla automatyzacji niż próba cd do każdego katalogu submodułów.
Travis Castillo,
4
Pamiętaj, że możesz także chciećgit submodule foreach --recursive git clean -x -f -d
yoyo
1
na moim komputerze (Windows z Git 2.22.0) Potrzebuję pojedynczych cudzysłowów wokół drugiego polecenia git, gdy używasz flagi --recursive, bo inaczej to nie zadziała: git submodule foreach --recursive 'git clean -x -f -d'
aatwo
196

Bardziej bezpieczna metoda niż wszystkie poprzednie odpowiedzi:

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

Pierwsze polecenie całkowicie „rozłącza” wszystkie podmoduły, drugie następnie dokonuje ich ponownego sprawdzenia.
Zajmuje to więcej czasu niż inne metody, ale działa niezależnie od stanu twoich submodułów.

qwertzguy
źródło
1
Niestety nie zadziałało to w moim przypadku (ze zmodyfikowanymi plikami lokalnymi w podmodule git), polecenie „update --init” error: Your local changes to the following files would be overwritten by checkout
wyrzuca
Aby zaktualizować określony podmoduł wykonaj: $ git submodule deinit -f - <ścieżka_modułu>, a następnie $ $ git aktualizacja modułu --init - <
ścieżka_modułu
Próbowałem wszystkich metod powyżej, aż do tego doszedłem. Dla mnie, jest to tylko jeden z nich, ale mój git poszukuje „czyste” (bez *w moim PS1, że git status -unonie był w stanie wytłumaczyć).
Guy Rapaport
60

Dobrze dla mnie

git reset --hard

po prostu zresetuj submoduł do stanu, w którym się wypisał, nie jest to konieczne do zatwierdzenia / stanu repozytorium głównego. Nadal będę mieć „zmodyfikowane treści”, jak powiedział OP. Aby przywrócić submoduł do poprawnego zatwierdzenia, uruchamiam:

git submodule update --init

Kiedy to zrobię git status, w podmodule jest czysto.

suma kontrolna
źródło
niestety submodule update --initzresztą nie przywraca lokalnych modyfikacji w moim przypadku: |
rogerdpack,
48

wykonaj 4 kolejne kroki:

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
źródło
2
Jedyny, który mi pomógł.
Victor Sergienko,
pytanie, jeśli podmoduł jest nowy, w tym katalogu nie będzie pliku .git, prawda? czy polecenie git zostanie przeniesione do repozytorium rodzica?
Santiago arizti
1
@jiahut Nawet po wykonaniu tej czynności nadal mam „(nowe zatwierdzenia”) obok mojego podmodułu, gdy wykonuję „status git” od rodzica?
David Doria
1
@DavidDoria git submodule updatebyło tym, co naprawiło (new commits)dla mnie.
ubershmekel
31

To działało dla mnie, włączając rekurencyjnie w submoduły (być może dlatego twój -f nie działał, ponieważ zmieniłeś submoduł wewnątrz tego modułu):

git submodule update -f --recursive
Sergiu Todirascu
źródło
11

Najpierw spróbuj tego, jak powiedzieli inni:

git submodule update --init

Jeśli to nie zadziała, przejdź do katalogu submodułu i użyj następującego polecenia, aby sprawdzić, czy w tym module są jakieś zmiany:

git status

Jeśli są zmiany w twoim module podrzędnym, pozbądź się ich. Sprawdź, czy nie widzisz żadnych zmian po uruchomieniu „git status”.

Następnie wróć do głównego repozytorium i ponownie uruchom „git submodule update --init”.

Jean Libera
źródło
9

Od wersji Git 2.14 (III kwartał 2017 r.) Nie trzeba wchodzić do każdego podmodułu, aby wykonać git reset(jak w git submodule foreach git reset --hard)

Jest tak, ponieważ sam git reset wie teraz, jak rekurencyjnie wchodzić w podmoduły.

Zobacz zatwierdzenie 35b96d1 (21 kwietnia 2017 r.) I zatwierdzenie f2d4899 , zatwierdzenie 823bab0 , zatwierdzenie cd279e2 (18 kwietnia 2017 r.) Przez Stefan Beller ( stefanbeller) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 5f074ca , 29 maja 2017 r.)

wbudowany / reset: dodaj przełącznik --recurse-submodules

git-reset jest kolejnym działającym manipulatorem drzewa, którego należy uczyć o submodułach.

Gdy użytkownik korzysta z git-reset i żąda rekurencji w submoduły, spowoduje to zresetowanie submodułów do nazwy obiektu zapisanej w superprojekcie, odłączając HEAD.

Ostrzeżenie : różnica między:

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

polega na tym, że ten pierwszy zresetuje również główne drzewo robocze repozytorium nadrzędnego, ponieważ ten drugi zresetuje tylko drzewo robocze podmodułów.
Więc używaj ostrożnie.

VonC
źródło
7

W przypadku git <= 2.13 te dwa polecenia łącznie powinny zresetować repozytorium za pomocą rekurencyjnych submodułów:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init
cmcginty
źródło
3

Działa to z naszymi bibliotekami z GIT v1.7.1, w których mamy repozytorium pakietów DEV i repozytorium pakietów LIVE. Same repozytoria są niczym innym jak powłoką do pakowania zasobów dla projektu. wszystkie podmoduły.

NA ŻYWO nigdy nie jest celowo aktualizowana, jednak pliki pamięci podręcznej lub wypadki mogą wystąpić, pozostawiając repozytorię brudną. Nowe submoduły dodane do DEV muszą zostać zainicjowane również w LIVE.

Repozytorium paczek w DEV

W tym miejscu chcemy usunąć wszystkie zmiany, o których jeszcze nie wiemy, a następnie zaktualizujemy nasze repozytorium pakietów.

# 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   

Repozytorium paczek w LIVE

W tym miejscu chcemy wyciągnąć zmiany, które są zatwierdzone w repozytorium DEV, ale nie nieznane zmiany w górę.

# 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.
źródło
2

Jeśli chcesz odrzucić wszystkie zmiany w całym repozytorium wraz z podmodułami, możesz użyć

git restore . --recurse-submodules

Spowoduje to cofnięcie wszystkich zmian dokonanych w repozytorium i podmodułach.

Nitin Garg
źródło
0

mój sposób na zresetowanie wszystkich podmodułów (BEZ odłączania i utrzymywania ich gałęzi „master”):

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

alex_1948511
źródło