Posso cancellare tutti i rami locali tranne quello attuale?


95

Voglio eliminare tutti i rami che vengono elencati nell'output di ...

$ git branch

... ma mantenendo il ramo attuale, in un solo passaggio . È possibile? Se é cosi, come?


1
possibile duplicato di Elimina tutti i rami git locali
Andrew C


Risposte:


66

Sulla base della risposta di @pankijs, ho creato due alias 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"

Da aggiungere ~/.gitconfig


E, come ha sottolineato @torek:

Nota che le lettere minuscole -dnon eliminano un ramo "non completamente unito" (vedi la documentazione). L'utilizzo -D cancellerà tali branch , anche se questo causa la "perdita" dei commit; usalo con molta attenzione , poiché elimina anche i reflog di branch, in modo che anche la solita roba di "ripristino da eliminazione accidentale" non funzioni.

Fondamentalmente, non utilizzare mai la -forceversione se non sei sicuro al 300% di non perdere nulla di importante. Perché è perso per sempre .


2
i commit su un ramo cancellato dovrebbero essere ancora nel reflog per un po '.
CaptRespect

In effetti, i commit rimarrebbero in reflog. Ma non il ramo stesso. Non lo proverei, ma immagino che potresti trovare i tuoi commit, ma tornare allo stato del ramo? Ne dubito. Cherry-pick potrebbe essere utilizzato per recuperare i commit in un ramo eliminato, ma non sarai in grado di ripristinare il ramo stesso.
Vadorequest

1
@Vadorequest puoi ricreare il ramo che punta a un certo commit facendogit branch branchname commitid
pqnet

@pqnet non sapevo che avrebbe ricreato tutta la cronologia per quel ramo, grazie, buono a sapersi!
Vadorequest

1
@Vadorequest poiché gli oggetti commit sono immutabili (e indicizzati come hash), ogni modifica richiede la creazione di un nuovo oggetto (con un hash diverso)
pqnet

179
$ git branch | grep -v "master" | xargs git branch -D 

cancellerà tutti i rami eccetto il master (sostituisci il master con il ramo che vuoi mantenere, ma poi cancellerà il master)


29
Se vuoi mantenere il ramo corrente usa grep -v ^*.
Schwern

2
Molte fonti mi mostrano questo script, ma quando lo
eseguo

1
questo non è accurato, non cancellerà un ramo chiamato master-copy, ad esempio
mvallebr

2
Modifica la regex se necessario, quindi, ad esempiogrep -v "^ *master$"
Brad Koch,

7
Se vuoi mantenere due rami usa grep -v "master\|my-other-branch".
Derek Soike

17

prima (passa al ramo che vuoi mantenere> ex : master ):

git checkout master

secondo ( assicurati di essere sul master )

git branch -D $(git branch)

3
molto veloce e facile. Perché questo non viene votato in alto?
princebillyGK

1
È la risposta più semplice e migliore per me.
Saleh Enam Shohag,

1
Se stai usando PowerShell, usa git branch -D $(git branch).Trim().
NatoBoram

13

git branch -d (o -D ) consente più nomi di rami, ma è un po 'complicato fornire automaticamente "tutti i rami locali escluso quello in cui mi trovo ora" senza scrivere almeno un po' di codice.

Il metodo "migliore" (formalmente corretto) è quello di utilizzare git for-each-refper ottenere i nomi dei rami:

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

ma poi è ancora più difficile capire in quale ramo ti trovi ( git symbolic-ref HEADè il metodo "formalmente corretto" per questo, se vuoi scrivere uno script di fantasia).

Più comodamente, puoi usare git branch, che stampa i nomi dei tuoi rami locali preceduti da due spazi o (per il ramo corrente) da un asterisco *. Quindi, esegui questo passaggio per rimuovere la *versione e ti rimangono i nomi dei rami separati da spazi, che puoi quindi passare a git branch -d:

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

o:

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

Nota che le lettere minuscole -dnon eliminano un ramo "non completamente unito" (vedi la documentazione). L'utilizzo -Dcancellerà tali branch, anche se questo causa la "perdita" dei commit; usalo con molta attenzione, poiché elimina anche i reflog di branch, in modo che anche la solita roba di "ripristino da eliminazione accidentale" non funzioni.


Dovrebbe esserlo git branch -D $(git branch | grep -v '^*'), se vuoi eliminare quei rami che sono stati uniti.
Pratik Singhal

@ PratikSinghal: elimina tutti gli altri rami, non solo i rami che Git considera "uniti". Questa è raramente una buona idea. Ho già sottolineato entrambi questi elementi nella mia risposta.
torek

12

Per rimuovere tutti i rami uniti (eccetto quelli correnti -v ‘*’):

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

inoltre ho creato tale comando per la pulizia completa del repository:

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

preso da qui .


1
Ciò elimina solo i rami uniti.
Pratik Singhal

10

Elimina tutti i rami tranne uno specifico :

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

Elimina tutti i rami locali tranne lo sviluppo e il master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

6

Per Windows, in Powershell usa:

git branch | %{ $_.Trim() } | ?{ $_ -ne 'master' } | %{ git branch -D $_ }

4

Elimina localmente tutti i rami uniti:

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

Elimina tutti i rami tranne uno specifico :

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

Elimina tutti i rami locali tranne lo sviluppo e il master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

3

Una volta ho creato questo costrutto per il mio ambiente Windows. Forse aiuterà qualcun altro. Durante l'esecuzione, il master e il ramo corrente non vengono eliminati . Tutti gli altri rami uniti verranno eliminati indipendentemente.

@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

3

Per eliminare tutti i rami tranne il ramo corrente in un unico passaggio:

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


2

Supponendo che git branchmostri il ramo corrente con prefisso *; Utilizzando Powershell, il seguente liner eliminerà tutti i rami che non iniziano con *.

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

? = Where-Object

% = Foreach-Object


1

Quindi vedo molti nomi di rami codificati qui ... E penso che la mia risposta qui sia più accurata per la parte "ramo corrente" della domanda pur mantenendola su una riga e leggibile per i neofiti come me. Giusto per mettere il merito dove è dovuto, la risposta è piuttosto ovviamente basata anche sulla risposta di @ pankijs.

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

e ho anche l'alias su una riga nel mio .bash_aliases in Debian.

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

(Anche se penso che alcune funzionalità di bash debbano essere abilitate affinché il comando secondario venga eseguito su alcune righe di comando)


1

Lo uso perché riesco a essere più selettivo in ciò che non voglio eliminare. Questo comando seguente rimuove ogni ramo tranne master, sviluppo e il ramo corrente.

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

Quindi ho messo questo nel mio file ~/.zshrc

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

alias cleanup_branches=delete_branches

0

IMHO, il modo più sicuro per rimuovere le filiali locali è:

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

Inoltre, maggiori informazioni relative a questo argomento puoi trovare Elimina tutti i rami git locali


per stampare il gonemarker dovresti usare -vv(verbose due volte), mentre -anon ti aiuta (elenca anche rami remoti)
pqnet
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.