Elimine las ramas locales de Git después de eliminarlas en el repositorio remoto

162

Quiero tener mis repositorios locales y remotos siempre sincronizados en términos de sucursales.

Después de una revisión de solicitud de extracción en GitHub, fusiono y elimino mi rama allí (remota). ¿Cómo podría obtener esta información en mi repositorio local y hacer que Git elimine también mi versión local de la rama?

sf89
fuente
¿Desea eliminar sus sucursales de seguimiento remoto, sucursales locales o ambas? En realidad, puede escribir un alias (bash o git) que tomará todas las ramas remotas eliminadas, y también encontrará copias locales para eliminar, todo en un solo comando.
Tal vez intente usar los siguientes comandos para llegar a algo, git ls-remotey git show-ref.
Además, es posible que desee ver git symbolic-refy git update-ref.
gracias por tu ayuda, terminé encontrando la respuesta en otro lugar. Mira mi respuesta.
sf89
3
Posible duplicado de Eliminar ramas ya no en remoto
amaechler

Respuestas:

180

El camino rapido

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

NB: si no está encendido master, esto tiene el potencial de eliminar la rama. Sigue leyendo para la "mejor manera".

Asegúrate de seguir siendo maestro

Puede asegurarse de que master, o cualquier otra rama para el caso, no se elimine por grepmás. En ese caso irías:

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

Entonces si quisiéramos mantener master , developy stagingpor ejemplo, iríamos:

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

Haz de esto un alias

Como es un poco largo, es posible que desee agregar un alias a su .zshrco .bashrc. El mío se llamagbpurge (para git branches purge):

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

Luego recarga tu .bashrco.zshrc :

. ~/.bashrc

o

. ~/.zshrc
sf89
fuente
Puede poner los comandos en un alias y convertirlo en un solo comando. Sin embargo, dado que branches un comando de porcelana y no de plomería , tenga cuidado con cualquier cambio en la interfaz de usuario en futuras versiones de Git que pueda romperlo.
1
¡Perfecto! Tenga en cuenta que después del flujo de trabajo de Github, la rama local masterse eliminará.
Rubens Mariuzzo
No, estoy bastante seguro de que permanece allí (lo estoy usando todos los días y parece que no lo hace).
sf89
44
Para su información si usted quiere tener varias ramas se puede utilizar una sola grep, así: grep -Ev '(\*|master|important-branch)'
Andrew Burns,
44
Si desea poner esto en su ~/.gitconfiglugar, agregue lo siguiente a la [alias]sección: gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(no es necesario usar () en la expresión grep).
dskrvk
82

Utilizo el mismo flujo con GitHub, y no encontré las respuestas anteriores que me satisfacen, ya que git branch --mergedenumera las ramas que se fusionaron, pero no todas se eliminaron de forma remota en mi caso. Entonces, esto funcionó para mí:

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

dónde:

  • git fetch --all -p: actualizar el estado de las sucursales locales
  • git branch -vv: enumera el estado de las sucursales locales
  • grep ": gone]": filtra los eliminados
  • awk '{ print $1 }': extraer sus nombres
  • xargs -n 1 git branch -d: pasar el nombre al comando eliminar

Nota: si lo prefiere, puede usar -D en lugar de -d, lo que exige la eliminación.

Por ejemplo:

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

Referencia:

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

Alessio
fuente
3
Me tomé la libertad de asegurarme de que siempre haré eso contra el maestro, por lo tanto: 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 Gran guión y explicación, gracias por eso :)
Miguelgraz
Tenga en cuenta que branch -vvmuestra el último mensaje de confirmación de la rama. Si por casualidad se hubiera "ido" en ese mensaje, también grep gonellegaría a esa rama. Por lo tanto, grep ": gone]"es probablemente un poco más seguro de usar.
chawkinsuf
1
Esta es la respuesta real a la pregunta. Gracias.
Andrei Gladkyi
1
Aún mejor:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski el
3
¡Aparte de necesitar en -Dlugar de -desto, es la respuesta perfecta!
Cas
72

tratar:

git pull --prune

que elimina su sucursal local, si su sucursal remota correspondiente se elimina.

Actualizado:

La declaración anterior no es tan correcta.

De hecho, correr git pull --pruneserá sólo eliminan las ramas remotas de seguimiento , tales como

controles remotos / origen / fff
controles remotos / origen / dev
controles remotos / origen / maestro

Luego, puede ejecutar git branch -rpara verificar las ramas de seguimiento remoto que quedan en su máquina. Supongamos que las ramas izquierdas son:

origen / dev
origen / maestro

lo que significa que origin/fffse elimina la rama .

Entonces, después de correr git pull --prune, solo corre:

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

Puede encontrar todas las sucursales locales que:

  1. ya no tienen ramas remotas correspondientes;
  2. Se puede quitar de forma segura.

luego, <the command above> | xargs git branch -dpuede eliminarlos todos.

nicky_zs
fuente
42
Esta respuesta no es del todo correcta. La --prunebandera solo eliminará las ramas de seguimiento remoto, no las ramas locales.
3
De acuerdo con @Cupcake aquí, esto no logra lo que estoy buscando aquí.
sf89
66
No voy a votar, pero esto es lo que necesitaba después de haber eliminado las sucursales locales y luego eliminarlas de GitHub, pero todavía existen como controles remotos en mi comando git remote -v.
Spechal
8
También puedes hacerlo git fetch --prune, esa es mi forma de elección
e_m0ney
1
Sin embargo, otro error de Git de los consejos encontrados en el desbordamiento de la pila ... git pull --pruneresultó en "Solicitó extraer del control remoto '--prune', pero no especificó una rama. Debido a que este no es el control remoto configurado por defecto para su rama actual, usted debe especificar una rama en la línea de comando ".
jww
23

Esto debería funcionar para evitar eliminar las ramas maestra y de desarrollo con la solución aceptada:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d
Intrépido
fuente
16

Para las personas que usan powershell, este es el equivalente a la respuesta anterior :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Filtre todas las ramas que están marcadas como desaparecidas
  2. Llama git branch -Da cada una de las ramas encontradas
amaechler
fuente
6

Nada de esto estaba funcionando para mí. Puedes ver mi otra respuesta aquí: https://stackoverflow.com/a/34969726/550454

Pero esencialmente, ahora tengo esto en mi ~/.gitconfig:

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

Solución muy simple: elimine su repositorio local y clone el remoto nuevamente. Puede que no parezca muy elegante, pero es simple y comprenderá exactamente lo que está haciendo sin leer las páginas de manual :-).


fuente
1
¿Por qué tantos votos negativos? Es decir, obviamente no es eficiente, especialmente con repositorios más grandes, pero hace lo que OP pidió. ¿Hay alguna otra razón para no hacer esto?
3oceno
66
Debido a que perderá todas sus ramas locales, escondites, compromisos no apresurados ... es como pescar con dinamita.
sevenseacat
1
Lo mismo sucede cuando la computadora portátil en la que está trabajando de alguna manera se corrompe, se pierde o se la roban, por lo que tiendo a no guardar nada crucial localmente. Me parece mejor crear una rama y empujarla, incluso para funciones pequeñas, y eliminarla después de que ya no sea útil.
1

He escrito esta línea para enumerar todas las ramas locales que no tienen la rama remota correspondiente:

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

Una vez hecho esto, eliminar estas sucursales locales es fácil 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
ks1322
fuente
esto mastertambién me está enumerando , no funciona como se esperaba; ten cuidado
Enrico
1

Solo hago eso para eliminar ramas locales fusionadas:

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

y en caso de que quiera eliminar también los registros inexistentes:

git pull --prune
alacambra
fuente
1

En el caso de que haya presionado y fusionado su rama para dominar, haga lo siguiente en git bash:

git branch -d branch_name_to_delete

Si actualmente estás en esa rama, te empujará de regreso al dominio. En este punto, haz un tirón con

git pull
Joshua Schlichting
fuente
-2

La respuesta votada tiene el potencial de eliminar master. Considere el siguiente ejemplo práctico.

Tenía dos ramas de características hemen_README y hemen_BASEBOX que se fusionaron en desarrollo, y luego desarrollo se fusionó en maestro. Las ramas de funciones hemen_README y hemen_BASEBOX se eliminaron de forma remota, pero aún se mostraban localmente. Además, no estoy en master localmente, sino en desarrollo.

En ese 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)

Entonces, si ejecuto el comando parcial anterior

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

Tenga en cuenta que también muestra master, que eventualmente se eliminará.

En cualquier caso pude hacerlo. Estoy compartiendo mi registro de sesión con usted sobre cómo lo logré.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
    Pruning origin
    URL: [email protected]: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: [email protected]:hemenkapadiapublic/vagrant-webdev.git
     * [pruned] origin/hemen_BASEBOX
     * [pruned] origin/hemen_README

Acabo de comprobar qué será podado y luego lo pode. mirando el comando de rama a continuación nos hemos ocupado de los controles remotos

    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)

Ahora adelante y elimine las sucursales locales

    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).

Bien ahora las ramas están como se desea.

    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)
Hemen Kapadia
fuente
Por supuesto, tiene el potencial de eliminar master. Por favor lea la pregunta cuidadosamente. Como dije allí, necesitaba una forma de limpiar las cosas en mi local. Eso significa eliminar todas las ramas que ya no existen en remoto. Si el maestro ya no está allí, también desaparecerá en su máquina local.
sf89