Mam repozytorium Git, które zawiera kilka podmodułów. Jak wyświetlić nazwy wszystkich podmodułów po git submodule init
uruchomieniu?
git submodule foreach
Komenda mogła echo imiona modułem, ale to działa tylko jeżeli zostały one sprawdzone z których się nie stało po kroku Init. Jest więcej kroków w łańcuchu, które muszą się zdarzyć, zanim będą mogły zostać wyewidencjonowane, i nie chcę wprowadzać sztywnych nazw podmodułów do skryptu.
Czy istnieje więc polecenie Git, aby uzyskać nazwy wszystkich aktualnie zarejestrowanych, ale jeszcze nie sprawdzonych submodułów?
git
git-submodules
tpg2114
źródło
źródło
git submodule
zachowuje się tak, jak oczekiwałem hipotetycznegogit submodule list
zachowania - po prostu nigdy nie myślałem, aby sprawdzić, co się stanie bez argumentówgit submodule
. (Cieszę się, że przetestowałem ten link, ponieważ początkowo złapałem niewłaściwy link „Udostępnij”!)git submodule list
nie istniałem igit submodule help
nie pomogłem (według tego ostatniego rozwiązaniegit submodule
nie jest poprawne).paths
,names
a nie łamie się, gdy zawierają znaki specjalne. Próbowałem udzielić odpowiedzi zarówno na nazwy, jak i ścieżki, które powinny być bezpieczne: stackoverflow.com/a/56912913/3215929Odpowiedzi:
Możesz użyć tego samego mechanizmu, co
git submodule init
sam w sobie, czyli popatrzeć.gitmodules
. Te pliki wyliczają każdą ścieżkę podmodułu i adres URL, do którego się odnosi.Na przykład z katalogu głównego repozytorium
cat .gitmodules
wydrukuje zawartość na ekranie (zakładając, że maszcat
).Ponieważ pliki .gitmodule mają format konfiguracji Git, możesz użyć git config do parsowania tych plików:
Pokaże wszystkie wpisy submodułów i
dostaniesz tylko samą ścieżkę submodułu.
źródło
cat .gitmodules
w katalogu głównym repozytorium ...awk
Część nie, jeśli masz spacji w ścieżce submodule.awk
nie działa w przypadku submodułów ze spacjami! Polecenie powinno brzmiećgit config -z --file .gitmodules --get-regexp '\.path$' | sed -nz 's/^[^\n]*\n//p' | tr '\0' '\n'
(potrzebujesz nowoczesnegosed
z-z
). Nie udaje się to w przypadku ścieżek z nowymi liniami (można je tworzyćgit mv
). Jeśli chcesz się przed nimi zabezpieczyć, porzuć| tr '\0' '\n'
i użyj czegoś takiego jak... | while IFS='' read -d '' path; do ...
do dalszego przetwarzania za pomocą bash. To wymaga nowoczesnej bash, która rozumieread -d ''
(nie zapomnij o przestrzeni między-d
i''
).Możesz użyć
git submodule status
lub opcjonalnie,git submodule status --recursive
jeśli chcesz wyświetlić zagnieżdżone podmoduły.Z dokumentacji Git:
źródło
git submodule update --init --recursive
aby zainicjować wszystkie submoduły.git
komendy bez żadnej pomocy bash. To rozwiązanie jest eleganckie, ponieważ działa dobrze w dowolnym punkcie kopii roboczej (ale oczywiście same podmoduły, których wynik dotyczy bezpośrednio ich samych).git submodule
bez argumentów jest to samo, cogit submodule status
, więc możesz zaoszczędzić sobie wpisując 7 znaków ;-)git submodule status --recursive
działa, alegit submodule --recursive
nie. Te 7 postaci coś ci kupuje. To zależy od twoich potrzeb.Aby zwrócić tylko nazwy zarejestrowanych podmodułów, możesz użyć tego polecenia:
Pomyśl o tym, ponieważ
git submodule --list
to nie istnieje.źródło
perl -ne '/^\s*path =\s*(.*)/ and push(@submods, $1); END { print(join("\n", sort(@submods)));}' "$(git rev-parse --show-toplevel)/.gitmodules"
które w porównaniu z tą odpowiedzią (1) działa z dowolnego podkatalogu (choć nie w podmodule); (2) sortuje submoduły według nazwy; i (3) ignoruje komentowane wiersze w .gitmodules.path
może być obecne w submodule name (git submodule add https://github.com/commercialhaskell/path.git
). Ale pewnie już o tym wiedziałeś. Jeśli chcesz uzyskać dostęp.gitconfig
z dowolnego miejsca w drzewie roboczym lub chcesz uruchomić to w--bare
repozytorium, możesz użyć czegoś takiegogit cat-file -p HEAD:.gitmodules | ...
. Jeśli potrzebujesz odwołać się do pliku „etapowego”, możesz to zrobićgit cat-file -p :.gitmodules | ...
, jednak wymaga toindex
obecności git .Następujące polecenie wyświetli listę podmodułów:
Wynik jest mniej więcej taki:
Uwaga: Wymaga Git 2.7.0 lub nowszej wersji.
źródło
git ls-files --stage | grep ^160000
(z odpowiedzi stackoverflow.com/a/29325219 ) wydaje się dawać ten sam wynik, więc być może jest to dobry zamiennik, jeśli chcesz być kompatybilny ze starszymi gitsami.--
podwójne myślniki wsubmodule--helper
Posługiwać się:
Wyświetli listę wszystkich podmodułów w określonym repozytorium Git.
źródło
git submodule [status]
(uwagastatus
jest sugerowana, jeśli zostanie pominięta, więc jest taka sama).fatal: no submodule mapping found in .gitmodules for path 'bla-bla/foo-bar'
. Najpierw musisz usunąć wszystkie wewnętrzne repozytoria, które nie zostały jeszcze poddane podmodulowi.--recursive
flagi, musisz jawnie dodaćstatus
polecenie:git submodule status --recursive
działa, alegit submodule --recursive
nie działa.Używam tego:
źródło
Zauważyłem, że polecenie podane w odpowiedzi na to pytanie dało mi informacje, których szukałem:
W .gitmodule nie znaleziono mapowania submodułów dla ścieżki, która nie jest submodułem
źródło
git ls-files --stage | grep 160000 | perl -ne 'chomp;split;print "$_[3]\n"'
.gimodules
nic.git/config
. (Nie jestem pewien, jak to się stało, mam repozytorium w tym stanie. To był błąd, więc było rozwiązaniegit rm
).grep "^160000 "
byłaby nieco bardziej wytrzymała.Jeśli nie masz nic przeciwko operowaniu tylko na zainicjowanych submodułach, możesz użyć,
git submodule foreach
aby uniknąć parsowania tekstu.źródło
Możesz użyć:
źródło
test (master)
(nazwa ze spacją i nawiasami okrągłymi), co jest prawidłową nazwą podmodułu . Polecenia również nie można naprawić, ponieważ git albo drukuje,module
albomodule (branch)
. I jest jeszcze gorzej, ponieważ to polecenie nie jest porcelaną, więc wynik polecenia może ulec zmianie bez wcześniejszego powiadomienia.Używam tego:
Dane wyjściowe (ścieżka + wersja):
źródło
Aby wyświetlić wszystkie submoduły według nazwy:
git submodule --quiet foreach --recursive 'echo $name'
źródło
To działało dla mnie:
Opiera się na tym świetnym artykule: Zrozumienie Git Submodules
Musi przeczytać
grep ^160000
.źródło
git ls-files --stage | grep ^160000
wydaje się dawać takie same wyniki, jakgit submodule--helper list
z odpowiedzi stackoverflow.com/a/40877379👍🏼
źródło
.url
kluczy, więc mogą pojawiać się również inne wpisy (zwykle nie ma żadnych, ale gówno się zdarza). Powinieneś użyć--local
tutaj, ponieważ nie chcesz widzieć--global
i--system
ustawień. I na koniec należy pamiętać, ponieważ można go przeoczyć, działa tylko w przypadku podmodułów, które są już obecne w.git/config
(jak pogit submodule init
, patrz pytanie).git config
pozwala określić plik konfiguracyjny.I
.gitmodules
jest plikiem konfiguracyjnym.Tak więc za pomocą „ użyj spacji jako separatora z poleceniem cięcia ”:
Spowoduje to wyświetlenie tylko ścieżek, po jednej na zadeklarowany podmoduł.
Jak zauważa Tino w komentarzach :
Jako bardziej niezawodną alternatywę, Tino proponuje:
źródło
git submodule add https://github.com/hilbix/bashy.git "sub module"; git mv 'sub module' $'sub\nmodule'
). Zobacz mój komentarz do zaakceptowanej odpowiedzi, która jest bardzo podobna do twojej.W mojej wersji Git [1] każdy podmoduł Git ma a
name
i apath
. Niekoniecznie muszą być takie same [2] . Uzyskanie obu w niezawodny sposób, bez uprzedniego sprawdzenia submodułów (git update --init
), jest trudnym czarodziejstwem powłoki.Uzyskaj listę submodułów
names
Nie mogę znaleźć sposób, jak to osiągnąć stosując
git config
lub innegogit
polecenia. Dlatego wróciliśmy do wyrażenia regularnego.gitmodules
(super brzydkie). Ale wydaje się to nieco bezpieczne, ponieważgit
ogranicza możliwą przestrzeń kodu dozwoloną dla podmodułunames
. Ponadto, ponieważ prawdopodobnie chcesz użyć tej listy do dalszego przetwarzania powłoki, rozwiązanie poniżej oddzielne wpisy za pomocąNULL
-bytes (\0
).I w twoim skrypcie:
Uwaga :
read -rd ''
wymagabash
i nie będzie działaćsh
.Uzyskaj listę submodułów
paths
W moim podejściu staram nie przetwarzać dane wyjściowe
git config --get-regexp
zawk
,tr
,sed
, ... ale zamiast przechodzić to zerowy bajt oddzielone z powrotemgit config --get
. Ma to na celu uniknięcie problemów z znakami nowej linii, spacjami i innymi znakami specjalnymi (np. Unicode) w submodulepaths
. Ponadto, ponieważ prawdopodobnie chcesz użyć tej listy do dalszego przetwarzania powłoki, rozwiązanie poniżej oddzielne wpisy za pomocąNULL
-bytes (\0
).Na przykład w skrypcie Bash możesz:
Uwaga :
read -rd ''
wymagabash
i nie będzie działaćsh
.Przypisy
[1] Wersja Git
[2] Submoduł z rozbieżnymi
name
ipath
Skonfiguruj repozytorium testowe:
Przesuń submoduł, aby utworzyć
name
ipath
rozdzielić:Testowanie
Skonfiguruj repozytorium testowe:
.gitmodules
:Pobierz listę submodułów
names
Pobierz listę submodułów
paths
źródło
Jeśli nie ma żadnego
.gitmodules
pliku, ale konfiguracja submodułów istnieje w.git/modules/
:źródło
Oto inny sposób na parsowanie nazw podmodułów Git z .gitmodules bez potrzeby ustawiania sed lub fantazyjnych ustawień IFS. :-)
źródło