Puoi eliminare più rami in un solo comando con Git?


355

Mi piacerebbe per ripulire il mio repository locale, che ha una tonnellata di vecchi rami: ad esempio 3.2, 3.2.1, 3.2.2, etc.

Speravo in un modo subdolo per rimuoverne molti contemporaneamente. Dato che seguono principalmente una convenzione di rilascio dei punti, ho pensato che forse ci fosse una scorciatoia per dire:

git branch -D 3.2.*

e uccidi tutti i rami 3.2.x.

Ho provato quel comando e, ovviamente, non ha funzionato.


11
git branch -D $(git branch | grep 3.2*)- ha funzionato per me. Elimina i rami il cui nome inizia con "3.2". grep- pattern matching nell'output ( git branchin questo caso). $()- significa eseguire e posizionare il risultato. |- incatenamento.
Eduard,

4
Vale la pena notare per coloro che non lo sanno, che -Dè una cancellazione forzata , dovrebbe usare -dnella maggior parte dei casi per essere più sicuri prima.
Redfox05

Risposte:


363

Non con quella sintassi. Ma puoi farlo in questo modo:

git branch -D 3.2 3.2.1 3.2.2

Fondamentalmente, git branch cancellerà più rami per te con una sola chiamata. Sfortunatamente non completa il nome del ramo. Sebbene, in bash, puoi fare:

git branch -D `git branch | grep -E '^3\.2\..*'`

3
Il completamento su git branch -D/-dfunziona bene per me. Potrebbe voler aggiornare il tuo (forse dalla più recente directory contrib di git.git).
Cascabel,

19
Invece di git branch | ...te potresti usare $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). È più lungo, lo so, ma è garantito che sia un output adatto, mentre git branchha un output piuttosto con cose come *e ->(per symrefs) che possono rovinarti in script / one-liner.
Cascabel,

3
Forse sono l'unico con questo problema, ma ho grepdeciso di includere sempre la bandiera --color=always- ho git branch -Dlanciato error: branch 'my_branch' not found.fino a quando non ho corso senza la bandiera colorata.
eebbesen,

@eebbesen L'hai disabilitato a livello globale? git branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
Incontro

2
Con l'espansione parentesi puoi scrivere git branch -D 3.2{,.1,.2}per eliminare tutti e tre i rami gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck

147

Bene, nel peggiore dei casi, potresti usare:

git branch | grep '3\.2' | xargs git branch -d

22
Questo è praticamente il metodo perfetto per chiunque utilizzi una notazione prefissata standardizzata per i nomi dei rami (ad es. "Fix / ..." o "feature / ...").
Haz,

4
Semplice ed efficiente! Raccomanderei comunque di eseguire prima senza la | xargs git branch -dparte per verificare cosa verrà effettivamente eliminato.
mathielo,

Si consiglia di non eseguire grepl'output di git branch, poiché è destinato alla lettura, non all'analisi. Potrebbe cambiare in qualsiasi momento. usa for-each-refinsieme con i --formatparametri, come suggerito in altre risposte, e poi combina con i suggerimenti in questa risposta.
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

MODIFICARE:

Una versione più sicura (suggerita da Jakub Narębski e Jefromi), poiché l'output di git branch non è pensato per essere utilizzato negli script:

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

... o senza xargs:

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

14
Non utilizzare l' git branchoutput per gli script. Usa git for-each-ref.
Jakub Narębski,

1
Per eliminare i tag con il simbolo @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt

Ha un refuso. Dovrebbe essere "/3.2/*" non "/3.2*". Inoltre, sembra che tu abbia copiato le altre risposte incollate nelle tue.
Max MacLeod,

Nessun errore di battitura qui. Dalla pagina man: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
gawi

1
Vale la pena notare per coloro che non lo sanno, che -Dè una cancellazione forzata , dovrebbe usare -dnella maggior parte dei casi per essere più sicuri prima.
Redfox05

115

È possibile utilizzare git branch --list per elencare i rami idonei e utilizzare git branch -D / -d per rimuovere i rami idonei.

Un esempio di copertina:

git branch -d `git branch --list '3.2.*'`

Quando provo questo, ricevo un sacco di messaggi di errore come error: branch 'package.json' not found.. Sembra che * sia espanso troppo presto e tenta di eliminare un ramo corrispondente al nome di ogni file e directory.
Antimonio

Funziona bene! Sto gitconfig
riscontrando

6
Questa risposta deve essere più in alto nell'elenco, super pulita, funziona, niente grep
jemiloii,

1
Bello che questo sia facile da testare prima semplicemente emettendogit branch --list '3.2.*'
Will

3
Su windowsgit branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson

38

Di recente, stavo cercando una soluzione per lo stesso problema, finalmente ho trovato una risposta e funziona molto bene:

  1. Apri il terminale o equivalente.
  2. Digitare git branch | grep "pattern" per un'anteprima dei rami che verranno eliminati.
  3. Digitare git branch | grep "pattern" | xargs git branch -D

Questa soluzione è fantastica e se vuoi una spiegazione completa di ogni comando e di come funziona, è data qui .


28

Uso

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

7
un piccolo suggerimento è che se si rimuove l'ultima parte del comando "| xargs git branch -D", verranno prodotti solo i rami corrispondenti. Quindi, puoi visualizzare l'anteprima dei rami che verranno eliminati
Max MacLeod

1
Inoltre ho aggiunto un alias per semplificare questo: alias grefs='git for-each-ref --format="%(refname:short)"'così posso farlogrefs | grep 'regexpattern' | xargs git branch -D
angularsen,

Lo amo. Bello e semplice!
Bhargav Ponnapalli,

15

Forse lo troverai utile:

Se si desidera rimuovere tutti i rami che non sono ad esempio "master", "pippo" e "barra"

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

grep -v 'qualcosa' è un abbinamento con inversione.


Personalmente mi piace l' -Dopzione rispetto ad altre risposte. Grazie per la risposta qui @Adi. Le soluzioni funzionano per me.
AMIC MING

9

Ho messo le mie iniziali e un trattino (at-) come i primi tre caratteri del nome del ramo per questo motivo esatto:

git branch -D `git branch --list 'at-*'`

Tutte le risposte sostanzialmente lo dicono, questo sembra essere il più semplice.
tfantina,

7

Se non sei limitato all'utilizzo del prompt dei comandi git, puoi sempre eseguire git guie utilizzare la voce di menu Branch-> Elimina. Seleziona tutti i rami che desideri eliminare e lascialo strappare.


questo ti consente solo di eliminare le filiali locali
Stealth Rabbi

7

Soluzione Powershell:

Se usi Windows, puoi usare PowerShell per rimuovere più rami contemporaneamente ...

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.

Puoi anche mettere a punto il funzionamento della corrispondenza del modello usando il comando Select-String di Powershell. Dai un'occhiata ai documenti PowerShell .


6

Mantieni "sviluppa" ed elimina tutti gli altri in locale

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

5

Ho creato una piccola funzione che potrebbe essere utile sulla base della risposta fornita da @gawi (sopra).

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

Aggiungilo al tuo .bash_profilee riavvia il tuo terminale. Quindi puoi chiamare dalla riga di comando in questo modo:

removeBranchesWithPrefix somePrefix

Nota

L'ho attualmente configurato per un'eliminazione graduale, il che significa che non eliminerà i rami se non sono già stati uniti. Se ti piace vivere al limite, cambia -din -De cancellerà tutto con il prefisso a prescindere!


5

Se hai davvero bisogno di pulire tutti i tuoi rami, prova

git branch -d $(git branch)

Elimina tutte le filiali unite locali tranne quella che stai attualmente effettuando il check-in.

È un buon modo per rendere pulito il tuo locale


Questo ha funzionato abbastanza bene per me. Ha lasciato due rami tranne quello che ero uno che poi ho rimosso usando lo stesso comando ma usando la "-D" maiuscola anziché "-d". Ho avuto alcuni errori su git non trovando i file ma i rami sono stati eliminati.
Lurifaxel,

3

Potrebbe piacerti questo piccolo elemento ... Estrae l'elenco e chiede la conferma di ogni elemento prima di eliminare definitivamente tutte le selezioni ...

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`

Usa -D per forzare le cancellazioni (come al solito).

Per leggibilità, ecco quella suddivisa riga per riga ...

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`

ecco l'approccio 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

infine, mi piace avere questo nel mio .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'

In questo modo posso solo dire

gitSelect | xargs git branch -D.

3

Per le anime pure che usano PowerShell qui il piccolo script git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })


2

funziona correttamente per me:

git branch | xargs git branch -d

git branch | xargs git branch -D

elimina tutte le filiali locali


2

Utilizzare il seguente comando per rimuovere tutti i rami (il ramo estratto non verrà eliminato).

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

Modifica: sto usando un Mac OS


0

Se sei su Windows, puoi usare PowerShell per fare questo:

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

sostituire feature/*con qualsiasi motivo che ti piace.


6
grep è un cmdlet non riconosciuto per me ... quindi ho cambiato per questo ramo git | dove {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} e ha funzionato!
Alex


0

È possibile utilizzare git guiper eliminare più rami contemporaneamente. Da Prompt dei comandi / Bash -> git gui-> Remoto -> Elimina ramo ... -> seleziona i rami remoti che desideri rimuovere -> Elimina.


0

Oggi ho appena ripulito un gran numero di filiali locali / remote obsolete.

Di seguito è riportato come l'ho fatto:

1. elenca tutti i nomi delle filiali in un file di testo:

git branch -a >> BranchNames.txt

2. aggiungi i rami che voglio cancellare per comandare "git branch -D -r":

git branch -D -r origin / dirA / branch01 origin / dirB / branch02 origin / dirC / branch03 (... aggiungi qualsiasi nome di ramo)

3. eseguire il cmd

E questo funziona in modo molto più veloce e affidabile di " git push origin --delete ".

Questo potrebbe non essere il modo più intelligente come elencato in altre risposte, ma questo è piuttosto semplice e facile da usare.


0

Se hai installato Git GUI, che è un componente aggiuntivo predefinito per Windows, è il più semplice. Puoi usare ctrl per scegliere più rami ed eliminarli con un clic.


0

Se stai usando Fish shell, puoi sfruttare le stringfunzioni :

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

Questo non è molto diverso dalle opzioni Powershell in alcune delle altre risposte.


0

Se avessi tutti i rami da eliminare in un file di testo (rami-a-del.txt) (un ramo per riga), allora potresti farlo per eliminare tutti questi rami dal telecomando (origine): xargs -a branches-to-del.txt git push --delete origin


0

Per eliminare più rami in base a un modello specificato, procedi come segue:

Apri il terminale o equivalente e digita i seguenti comandi:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

Rimuovere tutti i rami 3.2.x, è necessario digitare

git branch | grep "3.2" | xargs git branch -D

È tutto!

Sei bravo ad andare!


-1

Come in Git, tutti i rami non sono nulla in base al riferimento al repository git, perché non eliminare semplicemente i rami che stanno andando .git/refe quindi se qualcosa che non viene lasciato fuori che non è interessante nel repository verrà automaticamente raccolto, quindi non ho bisogno di preoccuparti.



-4

Puoi rimuovere tutti i rami rimuovendo tutti i riferimenti non necessari:

rm .git/refs/heads/3.2.*


2
Sottovalutato per due motivi: 1. utilizza un dettaglio di implementazione (il fatto che le versioni correnti di Git memorizzano i rami come file in una determinata directory). Questo può cambiare nelle versioni future rendendo la risposta non valida. 2. Non funziona se il repository si trova in una directory separata .
axiac,

Inoltre, questo produce risultati molto imprevisti se lo si esegue su un repository compresso ( git gc). Non farlo.
Matthieu Moy
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.