Jak mogę iterować przez wszystkie lokalne gałęzie w moim repozytorium przy użyciu skryptu bash. Muszę iterować i sprawdzić, czy istnieje różnica między oddziałem a niektórymi zdalnymi oddziałami. Dawny
for branch in $(git branch);
do
git log --oneline $branch ^remotes/origin/master;
done
Muszę zrobić coś podobnego do podanego powyżej, ale problem, z którym się zmagam, to $ (gałąź git) daje mi foldery wewnątrz folderu repozytorium wraz z gałęziami obecnymi w repozytorium.
Czy to właściwy sposób rozwiązania tego problemu? Czy jest na to inny sposób?
Dziękuję Ci
for b in "$(git branch)"; do git branch -D $b; done
Odpowiedzi:
Nie powinieneś używać git branch podczas pisania skryptów. Git zapewnia interfejs „hydrauliczny” który został specjalnie zaprojektowany do użycia w skryptach (wiele aktualnych i historycznych implementacji normalnych poleceń Git (dodawanie, pobieranie, scalanie itp.) Używa tego samego interfejsu).
Polecenie hydrauliczne, które chcesz, to git for-each-ref :
Uwaga: Nie potrzebujesz
remotes/
przedrostka w zdalnym odnośniku, chyba że masz inne odniesienia, które powodująorigin/master
dopasowanie wielu miejsc w ścieżce wyszukiwania nazw referencyjnych (zobacz „Symboliczna nazwa odniesienia…” w sekcji Określanie wersji w git-rev-parse (1) ). Jeśli próbujesz explictly uniknąć niejasności, a następnie przejść z pełną nazwą ref:refs/remotes/origin/master
.Otrzymasz takie wyniki:
Możesz przesłać to wyjście do sh .
Jeśli nie podoba ci się pomysł generowania kodu powłoki, możesz porzucić trochę solidności * i zrobić to:
* Nazwy ref powinny być chronione przed podziałem na słowa w powłoce (zobacz git-check-ref-format (1) ). Osobiście trzymałbym się poprzedniej wersji (wygenerowany kod powłoki); Jestem bardziej przekonany, że nie może się z tym stać nic niewłaściwego.
Ponieważ określiłeś bash i obsługuje on tablice, możesz zachować bezpieczeństwo i nadal unikać generowania wnętrzności pętli:
Możesz zrobić coś podobnego,
$@
jeśli nie używasz powłoki obsługującej tablice (set --
do inicjalizacji iset -- "$@" %(refname)
dodawania elementów).źródło
--merged
, czy musiałbym zduplikować logikę w git branch? Musi być na to lepszy sposób.git for-each-ref refs/heads | cut -d/ -f3-
git for-each-ref refs/heads --format='%(refname)'
for-each-ref
teraz obsługuje wszystkie selektory gałęzi, takie jak--merged
i,git branch
agit tag
teraz są one faktycznie zaimplementowanegit for-each-ref
same w sobie, przynajmniej dla przypadków istniejących na liście. (Tworzenie nowych gałęzi i tagów nie jest i nie powinno być częściąfor-each-ref
.)Dzieje się tak, ponieważ
git branch
oznacza bieżącą gałąź gwiazdką, np .:więc
$(git branch)
rozwija się do np.* master mybranch
, a następnie*
rozwija się do listy plików w bieżącym katalogu.Nie widzę oczywistej opcji, aby nie drukować gwiazdki w pierwszej kolejności; ale możesz to odciąć:
źródło
$(git branch | sed -e s/\\*//g)
.3-
rozwiązanie.$(git branch | sed 's/^..//')
$(git branch | tr -d " *")
mapfile
Wbudowany bash jest do tego zbudowanywszystkie gałęzie git:
git branch --all --format='%(refname:short)'
wszystkie lokalne oddziały git:
git branch --format='%(refname:short)'
wszystkie zdalne gałęzie git:
git branch --remotes --format='%(refname:short)'
iteruj przez wszystkie gałęzie git:
mapfile -t -C my_callback -c 1 < <( get_branches )
przykład:
dla szczególnej sytuacji PO:
źródło: wyświetla wszystkie lokalne gałęzie git bez gwiazdki
źródło
Iteruję tak jak na przykład:
źródło
Zasugerowałbym
$(git branch|grep -o "[0-9A-Za-z]\+")
, aby nazwy lokalnych oddziałów miały tylko cyfry, az i / lub litery AZźródło
Przyjęta odpowiedź jest poprawna i naprawdę powinna być zastosowanym podejściem, ale rozwiązanie problemu w bash to świetne ćwiczenie w zrozumieniu, jak działają powłoki. Sztuczka polegająca na zrobieniu tego za pomocą basha bez wykonywania dodatkowych operacji na tekście polega na zapewnieniu, że wyjście git branch nigdy nie zostanie rozwinięte jako część polecenia wykonywanego przez powłokę. Zapobiega to rozszerzaniu się gwiazdki w rozszerzaniu nazwy pliku (krok 8) rozwijania powłoki (patrz http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html )
Użyj bash while construct z poleceniem read, aby podzielić wyjście git branch na linie. Znak „*” będzie czytany jako znak dosłowny. Użyj instrukcji case, aby ją dopasować, zwracając szczególną uwagę na pasujące wzorce.
Gwiazdki zarówno w konstrukcji bash case, jak i przy podstawianiu parametrów muszą być poprzedzone odwrotnymi ukośnikami, aby zapobiec ich interpretacji przez powłokę jako znaków pasujących do wzorca. Spacje są również chronione (aby zapobiec tokenizacji), ponieważ dosłownie dopasowujesz „*”.
źródło
Moim zdaniem najłatwiejsza do zapamiętania opcja:
git branch | grep "[^* ]+" -Eo
Wynik:
Opcja -o Grepa (--only-matching) ogranicza dane wyjściowe tylko do pasujących części danych wejściowych.
Ponieważ ani spacja, ani * nie są prawidłowe w nazwach gałęzi Git, zwraca to listę gałęzi bez dodatkowych znaków.
Edycja: jeśli jesteś w stanie odłączonej głowy , musisz odfiltrować bieżący wpis:
git branch --list | grep -v "HEAD detached" | grep "[^* ]+" -oE
źródło
To, co ostatecznie zrobiłem, w odniesieniu do twojego pytania (i zainspirowane wspomnieniem ccpizza
tr
):git branch | tr -d ' *' | while IFS='' read -r line; do git log --oneline "$line" ^remotes/origin/master; done
(Często używam pętli while. Podczas gdy dla pewnych rzeczy na pewno chciałbyś użyć wskazanej nazwy zmiennej [na przykład "gałąź"], przez większość czasu zajmuję się tylko zrobieniem czegoś z każdym wierszem danych wejściowych. Używanie `` linia '' zamiast `` gałęzi '' jest ukłonem w stronę wielokrotnego użytku / pamięci mięśni / wydajności).
źródło
Rozpoczynając od odpowiedzi @ finn (dziękuję!), Poniższe instrukcje pozwolą ci iterować po gałęziach bez tworzenia interweniującego skryptu powłoki. Jest wystarczająco solidny, o ile w nazwie gałęzi nie ma znaków nowych linii :)
Pętla while działa w podpowłoce, co zwykle jest w porządku, chyba że ustawiasz zmienne powłoki, do których chcesz uzyskać dostęp w bieżącej powłoce. W takim przypadku użyj podstawiania procesu, aby odwrócić potok:
źródło
Jeśli jesteś w tym stanie:
I uruchamiasz ten kod:
Otrzymasz ten wynik:
źródło
for b in "$(git branch)"; do git branch -D $b; done
Nie komplikuj
Prosty sposób na uzyskanie nazwy gałęzi w pętli za pomocą skryptu bash.
Wynik:
źródło
Odpowiedź Googliana, ale bez użycia dla
źródło
Używa poleceń git plumbing , które są przeznaczone do obsługi skryptów. Jest to również proste i standardowe.
Odniesienie: Ukończenie Bash w Git
źródło