Czy mogę usunąć wszystkie lokalne oddziały poza obecnym?

98

Chcę usunąć wszystkie gałęzie, które są wyświetlane w danych wyjściowych ...

$ git branch

... ale zachowując aktualną gałąź w jednym kroku . Czy to jest możliwe? Jeśli tak to jak?

sensorario
źródło

Odpowiedzi:

67

Na podstawie odpowiedzi @pankijs utworzyłem dwa aliasy git:

[alias]
    # Delete all local branches but master and the current one, only if they are fully merged with master.
    br-delete-useless = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -d;\
    }; f"
    # Delete all local branches but master and the current one.
    br-delete-useless-force = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -D;\
    }; f"

Do dodania ~/.gitconfig


I jak zauważył @torek:

Zwróć uwagę, że małe litery -dnie usuwają „nie w pełni scalonej” gałęzi (zobacz dokumentację). Użycie -D usunie takie gałęzie , nawet jeśli spowoduje to "zgubienie" zatwierdzeń; używaj tego z wielką ostrożnością , ponieważ powoduje to również usunięcie reflogów gałęzi, tak że zwykłe "odzyskiwanie po przypadkowym usunięciu" również nie działa.

Zasadniczo nigdy nie używaj -forcewersji, jeśli nie masz 300% pewności, że nie stracisz nic ważnego. Ponieważ jest stracony na zawsze .

Vadorequest
źródło
2
zatwierdzenia do usuniętej gałęzi powinny jeszcze przez jakiś czas znajdować się w reflogu.
CaptRespect
Rzeczywiście, zatwierdzenia pozostałyby w reflogu. Ale nie sama gałąź. Nie próbowałbym tego, ale myślę, że możesz znaleźć swoje zatwierdzenia, ale wróć do stanu gałęzi? Wątpię w to. Cherry-pick może być użyty do odzyskania zatwierdzeń w usuniętej gałęzi, ale nie będziesz w stanie przywrócić samej gałęzi.
Vadorequest
1
@Vadorequest możesz odtworzyć gałąź wskazującą pewne zatwierdzenie, wykonującgit branch branchname commitid
pqnet
@pqnet Nie wiedziałem, że odtworzy całą historię dla tej gałęzi, dzięki, dobrze wiedzieć!
Vadorequest
1
@Vadorequest, ponieważ obiekty zatwierdzone są niezmienne (i indeksowane jako skróty), każda edycja wymaga utworzenia nowego obiektu (z innym
hashem
188
$ git branch | grep -v "master" | xargs git branch -D 

usunie wszystkie gałęzie z wyjątkiem master (zamień master na gałąź, którą chcesz zachować, ale wtedy usunie master)

pankijs
źródło
31
Jeśli chcesz zachować bieżącą gałąź, użyj grep -v ^*.
Schwern
2
Wiele źródeł pokazuje mi ten skrypt, ale kiedy go uruchamiam, zawsze mi mówi, że nie znaleziono gałęzi :(
tucq88
1
to nie jest dokładne, nie usunie gałęzi o nazwie master-copy, na przykład
mvallebr
2
W razie potrzeby popraw wyrażenie regularne, na przykładgrep -v "^ *master$"
Brad Koch
9
Jeśli chcesz zachować dwie gałęzie, użyj grep -v "master\|my-other-branch".
Derek Soike,
22

najpierw (przełącz się na gałąź, którą chcesz zachować> ex : master ):

git checkout master

po drugie (upewnij się, że jesteś na master )

git branch -D $(git branch)
KhogaEslam
źródło
3
bardzo szybko i łatwo. Dlaczego to się nie cieszy?
princebillyGK
1
To dla mnie najprostsza i najlepsza odpowiedź.
Saleh Enam Shohag
3
Jeśli używasz programu PowerShell, użyj git branch -D $(git branch).Trim().
NatoBoram
1
@NatoBoram dzięki, działa idealnie!
StratMN
czy mamy $(git branch)cytować? To nie działa: błąd: nie znaleziono gałęzi „$ (git”. Error: branch „branch)”.
saran3h
13

git branch -d (lub -D ) zezwala na wiele nazw gałęzi, ale jest trochę trudne, aby automatycznie podawać „wszystkie lokalne gałęzie z wyjątkiem tego, na którym jestem teraz” bez pisania co najmniej odrobiny kodu.

„Najlepszą” (formalnie poprawną) metodą jest użycie git for-each-refdo uzyskania nazw gałęzi:

git for-each-ref --format '%(refname:short)' refs/heads

ale wtedy jeszcze trudniej jest ustalić, w której gałęzi się znajdujesz (git symbolic-ref HEAD znajdujesz jest to "formalnie poprawna" metoda do tego, jeśli chcesz napisać fantazyjny skrypt).

Wygodniej możesz użyć git branch, który wypisuje nazwy lokalnych oddziałów poprzedzone dwiema spacjami lub (w przypadku bieżącej gałęzi) gwiazdką *. Więc przeprowadź to przez coś, aby usunąć *wersję, a otrzymasz nazwy gałęzi oddzielone spacjami, które możesz następnie przekazać git branch -d:

git branch -d $(git branch | grep -v '^*')

lub:

git branch | grep -v '^*' | xargs git branch -d

Zwróć uwagę, że małe litery -dnie usuwają „nie w pełni scalonej” gałęzi (zobacz dokumentację). Użycie -Dusunie takie gałęzie, nawet jeśli spowoduje to "zgubienie" zatwierdzeń; używaj tego z wielką ostrożnością, ponieważ powoduje to również usunięcie reflogów gałęzi, tak że zwykłe "odzyskiwanie po przypadkowym usunięciu" również nie działa.

torek
źródło
Powinno być git branch -D $(git branch | grep -v '^*'), jeśli chcesz usunąć te gałęzie, które zostały połączone.
Pratik Singhal,
@PratikSinghal: usuwa wszystkie inne gałęzie, a nie tylko gałęzie, które Git uważa za „scalone”. Rzadko jest to dobry pomysł. W mojej odpowiedzi zwróciłem już uwagę na oba te elementy.
torek
12

Aby usunąć wszystkie połączone gałęzie (z wyjątkiem bieżących -v ‘*’):

git branch --merged | grep -v '*' | xargs git branch -D

również zrobiłem takie polecenie do całkowitego wyczyszczenia repozytorium:

alias git-clean="git branch  | grep -v '*' | grep -v 'master' | xargs git branch -D  && git reset --hard && git clean -d -x -f"

zaczerpnięte stąd .

Stepan Suvorov
źródło
1
Spowoduje to tylko usunięcie połączonych gałęzi.
Pratik Singhal,
10

Usuń wszystkie oddziały z wyjątkiem konkretnego oddziału :

git branch | grep -v "branch name" | xargs git branch -D

Usuń wszystkie lokalne oddziały z wyjątkiem develop i master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Asad Manzoor
źródło
6

W przypadku systemu Windows w programie PowerShell użyj:

git branch | %{ $_.Trim() } | ?{ $_ -ne 'master' } | %{ git branch -D $_ }
Robert Corvus
źródło
3

Kiedyś stworzyłem tę konstrukcję dla mojego środowiska Windows. Może to pomoże komuś innemu. Podczas wykonywania główna i bieżąca gałąź nie są usuwane . Wszystkie inne połączone gałęzie zostaną usunięte niezależnie.

@echo off
cd PATH_TO_YOUR_REPO

REM -- Variable declerations
set "textFile=tempBranchInfo.txt"
set "branchToKeep=master"
set "branchToReplaceWith="
git branch --merged > %textFile%

REM -- remove "master" from list to keep the branch
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%textFile%" echo(!line:%branchToKeep%=%branchToReplaceWith%!
    endlocal
)

REM -- execute branch delete commands
for /f "delims=" %%a in (%textFile%) do (
    git branch -D %%a
)

REM -- remove temp-file with branch information inside
DEL %textFile%

REM -- show local branches after the cleaning
echo Local branches:
git branch

pause 
exit
George Maharis
źródło
3

Aby usunąć wszystkie gałęzie z wyjątkiem bieżącej gałęzi w jednym kroku:

git branch | grep -v $(git rev-parse --abbrev-ref HEAD) | xargs git branch -D

Dan Dye
źródło
2

Usuń lokalnie wszystkie połączone gałęzie:

git branch -D `git branch --merged | grep -v \* | xargs`

Usuń wszystkie oddziały z wyjątkiem konkretnego oddziału :

git branch | grep -v "branch name" | xargs git branch -D

Usuń wszystkie lokalne oddziały z wyjątkiem develop i master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Asad Manzoor
źródło
2

Zakładając, że git branchpokazuje bieżącą gałąź z prefiksem *; Używając Powershell, następująca jedna linijka usunie wszystkie gałęzie, które nie zaczynają się od *.

git branch | ? { $_ -lt "*" } | % { git branch -D $_.Trim() }

? = Gdzie-obiekt

% = Foreach-Object

Aaron
źródło
1

Widzę tutaj wiele zakodowanych na stałe nazw gałęzi ... I myślę, że moja odpowiedź jest dokładniejsza do części pytania dotyczącej „bieżącej gałęzi”, zachowując jednocześnie jedną linię i czytelną dla początkujących użytkowników, takich jak ja. Aby przypisać kredyt tam, gdzie jest należny, odpowiedź jest raczej oparta na odpowiedzi @ pankijs.

git branch | grep -v $(git branch --show-current) | xargs git branch -d

i mam alias w jednej linii w moich .bash_aliases w debianie.

alias gitbclean='git branch | grep -v $(git branch --show-current) | xargs git branch -d'

(Chociaż myślę, że niektóre funkcje basha muszą być włączone, aby polecenie sub działało w niektórych wierszach poleceń)

NullifiedWarp
źródło
1

Używam tego, ponieważ jestem bardziej selektywny w tym, czego nie chcę usuwać. Poniższe polecenie usuwa każdą gałąź z wyjątkiem master, develop i bieżącej gałęzi.

BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
echo $BRANCHES

Więc umieściłem to w moim ~/.zshrc

delete_branches() {
  BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
  echo $BRANCHES
}

alias cleanup_branches=delete_branches
Justin Rice
źródło
0

IMHO, najbezpieczniejszym sposobem usuwania lokalnych oddziałów jest:

git branch -av | grep "\[gone\]" | awk '{print $1}' | xargs git branch -d

Więcej informacji związanych z tym tematem można znaleźć w sekcji Usuń wszystkie lokalne gałęzie git

elbik
źródło
aby wydrukować goneznacznik, którego powinieneś użyć -vv(dwukrotnie gadatliwy), ale ci -anie pomoże (wyświetla również zdalne gałęzie)
pqnet