Jak przywrócić wskaźnik Git Submodule do zatwierdzenia przechowywanego w zawierającym repozytorium?

128

Mam podmoduł git w moim głównym repozytorium git. Jak rozumiem, repozytorium główne przechowuje wartość SHA (gdzieś ...), wskazując na konkretne zatwierdzenie podmodułu, z którym jest „połączone”.

Wszedłem do mojego podmodułu i napisałem git checkout some_other_branch. Nie mam pojęcia, z jakiego popełnienia pochodzę.

Chciałbym przywrócić ten wskaźnik, aby repozytorium główne i moduł podrzędny były ponownie zsynchronizowane.

Moim pierwszym (prawdopodobnie naiwnym) odruchem było stwierdzenie git reset --hard- to wydaje się działać na wszystko inne. Ku mojemu zdziwieniu nie zadziałało to w tym scenariuszu.

Więc wymyśliłem, że mogę pisać git diff, zanotować identyfikator SHA, który miał wskaźnik podmodułu, a następnie udać się do podmodułu i git checkout [SHA ID]... ale na pewno musi być łatwiejszy sposób?

Ponieważ wciąż uczę się o modułach podrzędnych git, prosimy o poprawienie mojej terminologii, jeśli są słowa na koncepcje, których nie znam.

Kowalstwo
źródło

Odpowiedzi:

167

Chcesz zaktualizować swój moduł podrzędny, aby był zsynchronizowany z tym, co według repozytorium nadrzędnego powinno być. Do tego służy polecenie aktualizacji:

Ze strony podręcznika modułu podrzędnego:

Zaktualizuj zarejestrowane moduły podrzędne, tj. Sklonuj brakujące moduły podrzędne i
wypisuje zatwierdzenie określone w indeksie zawierającym
magazyn. Spowoduje to odłączenie podmodułów HEAD, chyba że
--rebase lub --merge lub podmoduł klucza. $ nazwa.update
jest ustawiony na zmianę bazy lub scalanie.

Uruchom to i wszystko powinno być dobrze:

git submodule update
Brian Riehman
źródło
4
Jakoś musiałem dodać --init. Bez tego submoduły pozostałyby w stanie z (new commits). Mimo że moje moduły podrzędne zostały już zainicjowane.
Ambidex
@Ambidex tak, ta --initopcja jest w tym wszystkim kluczowa. Otrzymałem monit o podanie nazwy użytkownika i hasła, ponieważ moje podmoduły zostały sklonowane przez https. Wszedłem do obu folderów i ustawiłem piloty, aby używały sshprotokołu do kasy.
A-Dubb
1
nie działa, jeśli hash zatwierdzenia submodułu jest zmodyfikowany i nie znajduje się na
scenie
można dodać --recursive, aby nie trzeba było przechodzić do wszystkich
modułów podrzędnych
21

Aby zmienić zatwierdzenie, na które wskazuje podmoduł, musisz pobrać tę wersję w module podrzędnym, a następnie wrócić do zawierającego repozytorium, dodać i zatwierdzić tę zmianę.

Lub, jeśli chcesz, aby podmoduł był w wersji, na którą wskazuje najlepsze repozytorium, zrób git submodule update --recursive. Dodaj, --initjeśli właśnie sklonowałeś.

Również git submodulebez komendy podmodułu pokaże ci zatwierdzenie, na które wskazujesz. Przed zatwierdzeniem pojawi się - lub +, jeśli nie jest zsynchronizowane.

Jeśli spojrzysz na drzewo zawierające podmoduł, zobaczysz, że podmoduł jest oznaczony jako, w commitprzeciwieństwie do pozostałych, które są kropkami lub drzewami.

aby zobaczyć, co konkretne zatwierdzenie wskazuje na podmoduły, możesz:

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

możesz wtedy zobaczyć zatwierdzenie lub cokolwiek innego, jeśli chcesz, przekazując to do dziennika itp. ( git-diropcja na poziomie polecenia git pozwala pominąć konieczność przechodzenia do modułu podrzędnego):

git --git-dir=Submodule/path log -1 $(<the above statement>)
Adam Dymitruk
źródło
Pomogło mi poniższe polecenie (chciałem zignorować wszelkie zmiany w module podrzędnym, a także w moim module): git submodule update --init --recursive
Rajesh Goel
6

Innym przypadkiem, na który właśnie natknąłem się, jest niestabilna zmiana w module podrzędnym, którą chcesz odrzucić. Aktualizacja modułu podrzędnego git nie usunie tej zmiany ani git reset --hard w katalogu nadrzędnym. Musisz przejść do katalogu modułów podrzędnych i wykonać reset gita - hard. Jeśli więc chcę całkowicie odrzucić zmiany niestacjonarne zarówno w module nadrzędnym, jak i podrzędnym, wykonuję następujące czynności:

W rodzicu:

git reset --hard

git submodule update

W module podrzędnym:

git reset --hard
Benjamin Noffsinger
źródło
5

Użyj git ls-tree HEADw folderze "superproject", aby zobaczyć, w jakim zatwierdzeniu był pierwotnie twój podmoduł. Następnie przejdź do katalogu podmodułów i użyj, git log --oneline --decorateaby zobaczyć, w której gałęzi znajduje się oryginalne zatwierdzenie. Wreszcie git checkout original-commit-branch.

Korzystając z niektórych skonfigurowanych przeze mnie katalogów testowych, oto jak mogą wyglądać polecenia:

$ 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)

"Superproject" pokazuje podmoduł sm2 po zatwierdzeniu, f68bed6ale sm2 ma jego HEAD w 5b8d48f. Zatwierdzenie podmodułu f68bed6ma trzy rozgałęzienia, które mogą być użyte do pobrania w katalogu podmodułów.

Dan Cruz
źródło
DZIĘKI DAN, PERFECTO!
Alec
1

Chciałem zignorować wszelkie zmiany w module podrzędnym, a także w moim module

Pomogło mi poniższe polecenie:

git submodule update --init --recursive
Rajesh Goel
źródło