Normalnie nie odpowiedziałbym na pytanie, które ma już 16 odpowiedzi, ale wszystkie inne odpowiedzi są błędne, a właściwa odpowiedź jest tak prosta. Pytanie brzmi: „Czy istnieje prosty sposób usunięcia wszystkich gałęzi śledzenia, których zdalny odpowiednik już nie istnieje?”
Jeśli „prosty” oznacza usunięcie ich wszystkich za jednym razem, nie jest kruchy, nie jest niebezpieczny i bez polegania na narzędziach, które nie wszyscy czytelnicy będą mieli, wtedy właściwa odpowiedź brzmi: nie.
Niektóre odpowiedzi są proste, ale nie robią tego, o co pytano. Inni robią to, o co proszono, ale nie są proste: wszyscy polegają na analizie danych wyjściowych Gita za pomocą poleceń manipulacji tekstem lub języków skryptowych, które mogą nie być obecne w każdym systemie. Ponadto większość sugestii używa komend porcelanowych, których wynik nie jest przeznaczony do analizowania przez skrypt („porcelana” odnosi się do komend przeznaczonych do działania przez człowieka; skrypty powinny używać komend niższego poziomu).
Dalsza lektura:
Jeśli chcesz to zrobić bezpiecznie, w przypadku zastosowania w pytaniu (gałęzie śledzące odśmiecanie, które zostały usunięte na serwerze, ale nadal istnieją jako gałęzie lokalne) i tylko za pomocą poleceń Git wysokiego poziomu, musisz:
git fetch --prune
(lub git fetch -p
, który jest aliasem lub git prune remote origin
który robi to samo bez pobierania i prawdopodobnie nie jest tym, czego chcesz przez większość czasu).
- Zanotuj wszystkie zdalne gałęzie, które są zgłaszane jako usunięte. Lub, aby je później znaleźć
git branch -v
(każda osierocona gałąź śledzenia będzie oznaczona „[odszedł]”).
git branch -d [branch_name]
w każdej osieroconej gałęzi śledzenia
(co proponują niektóre inne odpowiedzi).
Jeśli chcesz napisać rozwiązanie, to for-each-ref
jest twój punkt wyjścia, jak w odpowiedzi Marka Longaira tutaj i tej odpowiedzi na inne pytanie , ale nie widzę sposobu na wykorzystanie go bez napisania pętli skryptu powłoki lub użycia xargs lub czegoś takiego .
Wyjaśnienie tła
Aby zrozumieć, co się dzieje, musisz zdawać sobie sprawę, że w sytuacji śledzenia oddziałów nie masz jednej gałęzi, ale trzy. (I przypomnij sobie, że „gałąź” oznacza po prostu wskaźnik do zatwierdzenia.)
Biorąc pod uwagę gałąź śledzenia feature/X
, zdalne repozytorium (serwer) będzie miało tę gałąź i będzie ją wywoływać feature/X
. Twoje lokalne repozytorium ma gałąź, remotes/origin/feature/X
co oznacza: „To, co zdalnie powiedział mi jego funkcja / gałąź X, kiedy ostatnio rozmawialiśmy”, a na koniec, lokalne repozytorium ma gałąź, feature/X
która wskazuje na twoje ostatnie zatwierdzenie i jest skonfigurowana do „śledzenie” remotes/origin/feature/X
, co oznacza, że możesz pociągać i pchać, aby je wyrównać.
W pewnym momencie ktoś usunął feature/X
zdalne sterowanie. Od tego momentu pozostaniesz z lokalnym feature/X
(którego prawdopodobnie już nie chcesz, ponieważ praca nad funkcją X jest prawdopodobnie zakończona), a twój z remotes/origin/feature/X
pewnością jest bezużyteczny, ponieważ jego jedynym celem było zapamiętanie stanu gałęzi serwera .
A Git pozwoli ci automatycznie wyczyścić zbędne remotes/origin/feature/X
- to właśnie git fetch --prune
robi - ale z jakiegoś powodu nie pozwala ci automatycznie usunąć własnego feature/X
... nawet jeśli feature/X
nadal zawiera osierocone informacje o śledzeniu, więc ma informacje w celu zidentyfikowania wcześniejszych gałęzi śledzenia, które zostały całkowicie scalone. (Wszakże może dać Ci informacje, które pozwala wykonać operację ręcznie samemu).
* master
w moim systemie. Następujące polecenie działało dla mnie:git branch -d $(git branch --merged |tail -n +2)