Elimina i rami Git locali dopo averli eliminati nel repository remoto


162

Voglio avere i miei repository locali e remoti sempre sincronizzati in termini di filiali.

Dopo una revisione della richiesta pull su GitHub, unisco e rimuovo il mio ramo lì (remoto). Come posso recuperare queste informazioni nel mio repository locale e far sì che Git rimuova anche la mia versione locale del ramo?


Vuoi eliminare le filiali di tracciamento remoto, le filiali locali o entrambe? Puoi effettivamente scrivere un alias (bash o git) che prenderà tutti i rami remoti eliminati e troverà anche copie locali da eliminare, tutto in un solo comando.

Forse prova a usare i seguenti comandi per trovare qualcosa git ls-remotee git show-ref.

Inoltre, potresti voler dare un'occhiata git symbolic-refe git update-ref.

grazie per il tuo aiuto, ho finito per trovare la risposta da qualche altra parte. Vedi la mia risposta
sf89

Risposte:


180

Il modo rapido

git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

NB: se non sei attivo master, questo ha il potenziale per eliminare il ramo. Continua a leggere per il "modo migliore".

Assicurati di essere padrone

Puoi assicurarti che master, o qualsiasi altro ramo per quella materia, non venga rimosso greping per altro. In tal caso andresti:

git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d

Quindi se volessimo mantenere master, develope stagingper esempio, andremmo:

git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d

Rendi questo un alias

Dal momento che è un po 'lungo, potresti voler aggiungere un alias al tuo .zshrco .bashrc. Il mio si chiama gbpurge(per git branches purge):

alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'

Quindi ricaricare il tuo .bashrco .zshrc:

. ~/.bashrc

o

. ~/.zshrc

È possibile inserire i comandi in un alias e trasformarlo in un singolo comando. Tuttavia, poiché branchè un comando di porcellana e non idraulico , fai attenzione a eventuali cambiamenti dell'interfaccia utente nelle versioni future di Git che potrebbero romperlo.

1
Perfetto! Si noti che in seguito al flusso di lavoro di Github il ramo locale masterverrà eliminato.
Rubens Mariuzzo,

Non abbastanza sicuro che rimanga lì (lo sto usando tutti i giorni e non sembra farlo).
sf89,

4
Cordiali saluti, se vuoi mantenere più rami puoi usare una sola grep, in questo modo: grep -Ev '(\*|master|important-branch)'
Andrew Burns,

4
Se invece vuoi metterlo nel tuo ~/.gitconfig, aggiungi quanto segue alla [alias]sezione: gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(non c'è bisogno di usare () nell'espressione grep).
dskrvk,

82

Uso lo stesso flusso con GitHub e non ho trovato soddisfacenti le risposte precedenti, poiché git branch --mergedelenca i rami che sono stati uniti, ma non tutti sono stati rimossi in remoto nel mio caso. Quindi, questo ha funzionato per me:

git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d

dove:

  • git fetch --all -p: aggiorna lo stato delle filiali locali
  • git branch -vv: elenca lo stato delle filiali locali
  • grep ": gone]": filtra quelli eliminati
  • awk '{ print $1 }': estrae i loro nomi
  • xargs -n 1 git branch -d: passa il nome al comando delete

Nota: se si preferisce, è possibile utilizzare -D invece di -d, che impone l'eliminazione.

Per esempio:

someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).

someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

Riferimento:

http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches


3
Mi sono preso la libertà di assicurarmi che lo farò sempre contro il maestro, quindi: git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d Grande sceneggiatura e spiegazione, grazie per quello :)
Miguelgraz,

Si noti che branch -vvmostra l'ultimo messaggio di commit dal ramo. Se ti fosse capitato di "sparire" in quel messaggio, grep goneavrebbe colpito anche quel ramo. Quindi, grep ": gone]"è probabilmente un po 'più sicuro da usare.
Chawkinsuf,

1
Questa è la risposta effettiva alla domanda. Grazie.
Andrei Gladkyi,

1
Ancora meglio:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski il

3
Oltre a necessitare -Dinvece di -dquesta è la risposta perfetta!
Cas

72

provare:

git pull --prune

che elimina il tuo ramo locale, se il suo ramo remoto corrispondente viene eliminato.

aggiornato:

L'affermazione sopra non è così corretta.

Infatti, l'esecuzione git pull --prunesarà solo rimuovere i rami remoto di monitoraggio tali come

telecomandi / origine / fff
telecomandi / origine / dev
telecomandi / origin / master

Quindi, puoi eseguire git branch -rper controllare i rami di tracciamento remoto rimasti sul tuo computer. Supponiamo che i rami a sinistra siano:

origine / dev
origin / master

il che significa che il ramo origin/fffviene eliminato.

Quindi, dopo aver eseguito git pull --prune, basta eseguire:

git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)

puoi scoprire tutte le filiali locali che:

  1. non ha più la ricodifica dei rami remoti;
  2. può essere rimosso in modo sicuro.

quindi, è <the command above> | xargs git branch -dpossibile eliminarli tutti.


42
Questa risposta non è del tutto corretta. Il --pruneflag eliminerà solo le filiali di tracciamento remoto, non le filiali locali.

3
D'accordo con @Cupcake qui, questo non ottiene ciò che sto cercando qui.
sf89

6
Non ho intenzione di effettuare l'upgrade, ma questo è ciò di cui avevo bisogno dopo aver cancellato i rami locali e quindi aver eliminato GitHub, ma questi erano ancora presenti come telecomandi nel mio comando git remote -v.
Spechal,

8
Puoi anche farlo git fetch --prune, questo è il mio modo di scegliere
e_m0ney,

1
Ancora un altro errore Git dai consigli trovati su Stack Overflow ... ha git pull --pruneprovocato "Hai chiesto di estrarre dal telecomando '--prune', ma non hai specificato un ramo. Poiché questo non è il telecomando configurato di default per il tuo ramo corrente, tu deve specificare un ramo nella riga di comando. "
jww

23

Questo dovrebbe funzionare per evitare di eliminare i rami master e di sviluppo con la soluzione accettata:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d

16

Per le persone che usano PowerShell, questo equivale alla risposta sopra :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Filtra tutti i rami contrassegnati come spariti
  2. Chiama git branch -Dsu ciascuna delle filiali trovate

6

Niente di tutto questo funzionava per me. Puoi vedere la mia altra risposta qui: https://stackoverflow.com/a/34969726/550454

Ma essenzialmente, ora ho questo nel mio ~/.gitconfig:

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

5

Soluzione molto semplice: rimuovi il tuo repository locale e clona nuovamente il telecomando. Può non sembrare molto elegante, ma è semplice e capirai esattamente cosa stai facendo senza leggere le pagine man :-).


1
Perché così tanti voti negativi? Intendo ovviamente non efficiente, specialmente con repository più grandi, ma fa quello che ha chiesto OP. C'è qualche altro motivo per non farlo?
3ocene,

6
Perché perderai tutti i tuoi rami locali, gli stash, i commit non compressi ... è come pescare con la dinamite.
sevenseacat,

1
Lo stesso accade quando il laptop su cui stai lavorando viene in qualche modo corrotto, perso o rubato, quindi tendo a non tenere nulla di cruciale a livello locale. Mi sembra meglio solo creare un ramo e spingerlo, anche per piccole funzionalità, ed eliminarlo dopo che non è più utile.

1

Ho scritto questo one-liner per elencare tutti i rami locali che non hanno il ramo remoto corrispondente:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -

Fatto ciò, eliminare queste filiali locali è facile con xargs:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -|xargs -r git branch -d

anche questo mi sta elencando master, non funziona come previsto; fai attenzione
Enrico,

1

Lo faccio solo per rimuovere le filiali locali unite:

git branch -d $(git branch --merged)

e nel caso in cui desideri rimuovere anche i tracciamenti inesistenti:

git pull --prune

1

Nel caso in cui tu abbia appena spinto e unito il tuo ramo al master, quindi esegui le seguenti operazioni in git bash:

git branch -d branch_name_to_delete

Se sei attualmente in quel ramo ti riporterà al master. A questo punto fai un tiro con

git pull

-2

La risposta votata ha il potenziale per eliminare il master. Considera l'esempio pratico di seguito.

Ho avuto due rami di funzionalità hemen_README e hemen_BASEBOX che sono stati fusi in sviluppo, quindi sviluppo è stato unito in master. I rami delle funzionalità hemen_README e hemen_BASEBOX sono stati eliminati in remoto ma venivano comunque visualizzati localmente. Inoltre non sono un esperto locale, ma lo sviluppo.

In quel caso

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                      671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX                a535c0f added global exec paths to puppet manifest
        hemen_README                 ba87489 Updated Readme with considerable details
        master                       8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop       671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/hemen_BASEBOX a535c0f added global exec paths to puppet manifest
        remotes/origin/hemen_README  ba87489 Updated Readme with considerable details
        remotes/origin/master        2f093ce Merged in develop (pull request #3)

Quindi, se eseguo il comando parziale sopra

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
        hemen_BASEBOX
        hemen_README
        master

Si noti che mostra anche il master, che verrà infine eliminato.

In ogni caso sono stato in grado di farlo. Condivido il mio registro delle sessioni con te su come l'ho raggiunto.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [would prune] origin/hemen_BASEBOX
     * [would prune] origin/hemen_README
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin 
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [pruned] origin/hemen_BASEBOX
     * [pruned] origin/hemen_README

Ho appena controllato perché si poterà e poi lo poterò. guardando il comando di filiale qui sotto ci siamo occupati dei telecomandi

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX          a535c0f added global exec paths to puppet manifest
        hemen_README           ba87489 Updated Readme with considerable details
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Ora vai avanti ed elimina le filiali locali

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_BASEBOX 
    Deleted branch hemen_BASEBOX (was a535c0f).
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_README
    Deleted branch hemen_README (was ba87489).

Bene ora i rami sono come desiderato.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Naturalmente ha il potenziale di eliminare il master. Si prega di leggere attentamente la domanda. Come ho detto lì, avevo bisogno di un modo per ripulire le cose sul mio locale. Ciò significa eliminare tutti i rami che non esistono più sul telecomando. Se master non è più lì, allora scomparirà anche sul tuo computer locale.
sf89,
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.