Czy możesz usunąć wiele gałęzi za pomocą jednego polecenia za pomocą Git?

355

Chciałbym, aby oczyścić moje lokalne repozytorium, które ma mnóstwo starych gałęzi, na przykład: 3.2, 3.2.1, 3.2.2, itd

Miałem nadzieję na sprytny sposób na usunięcie wielu z nich na raz. Ponieważ w większości są zgodne z konwencją uwalniania kropek, pomyślałem, że może istnieć skrót do powiedzenia:

git branch -D 3.2.*

i zabij wszystkie gałęzie 3.2.x.

Wypróbowałem to polecenie i oczywiście nie zadziałało.

Doug
źródło
11
git branch -D $(git branch | grep 3.2*)- to zadziałało dla mnie. Usuwa gałęzie, których nazwa zaczyna się od „3.2”. grep- dopasowanie wzorca na wyjściu ( git branchw tym przypadku). $()- oznacza wykonać i umieścić wynik. |- łańcuchy.
Eduard,
4
Warto zwrócić uwagę na te, które nie wiedzą, że -Dto siła kasowania, należy użyć -dw większości przypadków będzie bezpieczniej pierwszy.
redfox05

Odpowiedzi:

363

Nie z tą składnią. Ale możesz to zrobić w następujący sposób:

git branch -D 3.2 3.2.1 3.2.2

Zasadniczo, gałąź git usunie dla ciebie wiele gałęzi za pomocą jednego wywołania. Niestety nie wykonuje uzupełniania nazw gałęzi. Chociaż w bash możesz zrobić:

git branch -D `git branch | grep -E '^3\.2\..*'`
Slebetman
źródło
2
Ukończenie git branch -D/-ddziała dobrze dla mnie. Może chcesz zaktualizować swój (być może z najnowszego katalogu contit git.git).
Cascabel,
19
Zamiast git branch | ...ciebie możesz użyć $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). Wiem, że jest dłuższy, ale z pewnością jest odpowiedni, ale git branchma całkiem niezłe wyjście z rzeczami takimi jak *i ->(dla symrefs), które mogą zepsuć cię w skryptach / liniach.
Cascabel,
3
Może jestem jedynym, który ma ten problem, ale grepaliasy zawsze zawierały flagę --color=always- git branch -Drzucałem, error: branch 'my_branch' not found.dopóki nie uciekłem bez kolorowej flagi.
eebbesen
@eebbesen Czy wyłączyłeś to globalnie? git branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
Napotkałem
2
Dzięki rozszerzeniu nawiasów klamrowych możesz napisać, git branch -D 3.2{,.1,.2}aby usunąć wszystkie trzy gałęzie gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck
147

W najgorszym przypadku możesz użyć:

git branch | grep '3\.2' | xargs git branch -d
Carl Norum
źródło
22
Jest to w zasadzie idealna metoda dla każdego, kto używa standardowych nazw prefiksów dla nazw oddziałów (np. „Fix / ...” lub „feature / ...”).
Haz
4
Prosty i wydajny! Polecam jednak uruchomienie najpierw bez | xargs git branch -dczęści, aby sprawdzić, co faktycznie zostanie usunięte.
mathielo,
Zaleca się, aby nie grepwyświetlać git branch, ponieważ ma to na celu czytanie, a nie parsowanie. Można zmienić w dowolnym momencie. użyj for-each-refrazem z parametrami --format, jak sugerowano w innych odpowiedziach, a następnie połącz z sugestiami w tej odpowiedzi.
redfox05
138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

EDYTOWAĆ:

Bezpieczniejsza wersja (sugerowana przez Jakuba Narębskiego i Jefromiego), ponieważ wyjście gałęzi git nie jest przeznaczone do użycia w skryptach:

git for-each-ref --format="%(refname:short)" refs/heads/3.2\* | xargs git branch -D

... lub xargs-free:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`
Gawi
źródło
14
Nie używaj git branchdanych wyjściowych do tworzenia skryptów. Zastosowanie git for-each-ref.
Jakub Narębski
1
Aby usunąć tagi z symbolem @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt
Ma literówkę. Powinien być „/3.2/*”, a nie „/3.2*”. Wygląda również na to, że skopiowałeś inne odpowiedzi do swoich.
Max MacLeod
Tutaj nie ma literówki. Ze strony If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
podręcznika
1
Warto zwrócić uwagę na te, które nie wiedzą, że -Dto siła kasowania, należy użyć -dw większości przypadków będzie bezpieczniej pierwszy.
redfox05
115

Możesz użyć git branch --list, aby wyświetlić listę kwalifikujących się gałęzi, a git branch -D / -d, aby usunąć kwalifikujące się gałęzie.

Przykład jednego liniowca:

git branch -d `git branch --list '3.2.*'`
50shadesofbae
źródło
Gdy próbuję tego, otrzymuję wiele komunikatów o błędach, takich jak error: branch 'package.json' not found.. Wygląda na to, że * jest rozwijany zbyt wcześnie i próbuje usunąć gałąź odpowiadającą nazwie każdego pliku i katalogu.
Antymon
To działa dobrze! Mam problem z używaniem tego jako aliasu z gitconfig...
kimś z
6
Ta odpowiedź musi być wyżej na liście, super czysta, działa, bez grep
jemiloii
1
Fajnie, że ten jest łatwy do przetestowania w pierwszej kolejności, po prostu wydającgit branch --list '3.2.*'
Will
3
W git branch -d (git branch --list '3.2.*').trim()
systemie
38

Ostatnio szukałem rozwiązania tego samego problemu, w końcu znalazłem jedną odpowiedź i działa ona bardzo dobrze:

  1. Otwórz terminal lub odpowiednik.
  2. Wpisz gałąź git | grep „wzorzec” dla podglądu gałęzi, które zostaną usunięte.
  3. Wpisz gałąź git | grep „wzór” | xargs git branch -D

To rozwiązanie jest niesamowite, a jeśli chcesz uzyskać pełne wyjaśnienie każdego polecenia i sposobu jego działania, podaj je tutaj .

KJ Gor
źródło
28

Posługiwać się

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Jakub Narębski
źródło
7
mała wskazówka jest taka, że ​​jeśli usuniesz ostatnią część polecenia „| xargs git branch -D”, to po prostu wyświetli pasujące gałęzie. Możesz więc wyświetlić podgląd gałęzi, które zostaną usunięte
Max MacLeod
1
Dodałem także alias, aby to uprościć: alias grefs='git for-each-ref --format="%(refname:short)"'dzięki czemu mogę zrobićgrefs | grep 'regexpattern' | xargs git branch -D
angularsen
Pokochałem to. Ładnie i prosto!
Bhargav Ponnapalli
15

Może przyda ci się to:

Jeśli chcesz usunąć wszystkie gałęzie, które nie są na przykład „master”, „foo” i „bar”

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v 'coś' jest dopasowaniem z inwersją.

Adi
źródło
Osobiście podoba mi się -Dopcja w porównaniu do innej odpowiedzi. Dzięki za odpowiedź tutaj @Adi. Rozwiązania dla mnie działają.
AMIC MING
9

Umieszczam moje inicjały i myślnik (at-) jako pierwsze trzy znaki nazwy oddziału z tego właśnie powodu:

git branch -D `git branch --list 'at-*'`
Alan Tweedie
źródło
Wszystkie odpowiedzi w zasadzie to mówią, tak się składa, że ​​jest to najprostsze.
tfantina,
7

Jeśli nie jesteś ograniczony do używania wiersza polecenia git, zawsze możesz uruchomić git guii użyć pozycji menu Oddział-> Usuń. Wybierz wszystkie gałęzie, które chcesz usunąć i pozwól mu zgrać.

Efpofis
źródło
pozwala to jednak usunąć tylko lokalne oddziały
Stealth Rabbi
7

Rozwiązanie PowerShell:

Jeśli korzystasz z systemu Windows, możesz użyć programu PowerShell, aby usunąć wiele gałęzi jednocześnie ...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

Możesz także dostroić sposób, w jaki powinno działać dopasowywanie wzorców za pomocą polecenia Select-String programu Powershell. Spójrz na dokumenty PowerShell .

Imtiaz Shakil Siddique
źródło
6

Kontynuuj „rozwijaj” i usuwaj wszystkie inne w lokalnym

    git branch | grep -v "develop" | xargs git branch -D 
Daniel
źródło
5

Zrobiłem małą funkcję, która może być użyteczna na podstawie odpowiedzi udzielonej przez @gawi (powyżej).

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}

Dodaj to do swojego .bash_profilei uruchom ponownie terminal. Następnie możesz zadzwonić z wiersza polecenia w następujący sposób:

removeBranchesWithPrefix somePrefix

Uwaga

Mam go obecnie skonfigurowanego do miękkiego usuwania, co oznacza, że ​​nie usunie gałęzi, chyba że zostały już scalone. Jeśli chcesz mieszkać na krawędzi, zmień -dna -Di usunie wszystko z prefiksem niezależnie!

Logan
źródło
5

Jeśli naprawdę potrzebujesz wyczyścić wszystkie swoje gałęzie, spróbuj

git branch -d $(git branch)

Spowoduje to usunięcie wszystkich lokalnych połączonych oddziałów z wyjątkiem tego, w którym aktualnie się logujesz.

To dobry sposób na utrzymanie lokalnych czystości

Yulin
źródło
To mi wystarczało. Pozostawił dwie gałęzie oprócz tej, którą byłem, którą następnie usunąłem za pomocą tego samego polecenia, ale używając dużej litery „-D” zamiast „-d”. Otrzymałem kilka błędów związanych z tym, że git nie znalazł plików, ale gałęzie zostały usunięte.
Lurifaxel,
3

Może ci się spodobać ten mały element ... Pobiera listę i prosi o potwierdzenie każdego elementu przed ostatecznym usunięciem wszystkich zaznaczeń ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

Użyj -D, aby wymusić usunięcie (jak zwykle).

Dla czytelności, oto ten podzielony wiersz po wierszu ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

oto podejście xargs ...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

wreszcie lubię mieć to w moim .bashrc

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

W ten sposób mogę po prostu powiedzieć

gitSelect | xargs git branch -D.
Rzemieślnik Chaosu
źródło
3

Dla czystych dusz, które używają PowerShell tutaj mały skrypt git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })

codevision
źródło
2

działa dla mnie poprawnie:

git branch | xargs git branch -d

git branch | xargs git branch -D

usuń wszystkie lokalne oddziały

velastiqui
źródło
2

Użyj następującego polecenia, aby usunąć wszystkie gałęzie (gałąź wyewidencjonowana nie zostanie usunięta).

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

Edycja: używam Mac OS

ILYAS_Kerbal
źródło
0

Jeśli korzystasz z systemu Windows, możesz to zrobić za pomocą programu PowerShell:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

zastąp feature/*dowolny wzór.

Mo Valipour
źródło
6
grep jest dla mnie nieznanym poleceniem cmdlet ... więc zmieniłem dla tej gałęzi git gdzie {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} i działał!
Alex
0

Możesz użyć git guido usunięcia wielu oddziałów jednocześnie. W wierszu polecenia / Bash -> git gui-> Zdalny -> Usuń gałąź ... -> wybierz zdalne gałęzie, które chcesz usunąć -> Usuń.

Terry Truong
źródło
0

Właśnie dzisiaj wyczyściłem duży zestaw przestarzałych oddziałów lokalnych / zdalnych.

Oto jak to zrobiłem:

1. wypisz wszystkie nazwy gałęzi do pliku tekstowego:

git oddział -a >> BranchNames.txt

2. dołącz gałęzie, które chcę usunąć, do polecenia „git branch -D -r”:

git branch -D -r origin / dirA / branch01 origin / dirB / branch02 origin / dirC / branch03 (... dołącz dowolne nazwy gałęzi)

3. uruchom cmd

A ten działa o wiele szybciej i bardziej niezawodnie niż „ git push origin - usuń” ”.

To może nie być najmądrzejszy sposób wymieniony w innych odpowiedziach, ale ten jest dość prosty i łatwy w użyciu.

RainCast
źródło
0

Jeśli masz zainstalowany Git GUI, który jest domyślnym dodatkiem do systemu Windows, to jest najprostszy. Możesz użyć ctrl, aby wybrać wiele gałęzi i usunąć je jednym kliknięciem.

peiz
źródło
0

Jeśli używasz powłoki rybnej, możesz wykorzystać stringfunkcje :

git branch -d (git branch -l "<your pattern>" | string trim)

To niewiele różni się od opcji PowerShell w niektórych innych odpowiedziach.

mdiin
źródło
0

Jeśli miałeś wszystkie gałęzie do usunięcia w pliku tekstowym (oddziały do ​​del.txt) (jedna gałąź na linię), możesz to zrobić, aby usunąć wszystkie takie gałęzie ze zdalnego (pochodzenie): xargs -a branches-to-del.txt git push --delete origin

code4kix
źródło
-1

Ponieważ w Git wszystkie gałęzie są niczym przez odniesienia do repozytorium git, dlaczego po prostu nie usuniesz gałęzi, które je przechodzą, .git/refa jeśli coś zostanie pominięte, co nie jest interesujące w repozytorium, zostanie automatycznie usunięte, więc nie trzeba zawracać sobie głowę.

Debajit
źródło
-3

git branch -D <branchName>

Aakash Pahuja
źródło
-4

Możesz usunąć wszystkie gałęzie, usuwając wszystkie niepotrzebne odwołania:

rm .git/refs/heads/3.2.*

Artur Owczarek
źródło
2
Przesłuchanie z dwóch powodów: 1. wykorzystuje szczegół implementacji (fakt, że obecne wersje Git przechowują gałęzie jako pliki w określonym katalogu). Może to ulec zmianie w przyszłych wersjach, powodując, że odpowiedź będzie nieprawidłowa. 2. Nie działa, jeśli repozytorium znajduje się w osobnym katalogu .
axiac
Daje to również bardzo nieoczekiwane wyniki, jeśli uruchomisz to w spakowanym repozytorium ( git gc). Nie rób tego
Matthieu Moy,