Git nie będzie inicjował / synchronizował / aktualizował nowych modułów podrzędnych

113

Oto część zawartości mojego .gitmodulespliku:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

Jednak .git/configzawiera tylko pierwszy:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

Drugi moduł podrzędny ( external/pyfacebook) został dodany przez innego programistę w gałęzi funkcji. Odziedziczyłem teraz rozwój i sprawdziłem gałąź funkcji. Jednak Git nie ściągnie dla mnie modułu podrzędnego. Próbowałem:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • Usunięcie wszystkich definicji podmodułów z .git/configi uruchomienie git submodule init. Kopiuje tylko poprzednio istniejący moduł podrzędny i ignoruje nowy.
  • .git/configRęczne wprowadzanie nowych definicji podmodułów i uruchamianie git submodule update. Aktualizacją zajmują się tylko istniejące wcześniej moduły podrzędne.

w różnych kombinacjach, ale git po prostu nie zaktualizuje się .git/configna podstawie nowej zawartości .gitmodules, ani nie utworzy external/pyfacebookfolderu i nie pobierze zawartości modułu podrzędnego.

czego mi brakuje? Czy ręczna interwencja (ręczne dodanie wpisu podmodułu .git/config) jest naprawdę wymagana i dlaczego?

Edycja: ręczna interwencja nie działa. Ręczne dodanie nowego wpisu podmodułu do .git/confignic nie daje. Nowy moduł podrzędny jest ignorowany.

David Eyk
źródło
1
działający 1.7.7.1 i mający ten sam problem: „git submodule sync” nie aktualizuje .git / config po zmianie na .gitmodules.
James Pritts
2
Ten artykuł jest pomocny: chrisjean.com/git-submodules-adding-using-removing-and-updating
IgorGanapolsky

Odpowiedzi:

92

Miałem ten sam problem - okazało się, że plik .gitmodules został zatwierdzony, ale faktyczne zatwierdzenie submodułu (czyli zapis ID zatwierdzenia submodułu) nie.

Dodanie go ręcznie zdawało się załatwić sprawę - np:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(Nawet bez usuwania czegokolwiek z .git / config lub .gitmodules.)

Następnie zatwierdź go, aby poprawnie zapisać identyfikator.

Dodanie dalszych komentarzy do tej roboczej odpowiedzi: Jeśli podmoduł git init lub aktualizacja submodułu git nie działa, to zgodnie z powyższym podmoduł git add url powinien załatwić sprawę. Można to sprawdzić krzyżowo

 git config --list

i należy uzyskać wpis podmodułu, który chcesz pobrać w wyniku wykonania polecenia git config --list. Jeśli w wyniku konfiguracji znajduje się wpis twojego modułu podrzędnego, to teraz zwykła aktualizacja modułu podrzędnego git --init powinna wyciągnąć moduł podrzędny. Aby przetestować ten krok, możesz ręcznie zmienić nazwę modułu podrzędnego, a następnie zaktualizować moduł podrzędny.

 mv yourmodulename yourmodulename-temp
 git submodule update --init

Aby dowiedzieć się, czy masz lokalne zmiany w module podrzędnym, możesz je zobaczyć za pomocą git status -u (jeśli chcesz zobaczyć zmiany w module podrzędnym) lub git status --ignore-submodules (jeśli nie chcesz widzieć zmian w podmoduł).

Dave James Miller
źródło
Do czego służy external/pyfacebook?
Igor Ganapolsky
2
@IgorGanapolsky To ścieżka docelowa dla Twojego modułu podrzędnego.
yuhua
To mi pomogło, wielkie dzięki! Mógłbym tylko dodać, że jeśli ścieżka docelowa już istnieje (co zrobiła dla mnie w wyniku wypróbowania innych poleceń), pojawia się następujący komunikat, który tylko pogłębia zamieszanie:'your/local/path' already exists and is not a valid git repo
Michael Ambrus
1
jedna linijka do odczytu wpisów w „git config --list”:git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
Puggan Se
64

git w wersji 2.7.4. To polecenie aktualizuje kod lokalny git submodule update --init --force --remote

palik
źródło
20
Nic dla mnie nie robisz.
Carlo Wood
1
w odniesieniu do git-submodule [dokumentacja) ( git-scm.com/docs/git-submodule#git-submodule---remote ) powyższe polecenie powinno zaktualizować lokalną gałąź podmodułów.
palik
1
@palik you rock!
Denis Trofimov
1
Możesz zaktualizować pojedynczy moduł za pomocą git submodule update --init --force --remote <module-name>.
Adam Faryna
15

Miałem ten sam problem, gdy git ignorował initi updatepolecenia, i nic nie robi.

JAK NAPRAWIĆ

  1. Twój folder podmodułu powinien zostać zatwierdzony w repozytorium git
  2. Nie powinno być w .gitignore

Jeśli te wymagania zostaną spełnione, będzie działać. W przeciwnym razie wszystkie polecenia zostaną wykonane bez żadnych komunikatów i wyników.

Jeśli zrobiłeś to wszystko i nadal nie działa:

  1. Dodaj podmoduł ręcznie, np git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. zatwierdź i wypchnij wszystkie pliki - .gitmodulesi folder modułu (pamiętaj, że zawartość folderu nie zostanie zatwierdzona)
  5. porzuć lokalne repozytorium git
  6. sklonuj nowy
  7. upewnij się, że .git/confignie ma jeszcze żadnych modułów podrzędnych
  8. Teraz git submodule init- i zobaczysz komunikat, że moduł został zarejestrowany
  9. git submodule update - pobierze moduł
  10. Teraz spójrz na, .git/configa znajdziesz zarejestrowany podmoduł
Alex Ivasyuv
źródło
1
Uważam, że ścieżka do modułów podrzędnych MOŻE znajdować się w .gitignore. Przynajmniej udało mi się to, podążając za odpowiedzią z @DaveJamesMiller. Nic innego nie działało dla mnie.
gebbissimo
7

Wydaje się, że w odpowiedziach (również) jest wiele nieporozumień.

git submodule initjest nie przeznaczony do generowania magiczną rzeczy w .git / konfiguracji (od .gitmodules). Jego celem jest ustawienie czegoś w całkowicie pustym podkatalogu po sklonowaniu projektu nadrzędnego lub ściągnięciu zatwierdzenia, które dodaje wcześniej nieistniejący moduł podrzędny.

Innymi słowy, podążasz za git cloneprojektem, który ma podmoduły (które poznasz po tym, że klon pobrał plik .gitmodules) przez rozszerzenie git submodule update --init --recursive.

Zdajesz nie postępować git submodule add ...z git submodule init(lub git submodule update --init), że nie ma pracy. W rzeczywistości dodatek będzie już aktualizował odpowiedni plik .git / config, jeśli coś działa.

EDYTOWAĆ

Jeśli wcześniej nieistniejący podmoduł git został dodany przez kogoś innego i wykonasz takie git pullzatwierdzenie, katalog tego modułu podrzędnego będzie całkowicie pusty (podczas wykonywania git submodule statusnowego modułu podrzędnego hash powinien być widoczny, ale będzie miał -przed it.) W takim przypadku musisz również podążać za swoim git pullrównież git submodule update --init(plusem, --recursivejeśli jest to podmoduł wewnątrz podmodułu), aby pobrać nowy, wcześniej nieistniejący podmoduł wyewidencjonowany; tak jak po początkowym sklonowaniu projektu z podmodułami (gdzie oczywiście nie miałeś tych podmodułów wcześniej).

Carlo Wood
źródło
1
To interesujące, ponieważ git help submodulemówi tak o init: "init: Zainicjuj podmoduły zapisane w indeksie (które zostały dodane i zatwierdzone w innym miejscu), kopiując nazwy i adresy URL podmodułów z .gitmodules do .git / config." Więc na pewno brzmi, że powinien robić dokładnie to, co mówisz, że nie robi ...? Czas na aktualizację dokumentacji gita?
Brad
@brad Wydaje mi się, że to nie powiedziałem - ale dodałem wyjaśnienie dotyczące tego konkretnego przypadku. Dzięki.
Carlo Wood
@CarloCzy masz jakiś pomysł, dlaczego twórcy podmodułów git zdecydowali, że --initpowinno być konieczne uzyskanie nowych modułów podrzędnych (zamiast pobierać je automatycznie update)? Wygląda na to, że aktualizacja repozytorium powinna pobrać wszystko, co konieczne, chyba że zniszczyłaby dane. Dzięki --initniemu musisz wiedzieć, że mogły zostać utworzone nowe podmoduły, lub po prostu zawsze generować a za --initkażdym razem, w takim przypadku wydaje się, że powinien być domyślnie włączony.
Catskul
@Catskul Oczywiście nie mam pojęcia, dlaczego autorzy podmodułów git zdecydowali cokolwiek, ale przypuszczam, że „aktualizacja” jest zarezerwowana do aktualizacji czegoś, co już istnieje, a „init” służy do tworzenia czegoś (lokalnie) nowego. Pod maską te dwie osoby są prawdopodobnie na tyle różne, że uzasadniają inne polecenie.
Carlo Wood
6

Miałem ten sam problem, ale żadne z powyższych rozwiązań nie pomogło. Wpisy w .gitmodules i .git / config były prawidłowe, ale polecenie git submodules update --init --recursivenic nie robiło. Usunąłem również katalog podmodułów, uruchomiłem git submodules update --init --recursivei odzyskałem katalog podmodułów, ale z dokładnie takim samym zatwierdzeniem jak poprzednio.

Znalazłem odpowiedź na tej stronie . Polecenie to:git submodule update --remote

masterop
źródło
2
Dla mnie było to również właściwe rozwiązanie. git submodule updateZamiast tego biegałem git submodule update --remote.
Andrew Medlin
5

Trochę magicznie, ale dzisiaj pobiegłem, git submodule initza którym git submodule syncpodążał, git submodule updatei zaczęło ciągnąć moje podmoduły ... Magia? Być może! To naprawdę jedno z najbardziej irytujących doświadczeń z Git…

Podrap to. Właściwie udało mi się to przez działanie git submodule update --init --recursive. Mam nadzieję że to pomoże.

PS: Upewnij się, że jesteś w głównym katalogu git, a nie w module podrzędnym.

Levi Figueira
źródło
7
Nie, to dla mnie absolutnie nic.
Igor Ganapolsky
@IgorGanapolsky Powyższą odpowiedź zredagowałem, podając informacje, które mi pomogły. Daj znać czy działa!
Levi Figueira
Wypróbowałem twoje nowe polecenia, ale one też nic nie zrobiły.
IgorGanapolsky
5

Myślenie, że .gitmoduleswystarczy ręczna konfiguracja , jest NIEPOPRAWNE

Mój lokalny git version 2.22.0w chwili pisania tego tekstu.

Więc doszedłem do tego wątku, zastanawiając się, dlaczego nie git submodule initdziała; Skonfigurowałem .gitmodulesplik i przystąpiłem do git submodule init...

WAŻNY

  1. git submodule add company/project.git includes/projectjest wymagane (przy pierwszym dodawaniu modułu), spowoduje to:

    • dodaj konfigurację do .git/config
    • zaktualizuj .gitmodulesplik
    • śledź lokalizację podmodułu (includes/project w tym przykładzie).
  2. Państwo musi następniegit commit po dodaniu submodule, to popełni .gitmodulesi gąsienicowym lokalizacja modułem.

Gdy projekt zostanie ponownie sklonowany, będzie miał .gitmodulespusty katalog modułów podrzędnych (np. includes/projectW tym przykładzie). W tym momencie.git/config nie ma jeszcze konfiguracji podmodułu, dopóki nie git submodule initzostanie uruchomiony, i pamiętaj, że działa to tylko dlatego, że .gitmodulesAND includes/projectsą śledzone w głównym repozytorium git.

Zobacz także:

Farinspace
źródło
3

Miałem ten sam problem.

.gitmodulesmiał moduł podrzędny, ale po git submodule initpoleceniu go nie było.git/config .

Okazuje się, że programista, który dodał moduł podrzędny, dodał również katalog podmodułu do .gitignorepliku. To nie działa.

joseph.hainline
źródło
2

Tak jak Ty, odkryłem, że synchronizacja modułu podrzędnego git nie robi tego, czego oczekujesz. Dopiero po git submodule addponownym wykonaniu jawnego adresu URL modułu podrzędnego zmienia się.

Więc umieściłem ten skrypt w ~/bin/git-submodule-sync.rb:

https://gist.github.com/frimik/5125436

Używam też tej samej logiki w kilku skryptach wdrażania git po otrzymaniu.

Wszystko, co teraz muszę zrobić, to edytować .gitmodules, a następnie uruchomić ten skrypt i w końcu działa tak, jak myślałem, że git submodule syncpowinien.

fridh
źródło
Wydaje się, że dzieje się tak tylko w niektórych repozytoriach ... prawdopodobnie z powodu błędu w Git. Od dłuższego czasu nie zdarzyło mi się to na nowo utworzonych repozytoriach, ale dawno temu zdarzało się to cały czas na niektórych
repozytoriach
2

Miałem dziś ten sam problem i doszedłem do wniosku, że ponieważ wpisałem git submodule initwtedy, miałem te linie w moim .git/config:

[submodule]
   active = .

Usunąłem to i wpisałem:

git submodule update --init --remote

I wszystko wróciło do normy, mój podmoduł jak zwykle zaktualizowany w swoim podkatalogu.

Eric Jeker
źródło
2

Problem dla mnie polega na tym, że poprzedni programista repozytorium zatwierdził submodules/thingfolder jako zwykły folder, co oznacza, że ​​kiedy próbowałem uruchomić git submodule add ..., nie powiodło się z:'submodules/thing' already exists in the index :, ale próba zaktualizowania modułu podrzędnego również zakończy się niepowodzeniem, ponieważ zobaczył, że ścieżka nie zawierają podmoduł.

Aby to naprawić, musiałem usunąć submodules/thingfolder, zatwierdzić usunięcie, a następnie uruchomić git submodule addpolecenie, aby dodać go z powrotem poprawnie:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing
Venryx
źródło
1

Kiedy zobaczyłem to dzisiaj, programista przeniósł część drzewa do nowego podkatalogu i wygląda na to, że jego klient git nie zarejestrował zaktualizowanych reguł podprojektu w drzewie, zamiast tego zostały po prostu nukowane, pozostawiając .gitmodules odwołanie do nieaktualnych lokalizacje i podprojekty, które już nie istnieją w bieżącym drzewie.

Dodanie modułów podrzędnych z powrotem i porównanie zatwierdzeń shas modułu podrzędnego z tymi znalezionymi w git show $breaking_commit_sha(wyszukaj wiersze pasujące ^-Subprojectdo wyrażenia regularnego ) w celu dostosowania do potrzeb naprawiono rzeczy.

Phil P.
źródło
1

Usunięcie katalogu podmodułu i jego zawartości (folder „zewnętrzny / pyfacebook”), jeśli istniał wcześniej, git submodule add ...może rozwiązać problemy.

atahan
źródło
1
To był dla mnie problem. Ktoś popełnił folder „submodule” jako zwykły folder, co oznacza, że ​​kiedy próbowałem uruchomić „git submodule add ...”, zakończyło się to niepowodzeniem i wyświetleniem: „Drzewo stanu dostawcy / mobx” już istnieje w indeksie ” , ale próba zaktualizowania modułu podrzędnego również zakończy się niepowodzeniem, ponieważ zobaczył, że ścieżka nie zawiera modułu podrzędnego). Aby to naprawić, musiałem usunąć folder, zatwierdzić usunięcie, a następnie uruchomić polecenie git add, aby dodać go ponownie.
Venryx
1

Miałem podobny problem z submodułem. Po prostu nie chciał być klonowany / ściągany / aktualizowany / cokolwiek.

Podczas próby ponownego dodania modułu podrzędnego za pomocą git submodule add [email protected] destinationotrzymałem następujące dane wyjściowe:

A git directory for 'destination' is found locally with remote(s):
  origin        [email protected]
If you want to reuse this local git directory instead of cloning again from
  [email protected]
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

Próbowałem więc wymusić polecenie dodawania :
git submodule add --force [email protected] destination

To zadziałało w moim przypadku.

Arvid
źródło
0

Dla przypomnienia:
ten sam problem utworzyłem, dodając puste repozytorium jako moduł podrzędny. W tym przypadku nie było dostępnego skrótu referencyjnego dla podmodułu, co doprowadziło do błędu opisanego przez oryginalny plakat.

Wymuszenie dodania repozytorium po zatwierdzeniu go rozwiązało problem (jak w poście Arvids)
git submodule add --force [email protected] destination

Marc
źródło
0
  • Usuń moduł podrzędny z pliku .git/config
  • Uruchom git submodule initpolecenie
  • Przejdź do katalogu modułu podrzędnego i uruchom git pull origin master

Powinno teraz działać

Masoud Darvishian
źródło
0

Po prostu dzielę się tym, co zadziałało dla mnie:

git clone --recurse-submodules <repository path>

Powoduje to sklonowanie zdalnego repozytorium zawierającego już moduły podrzędne. Oznacza to, że po sklonowaniu nie trzeba uruchamiać aktualizacji modułu podrzędnego git ani inicjować go.

Anne Kariny Silva Freitas
źródło
0

Poniższe polecenie synchronizacji rozwiązało problem:

git submodule sync
Nishant Chauhan
źródło