Czy istnieje sposób, aby git pull automatycznie aktualizował submoduły?

203

Czy istnieje sposób, aby automatycznie mieć git submodule update(lub najlepiej git submodule update --initdzwonić za każdym razem, gdy git pulljest to zrobione?

Szukasz ustawienia konfiguracji git lub aliasu git, aby Ci w tym pomóc.

philfreo
źródło
1
Dlaczego alias git jest lepszy od aliasu powłoki?
wnoise
20
Aliasy git są fajne, ponieważ zawierają polecenie w przestrzeni nazw „git”. Równie dobrze możesz zapytać, dlaczego wszystkie polecenia git zaczynają się od „git” zamiast mieć własne nazwy.
Lily Ballard
5
Dla każdego, kto to znajdzie, wysoko głosowane odpowiedzi są obecnie nieaktualne. Odpowiedź Kane'a jest prawidłowa: stackoverflow.com/a/49427199/3499424
John Neuhaus

Odpowiedzi:

176

Począwszy od Gita 2.14 , możesz używać git pull --recurse-submodules(i aliasować go na cokolwiek chcesz).

Od wersji 2.15 Git można ustawić wartość submodule.recursetrue, aby umożliwić pożądane zachowanie.

Możesz to zrobić globalnie, uruchamiając:

git config --global submodule.recurse true
Kane
źródło
3
Potwierdzenie w wersji 2.16, ustawienie tej wartości na true spowoduje git pullrównież pobranie submodułu i uruchomienie submodule update. To naprawdę musi być teraz zaakceptowana odpowiedź
John Neuhaus
1
Aby ustawić to globalnie:git config --global submodule.recurse true
wintersolutions
14
Sfrustrowały mnie submoduły, a potem to zrobiłem. Teraz działają tak, jak bym się spodziewał. Czy istnieje powód, dla którego nie myślę o tym, że nie jest to zachowanie domyślne?
Ben,
9
Powinny również to umożliwić git clone. I włącz to domyślnie. W przeciwnym razie zawsze będzie ogromny opór przed korzystaniem z submodułów, ponieważ moduły ludzi zawsze nie są zsynchronizowane :-(
Ciro Santilli 30 冠状 病 六四 事件 法轮功
1
@CiroSantilli新疆改造中心法轮功六四事件Santilli git polecenia (na przykład commit, fetch, pulletc.) są przeznaczone do stosowania tylko do aktualnego repozytorium. submoduł jest innym repozytorium i domyślnie nie powinny na niego wpływać polecenia wykonywane w repozytorium nadrzędnym. jest to rodzaj decyzji projektowej autorstwa git-developer.
anion
113

git config --global alias.pullall '!git pull && git submodule update --init --recursive'

Jeśli chcesz przekazać argumenty do git pull, użyj tego zamiast tego:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'
Lily Ballard
źródło
4
pamiętaj, aby używać „git config --global”, jeśli chcesz mieć ten alias we wszystkich używanych repozytoriach git
yoyo
43

Począwszy od wersji 1.7.5 Git powinien automatycznie aktualizować podmoduły, tak jak tego chcesz.

[EDIT: za komentarze: nowy 1.7.5 zachowanie jest do automatycznego pobierania najnowszych zobowiązuje do submodules, ale nie do aktualizować je (w git submodule updatesensie). Dlatego informacje zawarte w tej odpowiedzi są istotne jako tło, ale same w sobie nie stanowią pełnej odpowiedzi. Nadal potrzebujesz aliasu, aby pobrać i zaktualizować submoduły za pomocą jednego polecenia.]

Domyślne zachowanie, „na żądanie”, polega na aktualizacji podmodułów za każdym razem, gdy pobierasz zatwierdzenie, które aktualizuje zatwierdzenie podmodułu, a to zatwierdzenie nie znajduje się jeszcze w lokalnym klonie.
Możesz także aktualizować go przy każdym pobieraniu lub nigdy (zakładam, że zachowanie wcześniejsze niż 1.7.5).
Opcja konfiguracji zmiany tego zachowania to fetch.recurseSubmodules.

Ta opcja może być ustawiona na wartość logiczną lub na on-demand.
Ustawienie go na wartość logiczną zmienia zachowanie fetchi pullbezwarunkową rekurencję w podmoduły, gdy jest ustawiona na wartość true lub w ogóle nie powtarza się, gdy jest ustawiona na wartość false.

Po ustawieniu na on-demand(wartość domyślna) fetchi pull będzie się powtarzać w zaludnionym podmodule tylko wtedy, gdy jego superprojekt pobierze zatwierdzenie, które aktualizuje odwołanie do podmodułu .

Widzieć:

po więcej informacji.

git fetch --recurse-submodules[=yes|on-demand|no]
Christopher Rogers
źródło
27
Uwaga: jak wyjaśniają poniższe odpowiedzi, powoduje to automatyczne pobieranie zmian, nadal musisz wykonać aktualizację submodułu - więc odpowiedź na alias jest poprawna.
Artem
4
@Artem jest poprawny. Ta odpowiedź, choć przydatna, nie obejmuje całego pytania. To ustawienie wykonuje po prostu a git fetch, a nie git submodule update.
Andrew Ferrier,
2
Ta odpowiedź jest bardzo zwodnicza. Nawet kiedy stosować git pull, zamiast git fetchtej opcji sprawia, że tylko pobieranie rekurencyjne. Nie zmieni to wcale zatwierdzenia zatwierdzonego w podmodułach. Tak git submodule updatejest nadal konieczne, jak zauważył @Artem.
Mark Amery
31

Dziwię się, że nikt nie wspominał o używaniu haków git do tego celu!

Po prostu dodaj pliki o nazwach post-checkouti post-mergedo .git/hookskatalogu odpowiednich repozytoriów i umieść w każdym z nich:

#!/bin/sh
git submodule update --init --recursive

Ponieważ konkretnie poprosiłeś o alias, zakładając, że chcesz go mieć dla wielu repozytoriów, możesz utworzyć alias, który doda je do repozytorium .git/hooks.

taleinat
źródło
2
Czy istnieje sposób, aby uczynić to ustawienie globalnym? A może dostajesz automatycznie przy sprawdzaniu repozytorium?
Raoul Steffen
3
Najnowsza wersja git, 2.9, dodała ustawienie nazwane core.hooksPathdla katalogu hooków , git-configwięcej informacji można znaleźć w dokumentacji .
taleinat
1
Jeśli chodzi o coś otrzymanego automatycznie przy kasie, szukałem, ale nic nie mogłem znaleźć. Jedno ze źródeł wspomniało, że nie jest to celowo obsługiwane ze względów bezpieczeństwa, ponieważ można raczej łatwo użyć go do uruchomienia dowolnego kodu na komputerach klienckich.
taleinat
1
Rozumiem, jak to może być problem z bezpieczeństwem. W końcu chcę go używać do uruchamiania kodu, który programuję na komputerach moich współpracowników, bez konieczności ich pouczania.
Raoul Steffen
1
To rozwiązanie było moją pierwszą myślą, ale potem zdałem sobie sprawę, że nie obejmie ludzi, którzy używają git pull --rebase:(
Vaz
8

Alias, jak sugeruje Kevin Ballard, jest idealnie dobrym rozwiązaniem. Aby rzucić inną opcję, możesz użyć haka po scaleniu, który po prostu działa git submodule update [--init].

Cascabel
źródło
7

Możesz utworzyć alias dla polecenia git, który automatycznie obsługuje aktualizację podmodułów. Dodaj następujące elementy do pliku .bashrc

# make git submodules usable
#   This overwrites the 'git' command with modifications where necessary, and
#   calls the original otherwise
git() {
    if [[ $@ == clone* ]]; then
        gitargs=$(echo "$@" | cut -c6-)
        command git clone --recursive $gitargs
    elif [[ $@ == pull* ]]; then
        command git "$@" && git submodule update --init --recursive
    elif [[ $@ == checkout* ]]; then
        command git "$@" && git submodule update --init --recursive
    else
        command git "$@"
    fi
}
Branden Ghena
źródło
1
Zamiast aliasu git, można dodać aliasy do git poprzez poleceniem alias lub poprzez tworzenie poleceń w ścieżce, które zaczynają się git- (git-bettermodule)
idbrii
7

Jak wspomnieli inni, możesz to łatwo ustawić za pomocą:

git config --global submodule.recurse true

Jednak jeśli jesteś podobny do mnie i masz bardziej złożoną .gitconfigkonfigurację (mój główny ~/.gitconfigplik używa includedo ładowania innych .gitconfigplików) i nigdy nie pamiętasz, jak przekonwertować między gitformatem konfiguracji wiersza polecenia a .gitconfigformatem, oto jak go dodać do dowolnego z twoich .gitconfigplików:

[submodule]
  recurse = true
JacobEvelyn
źródło
0

Jedyny sposób, w jaki udało mi się pobrać submoduły i zagnieżdżone moduły do ​​aktualizacji:

git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;

Z powodu nawiasów walczyłem o utworzenie aliasu przez terminal, więc musiałem ręcznie dodać to do .gitconfig dla globalnego:

[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"

Wszelkie sugestie dotyczące automatycznego uruchamiania poleceń lub aliasu?

Sauli Kiviranta
źródło