Elimina più rami remoti in git


129

Ho un membro del team che ha inavvertitamente inviato oltre 150 delle sue filiali locali al nostro repository centrale. Per fortuna, hanno tutti lo stesso prefisso. Usando quel prefisso, c'è un comando git o un piccolo script di shell che posso usare che cancellerà tutti quelli in una volta?

Risposte:


151

Utilizzare il seguente comando per rimuovere tutti i rami con PREFIXprefisso sul server remoto.

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}

Potresti voler eseguire prima una prova a secco per vedere se sono i rami che vuoi rimuovere:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'

2
Mi piace perché è un one liner e posso fare prima un dry run. Sfortunatamente, si sbaglia con questo messaggio: $ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL'
Jake A. Smith

Con git branch -r | awk -F/ '/\/APR/{print $2}', potresti vedere tutti i nomi di filiale con prefisso APR elencati?
neevek

1
OK, è perché il APR-04-DPHramo era già stato cancellato. Dai un'occhiata a queste domande con risposta: questo e questo e anche questo . Le risposte a queste domande affrontano lo stesso problema, potresti voler testare tu stesso le soluzioni.
neevek

26
se hai / nei nomi dei tuoi rami (se stai usando git-flow o qualcosa del genere), stampa invece {$ 2 "/" $ 3}
ajma

4
Sto usando msysgit in Windows e il seguente comando ha funzionato per me (in combinazione con il commento di @ ajma per i nomi dei rami contenenti barre in avanti:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe

96

Se ti piace un approccio più semplice, ad esempio elimina 3 o 4 rami:

git push origin --delete <branch1> <branch2> <branch3>

Importante: funziona solo su Git v1.7.0 e versioni successive.


6
Ho finito per usaregit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan

36

Grazie a Neevek per la soluzione fantastica ed elegante!

Ma ho alcuni problemi con le barre nei nomi dei rami (sto usando Git Flow), a causa del awkseparatore di campo /( -Fopzione)

Quindi la mia soluzione è basata su Neevek , ma analizza correttamente i nomi dei rami con /. In questo caso presumo che il tuo telecomando abbia chiamato origin. Comando per eliminare rami remoti con nomi che iniziano con PATTERN:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

E non dimenticare di controllare cosa vuoi eliminare:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

SUGGERIMENTO UTILE: se i nomi dei rami (senza origin/prefisso) sono memorizzati in un file di testo (un nome di ramo per riga), esegui semplicemente:

cat your_file.txt | xargs -I {} git push origin :{}

2
Usa xargs -a file -Linvece di cat file | xargs. Ancora più semplice xargs -a file git push --delete origin.
musiKk

15

Questa potrebbe essere una risposta duplicata, ma sotto testata e ha funzionato perfettamente per me.

  1. Elimina il ramo locale con forza

ramo git -D nome-ramo

  1. Elimina ramo remoto

git push origin - cancella nome-ramo

  1. Elimina più di 1 filiale locale

git branch -D branch-name1 branch-name2

  1. Elimina più di 1 ramo remoto

git push origin --delete branch-name1 branch-name2

  1. Elimina ramo locale con prefisso. Ad esempio, feature / *

git branch -D $ (git branch --list 'feature / *')

git branch -D backtick $ (git branch --list 'feature / *' backticks )

  1. Elenca ramo remoto con prefisso.

git branch -r | grep -Eo 'feature /.*'

  1. Elimina ramo remoto con prefisso

git branch -r | grep -Eo 'feature /.*' | xargs -I {} git push origin: {}


2
Penso che volevi sfuggire ai backtick nel passaggio 5
GPL

Come aggiungere backtick?
Naren

1
@ Naren: il problema è che la formattazione del markdown trasforma i tuoi backtick in un comando di styling. Li ho sostituiti con un diverso metodo di sostituzione dei comandi (ad es. "$ (Comando)" è equivalente a "comando" ma non viene tradotto da markdown in qualcosa di strano). L'altra cosa che potresti fare è sfuggire ai backtick con "\"
Stabledog

13

Lo stesso con grep: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -rspettacoli origin/prefix/branchname. Quindi ci vorrà prefix/branchname.


Penso che volevi dire xargs -I {} git push origin :{}, no -i.
jojo

1
@jojo, AFAIK, -iperché usa la sostituzione predefinita per {}ma con -Ite puoi dichiarare la tua. ... appena trovato nel manuale:-i ... the same as -I{}
Kirby

10

La soluzione di Neevek è elegante, ma può essere migliore: la soluzione proposta chiama "git push" una volta per filiale, il che significa che una rete aggiuntiva di andata e ritorno per filiale deve essere eliminata. Dato che stai comunque usando awk, perché non usarlo come prefisso ':' e quindi xargs può chiamare 'git push' esattamente una volta ed eliminare tutti i rami contemporaneamente:

Run a secco per elencare i rami che verrebbero eliminati:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'

Soluzione finale per eseguire effettivamente il push delle eliminazioni:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin

2
Funziona perfettamente nella situazione in cui non puoi usare l'opzione "-I" per xargs quando hai una versione inferiore di bash o usi una versione per Windows git bash.
zchholmes

Ne avevo una xargs: replstr may not be emptycon la soluzione di Neevek, forse la versione git .. git version 1.9.5Ma per me ha funzionato benissimo. Grazie a entrambi
IamFace

8

risorsa https://coderwall.com/p/eis0ba

    1 - List all your remote branches:

    $ git branch -r

    2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:

    $ git branch -r | awk -F/ '/\/feature-/{print $2}'
    3 - Pipe the last command to git push to delete them:
    # **Edit** - Removed extra colon, which is not needed
    $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
    4 - Grab a beer.

    5 - Remove any local reference to those branches:

    $ git remote prune origin

Grazie, questo ha funzionato per me. Nel caso in cui potrei eliminare più rami locali. Grazie!
Prashant Kabade,

5

Grazie a Steve e Neevek, ho trovato una soluzione che funzionava abbastanza bene per me che ho pensato valesse la pena condividere:

La soluzione di Steve ha funzionato per me con un piccolo aggiustamento. I miei telecomandi erano chiamati origin/feature/some-feature-namecosì ho tagliato il tuo awk:

git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}

Ora sta facendo un bel flusso di eliminazione:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
To github.com:project/project-name.git
- [deleted]         feature/search-placeholder
To github.com:project/project-name.git
- [deleted]         feature/server-error-message
To github.com:project/project-name.git
- [deleted]         feature/six-point-asterisk

Mi chiedevo se qualcuno avesse qualche idea per una soluzione più elegante, tuttavia, che potrebbe produrre qualcosa di simile (il mio scripting CLI è piuttosto scadente, quindi mi ci vorrebbe un po 'per capirlo):

git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk

Ciò si tradurrebbe in un bel singolo output con una richiesta di rete:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
- [deleted]         feature/search-placeholder
- [deleted]         feature/server-error-message
- [deleted]         feature/six-point-asterisk

4

Grazie a Neevek. Ha funzionato bene dopo averlo riconfigurato per il mio scopo:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

Avevo anche bisogno di prendere in considerazione la struttura delle cartelle. I miei rami di funzionalità sono in una struttura di cartelle come origin / feature / PREFIX-FEATURENUMBER. Quindi ho dovuto creare il mio pattern da $ 2 = cartella + $ 3 = branchname.


4

Tutti stanno usando awk, non so perché. Mi sento come se fosse più complesso. Ecco cosa uso per eliminare tutti i rami remoti sul mio forktelecomando:

$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork

Inserisci un greptra i xargse sedse devi filtrare l'elenco fino a solo un sottoinsieme di rami remoti.


1
Molte grazie. Questa in realtà ha funzionato per me tra tutte le soluzioni .. grep stava restituendo il ramo completo con il nome remoto come pure origin/blaprefix_anotherbla. Ma l'uso lo ha sedgestito bene. Un altro vantaggio di questo approccio è che utilizzo bitbucket e non ho bisogno di inserire manualmente la password di autenticazione per ogni cancellazione di ramo. Questo elimina tutti i rami in un unico batch.
Madhur Bhaiya

Per eliminare tutti i rami di git branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
Greenkeeper

4

Mi rendo conto che questo è per il comando git, ma se stai cercando una soluzione alternativa per fare lo stesso o lo stesso risultato:

Puoi farlo da qui (Git Remove Remote Branch):

Quindi seleziona i rami che desideri:

Assicurati di disporre delle autorizzazioni per rimuovere i rami remoti.


Questa dovrebbe essere una risposta eccellente, è indipendente dalla piattaforma.
Karmington

Qual è il software ed è disponibile per Linux?
abhisekp

1

Github ha anche una bella interfaccia utente e un meccanismo per eliminare rapidamente i rami, se preferisci usare un'interfaccia utente


1
Sì, è documentato qui , ma è comunque necessario fare clic una volta per ogni singolo ramo. La soluzione più votata qui è il modo migliore per fare molti rami che puoi scrivere una regex per abbinare.
thewoolleyman

0

Ho provato a eliminare tutti i rami remoti origin / release / r1-1 *, quindi la seguente riga di comando ha funzionato bene.

git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' |  xargs -I {} git push origin :{}

0

Non sono stato in grado di utilizzare awk perché stiamo utilizzando una struttura barra per il nome dei nostri rami.

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

Questo ottiene tutto il ramo remoto, ottiene solo quello per un singolo utente, remoto la stringa "origine /" ed esegue una cancellazione su ciascuno di essi.


0

Funzionamento a secco:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

Elimina rami remoti:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Elimina solo i rami remoti completamente uniti:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Spiegazione:

sed "s/origin\///"rimuoverà origin/dal nome del ramo. Senza toglierlo ho ottenuto:remote ref does not exist


0

Le risposte precedenti mi hanno aiutato a rimuovere tutti i rami di rilascio dal 2018. L'ho eseguito sul prompt dei comandi di Windows 10. Ho installato clink , quindi i comandi simili a Linux funzionano per me.

Funzionamento a secco:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

Se il funzionamento a secco mostra rami che non sono in remoto / origine. Esegui sotto il comando git prune per correggere e controllare di nuovo.

git remote prune origin

Elimina una volta che sei soddisfatto del risultato sopra:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

Se vedi: error: unable to delete 'release-...2018': remote ref does not exist. Quindi esegui il precedente comando prune e riprova.


-4

Attenzione: questo eliminerà tutti i rami remoti. Usare con cautela.

Penso che il mio modo di eliminare i rami remoti sia il migliore.

git branch -r | grep -v master | sed 's/origin\//:/'| xargs git push

Attenzione: questo eliminerà tutti i rami remoti. Usare con cautela.


4
Downvoted come un evidente troll. Cancellerei se avessi i diritti.
Jake A. Smith

dove hai trovato troll?
Dmytro Gorpynenko

2
questo non è corretto, ti mancano alcuni argomenti vitali per xargs e non risponde alla domanda.
Rob

@ JakeA.Smith Jake, immagino tu abbia pensato che questo codice rimuoverà il master remoto - il che non è il caso in quanto grep -v master trova tutto tranne master.
Vadim Samokhin

@ Rob, cosa c'è di sbagliato qui? L'istruzione finale eseguita sarà smth come git push: some_branch: another_branch, che è assolutamente corretto.
Vadim Samokhin
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.