Jak przycinać lokalne gałęzie śledzenia, które już nie istnieją na odległość

768

Dzięki git remote prune originmogę usunąć lokalne oddziały, które nie są już na pilocie.

Ale chcę również usunąć lokalne gałęzie, które zostały utworzone z tych zdalnych gałęzi (fajnie byłoby sprawdzić, czy nie są one połączone).

W jaki sposób mogę to zrobić?

Alex
źródło
1
Jednowarstwowa, wieloplatformowa, nie wygląda na to, że kot spał na twojej klawiaturze: npx git-removed-branches(na sucho) lub npx git-removed-branches --prune(na serio). Musisz już mieć zainstalowany plik node.js. Zobacz odpowiedzi poniżej, aby uzyskać szczegółowe informacje.
Cristian Diaconescu

Odpowiedzi:

890

Po przycięciu możesz uzyskać listę zdalnych gałęzi za pomocą git branch -r. Listę oddziałów wraz ze zdalną gałęzią śledzenia można pobrać za pomocą git branch -vv. Korzystając z tych dwóch list, możesz znaleźć gałęzie zdalnego śledzenia, których nie ma na liście pilotów.

Ta linia powinna zrobić lewę (wymaga bashlub zshnie będzie działać ze standardową powłoką Bourne'a):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

Ten ciąg pobiera listę zdalnych gałęzi i przekazuje ją do egrepstandardowego wejścia. I filtruje gałęzie, które mają zdalną gałąź śledzenia (używając git branch -vvi filtrując dla tych, które mają origin), a następnie uzyskuje pierwszą kolumnę tego wyniku, która będzie nazwą gałęzi. Na koniec przekazujemy wszystkie nazwy gałęzi do polecenia usuwania gałęzi.

Ponieważ korzysta z tej -dopcji, nie usuwa gałęzi, które nie zostały scalone z gałęzią, w której się znajdujesz po uruchomieniu tego polecenia.

Pamiętaj również, że musisz git fetch --prune najpierw uruchomić , w przeciwnym razie git branch -rnadal będą widoczne zdalne gałęzie.

Schleis
źródło
12
To działało dla mnie idealnie. Jakoś git fetch -pnie zawsze wystarczy?
Stefan Hendriks
16
Niestety nie działa to w Git Bash w systemie Windows. sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required Jakieś pomysły?
Ludder,
37
Aby dodać go jako alias:alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
bryant1410,
125
Czy jest jakieś proponowane polecenie dla przyszłej wersji git, które to zrobi? To polecenie wygląda, jakby mój kot był na moim laptopie
Bron Davies,
5
użycie git branch -Dna końcu polecenia działało dla nas lepiej, ponieważ mamy tendencję do zgniatania zatwierdzeń podczas scalania, co powoduje The branch x is not fully mergedbłędy podczas uruchamiania -d.
Mateus Gondim
429

Jeśli chcesz usunąć wszystkie lokalne gałęzie, które są już połączone w master, możesz użyć następującego polecenia:

git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

Więcej informacji .

jackocnr
źródło
4
Myślę, że działało idealnie! Czy ktoś mógłby wyjaśnić, czy ta odpowiedź robi coś innego niż odpowiedź zaakceptowana?
Andrew,
11
Niewielka poprawa: użyj xargs -r git branch -d, aby nic nie było uruchamiane, jeśli nie ma gałęzi do usunięcia. Pamiętaj, że -rflaga może nie być dostępna wszędzie
Jacob Wang
8
Ponieważ grep może nie pasować z powodu kolorów git:git branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
Mike D
5
@NickRes widząc, o co tak ładnie prosiłeś, git branch --merged masterwyświetla listę gałęzi, które są scalone w master, następnie środkowa część grep wyklucza samego master (nie chcemy usuwać master!), A ostatnia część xargs wykonuje git branch -d(usuń gałąź) na każdym wyniki. Lub możesz po prostu przeczytać link Więcej informacji podany w odpowiedzi;)
jackocnr
14
Poprawa: git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d. Wyjście z git v2.10.1 wyświetli „* master”, gdy master jest wyewidencjonowany. Pozbywam się mistrza zarówno z gwiazdką, jak i bez niej.
Esteban
162

Wśród informacji przedstawionych przez git help fetch, jest ten mały przedmiot:

 -p, --prune
        After fetching, remove any remote-tracking branches which no longer exist on the remote.

Więc może git fetch -pjest to, czego szukasz?

EDYCJA: Ok, dla tych, którzy wciąż debatują nad odpowiedzią 3 lata po fakcie, oto trochę więcej informacji na temat tego, dlaczego przedstawiłem tę odpowiedź ...

Po pierwsze, OP mówi, że chcą „usunąć również te lokalne gałęzie, które zostały utworzone z tych zdalnych gałęzi [których już nie ma na zdalnym]”. Nie jest to jednoznacznie możliwe w git. Oto przykład.

Powiedzmy, że mam repozytorium na centralnym serwerze i ma on dwie gałęzie, zwane Ai B. Jeśli sklonuję to repozytorium do mojego lokalnego systemu, mój klon będzie miał lokalne odwołania (jeszcze nie rzeczywiste gałęzie) origin/Ai origin/B. Powiedzmy teraz, że wykonuję następujące czynności:

git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>

Istotne fakty tutaj są takie, że z jakiegoś powodu postanowiłem utworzyć oddział w moim lokalnym repozytorium, który ma inną nazwę niż jego pochodzenie, a także mam oddział lokalny, który (jeszcze) nie istnieje w repozytorium źródłowym.

Powiedzmy teraz, że usuwam zarówno gałęzie, jak Ai Bzdalne repozytorium i aktualizuję moje lokalne repozytorium ( git fetchjakiejś formy), co powoduje, że moje lokalne odwołania origin/Ai origin/Bznikają. Teraz mój lokalny repo ma trzy oddziały nadal, A, Z, i C. Żadne z nich nie ma odpowiedniej gałęzi na zdalnym repozytorium. Dwa z nich zostały „utworzone z… odległych gałęzi”, ale nawet jeśli wiem, że kiedyś istniała gałąź wywoływana Bna początku, nie mam sposobu, aby wiedzieć, że Zzostała utworzona zB, ponieważ został przemianowany w tym procesie, prawdopodobnie z ważnego powodu. Tak naprawdę, bez pewnych zewnętrznych metadanych pochodzenia procesu rejestrowania gałęzi lub człowieka znającego historię, nie można stwierdzić, która z trzech gałęzi, jeśli w ogóle, OP stara się usunąć. Bez pewnych informacji zewnętrznych, które gitnie są automatycznie utrzymywane dla ciebie, git fetch -pjest tak blisko, jak to tylko możliwe, a każda automatyczna metoda dosłownej próby tego, o co poprosił PO, ryzykuje albo usunięcie zbyt wielu gałęzi, albo pominięcie niektórych, które w przeciwnym razie PO chcesz usunąć.

Istnieją również inne scenariusze, na przykład gdy utworzę trzy oddzielne gałęzie, origin/Aaby przetestować trzy różne podejścia do czegoś, a następnie origin/Aznikną. Teraz mam trzy gałęzie, które oczywiście nie wszystkie pasują do nazwy, ale zostały utworzone origin/A, więc dosłowna interpretacja pytania PO wymagałaby usunięcia wszystkich trzech. Może to jednak nie być pożądane, jeśli możesz nawet znaleźć niezawodny sposób na ich dopasowanie ...

twalberg
źródło
107
Nie usuwa to lokalnych oddziałów, a jedynie zdalne wskaźniki do oddziałów
Jaap
4
Usuwa tylko te lokalne oddziały, które nie istnieją zdalnie ORAZ nigdy ich nie kasowałeś.
Jarek Jakubowski
15
Powinieneś przeczytać pytanie uważniej, jak zauważa Jaap. Osoby głosujące na tę odpowiedź powinny również przeczytać, na czym naprawdę polega pytanie.
Søren Boisen,
4
Tak, to było dokładnie to, co chciałem zrobić! @ SørenBoisen Mam nadzieję, że w ciągu ostatnich dwóch lat miałeś czas na ponowne przejrzenie swojej opinii ... Jeśli treści zamieszczone na SO powinny zawsze odnosić się tylko do tego, o co czasami mylą OP, poprosilibyśmy o usunięcie wielu informacji. Nie zakładaj, że instruujesz ludzi, jak mogą korzystać z tej witryny, poza oficjalnymi wytycznymi, i wyraźnie nie zapobiegają prostym, ale użytecznym odpowiedziom.
Félix Gagnon-Grenier
6
@ FélixGagnon-Grenier Oto mój problem z tą odpowiedzią: 1) Pytanie jest krystalicznie czyste, OP nie jest wyraźnie pomylone. 2) Ta odpowiedź nie wspomina, że ​​nie odpowiada na pytanie! 3) Pytanie określa już sposób przycinania gałęzi zdalnego śledzenia, które już nie istnieją, więc dodaje wartość zerową.
Søren Boisen
117

Spowoduje to usunięcie oddziałów lokalnych, dla których gałęzie zdalnego śledzenia zostały przycięte. (Upewnij się, że jesteś na masteroddziale!)

git checkout master
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

Detale:

  • git branch -vv wyświetla „zniknął” dla lokalnych oddziałów, że pilot został przycięty.

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -dsprawdzi, czy został scalony ( -Dniezależnie od tego usunie)

    error: The branch 'mybranch' is not fully merged.
    
wisbucky
źródło
15
Możesz nawet skrócić komendę za pomocągit branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
chiborg
4
Po prostu wskazując, że powinieneś być mistrzem, zanim to zrobisz, ponieważ git branch -dporównuje gałęzie HEAD.
Steve Bennett
Świetny! Szukałem i szukałem tego. Chciałbym poznać twoją odpowiedź, zanim sami ją rozgryzłem. Oszczędziłoby mi to kilka minut. Oto moja inna odpowiedź: stackoverflow.com/questions/15661853/...
Karl Wilbur
1
Skończyło się na podobnym aliasie git, używanym do cięcia, ponieważ awk nie działał z jakiegoś powodu:prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
Zitrax
3
O, stary ... mam szczęście, że POTRZEBUJESZ zaktualizować swoją odpowiedź, aby powiedzieć ludziom, że powinni być mistrzem. Właśnie to zrobiłem z innej gałęzi. @ stevebennet2 dzięki za pouczający komentarz
GrayedFox
53

Można skonfigurować Git, aby automatycznie pobierał odwołania do usuniętych zdalnych gałęzi podczas pobierania:

git config --global fetch.prune true

Podczas dzwonienia git fetchlub git pullpóźniej odniesienia do usuniętych zdalnych gałęzi są automatycznie usuwane.

wedesoft
źródło
5
to nie usuwa lokalnych oddziałów, tylko odniesienia do nich, prawda?
Clint Eastwood
@ClintEastwood Usuwa tylko odniesienia do zdalnych gałęzi. Możesz wyświetlić listę referencji do zdalnych oddziałów za pomocą git branch -r.
wedesoft,
52

Jest fajny pakiet NPM, który robi to za Ciebie (i powinien działać na różnych platformach).

Zainstaluj z: npm install -g git-removed-branches

A następnie git removed-branchespokaże wszystkie przestarzałe lokalne oddziały i git removed-branches --prunefaktycznie je usunie.

Więcej informacji tutaj.

tzachs
źródło
1
To naprawdę powinno mieć więcej pozytywnych opinii. Dzięki za ułatwienie życia, niezależnie od platformy.
Szyfrowanie
Przydatne małe rozszerzenie. Zainstalowany i działał poprawnie w systemie Windows 10. Mała uwaga: traktuje niepołączone gałęzie jako możliwe do przycinania (błąd podczas uruchamiania --prune, chociaż wywołano odgałęzienie -d) .. nie są one jednak oznaczone jako takie na początku pokazana lista.
user2864740
1
To moja ulubiona odpowiedź. npx git-removed-branchesdziała jak sen.
Drazisil
tak! To powinno mieć więcej pozytywnych opinii! tak proste i intuicyjne rozwiązanie dla początkujących cli
geoseong
Przydałby się przegląd tego, co robi narzędzie z punktu widzenia git.
ryanwebjackson
41

Rozwiązanie Windows

W przypadku programu Microsoft Windows Powershell:

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

Wyjaśnienie

git checkout master przechodzi do gałęzi master

git remote update origin --prune przycina odległe gałęzie

git branch -vvpobiera pełne wyjście wszystkich gałęzi ( referencja git )

Select-String -Pattern ": gone]" pobiera tylko te rekordy, w których zostały usunięte ze zdalnego.

% { $_.toString().Split(" ")[0]} uzyskać nazwę oddziału

% {git branch -d $_} usuwa gałąź

chris31389
źródło
Niezły przykład. alternatywnie użyj git remote prune origin, również select-string wydaje się nie pasować do najnowszej wersji git. Rozważ użycieConvertFrom-String -TemplateContent
Bernie White
3
Wygląda na to, że najnowsza wersja git dodaje spacje końcowe, więc Split nie działa, aby uzyskać nazwę gałęzi. Wykonaj .toString (). Trim (). Split („”) i będzie
Chris Hynes
Oto moje:git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Omzig
@Omzig Co to robi inaczej? Czy możesz podać wyjaśnienie>
chris31389
@ chris31389, mam tam dostęp, aby uzyskać wszystko, czego brakuje mi w master, i zmieniłem gałąź na - scalone, a nie master, chcę się upewnić, że usunę tylko połączone gałęzie. To sprawia, że ​​czuję się lepiej;)
Omzig
27

Wyświetli listę lokalnych oddziałów, których gałąź zdalnego śledzenia została usunięta ze zdalnego

$ git remote prune origin --dry-run

Jeśli chcesz usunąć odniesienia do tych lokalnych oddziałów z lokalnych, które nie są śledzone

$ git remote prune origin
027
źródło
19
To nie odpowiada na pytanie, oto co OP już wiedział.
Ken Williams
2
Zgadzam się również, ale kiedy wyszukujesz „Jak przycinać lokalne gałęzie śledzenia, które już nie istnieją na odległość”, jest to górny link i ta odpowiedź jest zgodna z tytułem (nie, jeśli przeczytałeś pełny opis tego pytania), że jest powodem do większego głosowania :)
027
To nie usuwa lokalnych oddziałów. Nadal tam po uruchomieniu
Xin
@ X Spróbuj uruchomić komendę bez argumentu --dry-run, ponieważ tak naprawdę nie wykona polecenia, ale pokaże, co zmieni.
Torsten Ojaperv
19

Jak zauważa @tzacks ... istnieje przydatny do tego pakiet npm. Po prostu zrób:

npx git-removed-branches --prune

(Skomentowałbym, ale za mało reputacji)

johnshew
źródło
1
Wspaniały. Bez kłopotów. Cieszę się, że to była pełna odpowiedź!
Dan Rayson
1
To powinno być na górze. Działa również w systemie Windows.
tomtastico,
14

Jeśli używasz Windows i PowerShell, możesz użyć następujących poleceń, aby usunąć wszystkie lokalne oddziały, które zostały scalone z oddziałem aktualnie wyewidencjonowanym:

git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}

Wyjaśnienie

  • Wyświetla bieżącą gałąź i gałęzie, które zostały z nią połączone
  • Filtruje bieżącą gałąź
  • Czyści wszelkie początkowe lub końcowe spacje z danych gitwyjściowych dla każdej pozostałej nazwy gałęzi
  • Usuwa scalone lokalne oddziały

Warto git branch --mergednajpierw uruchomić sam, aby upewnić się, że usunie tylko to, czego się spodziewasz.

(Przeniesiony / zautomatyzowany z http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/ .)

Komar
źródło
10

Jeszcze krótszy i bezpieczniejszy jednowarstwowy:

git branch -d $(git branch --merged | cut -c 3- | grep -v master)

Pamiętaj, aby przejść do kasy, która nie została jeszcze scalona, ​​zanim ją uruchomisz. Ponieważ nie możesz usunąć oddziału, w którym jesteś aktualnie zalogowany.

FelikZ
źródło
3
czy to również usunie twojego „mistrza”?
dcsan
2
Jeśli obecnie zameldowałeś się na master, to nie, w przeciwnym razie tak
FelikZ
1
Aby pominąć mistrza, możesz po prostu git branch -d $(git branch --merged | cut -c 3- | grep -v master)
potokować,
Jest to niebezpieczne i ktoś w przyszłości nieświadomie usunie swoją główną gałąź
jasonseminara,
1
@jasonseminara #dcsan Zaktualizowałem fragment kodu, więc pomija gałąź master. #mozillalives dzięki
FelikZ
9

Chciałem czegoś, co wyczyści wszystkie lokalne gałęzie, które śledziły gałąź zdalną, w originktórej usunięto gałąź zdalną ( gone). Nie chciałem usuwać lokalnych gałęzi, które nigdy nie zostały skonfigurowane do śledzenia gałęzi zdalnej (tj. Moich lokalnych gałęzi programistów). Chciałem też mieć prostą liniówkę, która po prostu używa gitlub inne proste narzędzia CLI, zamiast pisać własne skrypty. Skończyłem używać trochę grepi, awkaby wykonać to proste polecenie, a następnie dodałem je jako alias w moim ~/.gitconfig.

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

Oto git config --global ...polecenie umożliwiające łatwe dodanie tego jako git prune-branches:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

UWAGA: Użycie -Dflagi git branchmoże być bardzo niebezpieczne. Tak więc w powyższym poleceniu config używam -dopcji git branchzamiast -D; Używam -Dw mojej aktualnej konfiguracji. Używam, -Dponieważ nie chcę słyszeć, jak Git narzeka na nieuporządkowane gałęzie, chcę tylko, żeby odeszły. Możesz także chcieć tę funkcjonalność. Jeśli tak, po prostu użyj -Dzamiast -dna końcu tego polecenia config.

Karl Wilbur
źródło
8

Aby usunąć zdalne gałęzie:

$git remote prune origin

Aby usunąć lokalne oddziały, które są już scalone:

$git branch -D $(git branch --merged)
Aniket
źródło
Pracuje dla mnie. Dzięki.
AndroidRuntimeException
2
(git branch --merged) zwraca mi również „master”. I inne gałęzie, które nie zostały usunięte na pilocie.
Tom G
8
To usunęło moją główną gałąź.
Greg
5

Wydaje się, że nie ma bezpiecznej jednowierszowej, zbyt wielu przypadków na krawędziach (jak gałąź posiadająca „master” jako część swojej nazwy itp.). Najbezpieczniejsze są następujące kroki:

  1. git branch -vv | grep 'gone]' > stale_branches.txt
  2. wyświetl plik i usuń wiersze dla gałęzi, które chcesz zachować (takich jak gałąź główna!); nie musisz edytować zawartości żadnego wiersza
  3. awk '{print $1}' stale_branches.txt | xargs git branch -d
Oliver
źródło
5

W oparciu o powyższe odpowiedzi używam tej krótszej linijki:

git remote prune origin | awk 'BEGIN{FS="origin/"};/pruned/{print $2}' | xargs -r git branch -d

Ponadto, jeśli już przycinałeś i masz lokalne zwisające gałęzie, to wyczyści je:

git branch -vv | awk '/^ .*gone/{print $1}' | xargs -r git branch -d
hidralisk
źródło
1
Nie działa, jeśli nazwy oddziałów mają /w nich
theicfire
4

Nie jestem pewien, jak to zrobić od razu, ale git git branch -d <branchname>usunie lokalny oddział TYLKO, jeśli zostanie całkowicie scalony. Zwróć uwagę na małe litery d.

git branch -D <branchname> (zwróć uwagę na wielką literę D) usunie lokalny oddział niezależnie od jego statusu scalenia.

NHDaly
źródło
W systemie Windows inne odpowiedzi nie działały dla mnie. Użycie tej odpowiedzi z prostym przełącznikiem -D tak (chociaż gałąź została już „usunięta”).
Czy możemy to zrobić dla wszystkich oddziałów jednocześnie?
Teoman shipahi
3

Możesz użyć tego polecenia:

git branch --merged master | grep -v "\* master" | xargs -n 1 git branch -d

Git Clean: usuwanie już połączonych gałęzi, w tym podział poleceń

sendon1982
źródło
Naprawdę nie musisz odfiltrowywać żadnych gałęzi (ex master). Jeśli jest „scalony”, oznacza to po prostu, że usunie twoją lokalną kopię, ale „git checkout dev” utworzy lokalny oddział ze zdalnego, jeśli jeszcze nie jest obecny
csga5000 24.09.2018
Ale lista lokalnych oddziałów nadal istnieje, nawet jeśli są scalone. To polecenie służy do usunięcia tych gałęzi, które zostały usunięte ze zdalnego.
sendon1982,
gwiazdka na początku oznacza bieżącą gałąź, gdy uruchomisz tę komendę w innej gałęzi, nie będzie
działać
2

Na podstawie powyższych odpowiedzi przyszedłem z tym rozwiązaniem jednoliniowym:

git remote prune origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
gagarwal
źródło
2

Korzystając z wariantu w odpowiedzi @ wisbucky, dodałem do mojego ~/.gitconfigpliku alias :

pruneitgood = "!f() { \
    git remote prune origin; \
    git branch -vv | perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \
}; f"

Dzięki temu prosty git pruneitgoodwyczyści zarówno lokalne, jak i zdalne oddziały, które nie są już potrzebne po scaleniu.

Ken Williams
źródło
2

Wersja Powershell git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}

Spowoduje to usunięcie wszystkich lokalnych oddziałów, które zostały połączone w master, gdy jesteś w gałęzi master .

git checkout master przełączyć.

Kevin George
źródło
1

Wariant Schleisa nie działa dla mnie (Ubuntu 12.04), więc proponuję moje (jasne i błyszczące :) warianty:

Wariant 1 (wolałbym tę opcję):

git for-each-ref --format='%(refname:short) %(upstream)' refs/heads/ | awk '$2 !~/^refs\/remotes/' | xargs git branch -D 

Wariant 2:

za. Próba:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}'

b. Usuń gałęzie:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D
daniilyar
źródło
1

Poniżej znajduje się adaptacja odpowiedzi @ wisbucky dla użytkowników systemu Windows:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

Używam posh-git i niestety PS nie lubi nagich for, więc stworzyłem prosty skrypt poleceń o nazwie PruneOrphanBranches.cmd:

@ECHO OFF
for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1

GOTO :EOF

:ProcessBranch
IF /I "%2%"=="-d" (
    git branch %1 %2
) ELSE (
    CALL :OutputMessage %1
)
GOTO :EOF

:OutputMessage
ECHO Will delete branch [%1] 
GOTO :EOF

:EOF

Wywołaj go bez parametrów, aby wyświetlić listę, a następnie wywołaj go za pomocą „-d”, aby wykonać faktyczne usunięcie lub „-D” dla wszystkich gałęzi, które nie są w pełni scalone, ale i tak chcesz je usunąć.

Sam C.
źródło
To nie działało dla mnie, w jakiś sposób :lub : (ze spacją) findstrpowodowało, że za każdym razem wszystko pasowało - prawie usunąłem master. Jednak użycie wyrażenia regularnego działało dobrze:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
Josh
1

Wypróbuj to w git bash, aby pobrać i przyciąć odniesienia do usuniętych gałęzi, a następnie przyciąć lokalne gałęzie, które śledziły usunięte:

git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs`

Pamiętaj, aby najpierw pobrać gałąź, która nie zostanie usunięta, aby nie blokowała usuwania gałęzi.

Guillermo Gutiérrez
źródło
0

Przekształciłem przyjętą odpowiedź w solidny skrypt. Znajdziesz go w moim repozytorium rozszerzeń git .

$ git-prune --help
Remove old local branches that do not exist in <remote> any more.
With --test, only print which local branches would be deleted.
Usage: git-prune [-t|--test|-f|--force] <remote>
Ingo Karkat
źródło
0

Dotarłem do tej strony, szukając odpowiedzi „jak usunąć lokalnie wypisane gałęzie, które nie mają już gałęzi upstream”

Nie obchodziło mnie również, czy lokalny oddział został jeszcze włączony, ponieważ przesyłanie do niego git branch -dpo prostu ostrzega zamiast usuwać nie połączone lokalne oddziały.

git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3 | egrep -v -f /dev/fd/0 <(git branch -a | grep -v origin) | grep branch_prefix_that_I_care_about | xargs git branch -d

# translation
# git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3
## this finds all remote branch names minus the "remote/origin/" part
#
# <(git branch -a | grep -v origin)
## this finds all local branch names and redirects it into the previous command
#
# egrep -v -f /dev/fd/0 STUFF
## this is doing some weird magic that I'm grokking as "take the set difference from whatever was piped in"
#
#
# overall translation: (STUFF TO CONSIDER) | egrep magic <(STUFF TO REMOVE FROM CONSIDERATION) | do cool things with resulting stuff
Meredith
źródło
0

W PowerShell :

git branch -D (git branch --merged |% { $_.trim() } )
Raúl Salinas-Monteagudo
źródło
0

Oto moje rozwiązanie:

git fetch -p
git branch -vv | grep ": gone" | awk '{print $1}' | xargs git branch -d
  • -p oznacza usunięcie wszelkich odniesień do zdalnego śledzenia, które już nie istnieją na pilocie. Więc pierwszy krok usunie odniesienia do zdalnych gałęzi.

  • -vv służy do pokazania sha1 i zatwierdzenia wiersza tematu dla każdej głowy, wraz z powiązaniem z odgałęzieniem (jeśli występuje). Drugi krok spowoduje pobranie wszystkich lokalnych gałęzi, a polecenie grep odfiltruje gałęzie, które zostały usunięte.

Neeraj Bansal
źródło
-2

Usuń każdą gałąź, która nie jest aktualna w Master

git co master && git branch | sed s/\*/\ / | xargs git branch -d 2> /dev/null
Jason Waldrip
źródło
-3

Jestem pewien, że git remote prune origintego właśnie chcesz.

Możesz uruchomić go, git remote prune origin --dry-runaby zobaczyć, co by zrobił bez wprowadzania jakichkolwiek zmian.

Jason Antman
źródło
12
To tak naprawdę nie usuwa samego oddziału lokalnego.
Taytay
-17

Korzystasz z GUI? Procedura ręczna, ale szybka i łatwa.

$ git gui

Wybierz „Oddział -> Usuń”. Możesz wybrać wiele gałęzi za pomocą kliknięcia klawiszem Ctrl (Windows) i usunąć je wszystkie.

Pedro Ballesteros
źródło
To zabawne, jak negatywna jest ta odpowiedź. Całkowicie poprawne podejście IMO, jeśli lubisz GUI.
serraosays