Eliminar múltiples ramas remotas en git

128

Tengo un miembro del equipo que, sin darse cuenta, empujó a más de 150 de sus sucursales locales a nuestro repositorio central. Afortunadamente, todos tienen el mismo prefijo. Usando ese prefijo, ¿hay un comando git o un pequeño script de shell que pueda usar que elimine todos esos a la vez?

Jake A. Smith
fuente

Respuestas:

150

Use el siguiente comando para eliminar todas las ramas con PREFIXprefijo en el servidor remoto.

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

Es posible que desee hacer una ejecución en seco primero para ver si son las ramas que desea eliminar:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'
neevek
fuente
2
Me gusta esto porque es un trazador de líneas y puedo hacer una carrera en seco primero. Desafortunadamente, se equivoca con este mensaje: $ 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}', ¿podría ver todos los nombres de sucursales con prefijo APR enumerados?
neevek
1
OK, es porque la APR-04-DPHrama ya fue eliminada. Eche un vistazo a estas preguntas respondidas: esto y esto y también esto . Las respuestas a esas preguntas abordan el mismo problema, es posible que desee probar las soluciones usted mismo.
neevek
26
si tiene / en sus nombres de sucursal (si está usando git-flow o algo así), imprima {$ 2 "/" $ 3} en su lugar
ajma 9/15
44
Estoy usando msysgit en Windows, y el siguiente comando funcionó para mí (junto con el comentario de @ ajma para nombres de sucursales que contienen barras diagonales:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe
96

Si desea un enfoque más simple, por ejemplo, elimine 3 o 4 ramas:

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

Importante: solo funciona en Git v1.7.0 y superior.

jfeston
fuente
66
Terminé usandogit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan
36

¡Gracias a Neevek por su excelente y elegante solución!

Pero tengo algunos problemas con las barras en los nombres de las ramas (estoy usando Git Flow), debido al awkseparador de campo /( -Fopción)

Por lo tanto, mi solución se basa en Neevek , pero analiza correctamente los nombres de rama con /. En este caso, supongo que su control remoto llamó origin. Comando para eliminar ramas remotas con nombres que comienzan con PATTERN:

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

Y no olvide verificar lo que va a eliminar:

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

CONSEJO ÚTIL: Si los nombres de sus sucursales (sin origin/prefijo) se almacenan en un archivo de texto (un nombre de sucursal por línea), simplemente ejecute:

cat your_file.txt | xargs -I {} git push origin :{}
Dmitriy
fuente
2
Usar en xargs -a file -Llugar de cat file | xargs. Aún más simple xargs -a file git push --delete origin.
musiKk
15

Esta puede ser una respuesta duplicada, pero a continuación la probé y funcionó perfectamente.

  1. Eliminar sucursal local con fuerza

git branch -D nombre-sucursal

  1. Eliminar rama remota

git push origin --delete branch-name

  1. Eliminar más de 1 sucursal local

git branch -D nombre-rama1 nombre-rama2

  1. Eliminar más de 1 rama remota

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

  1. Eliminar sucursal local con prefijo. Por ejemplo, característica / *

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

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

  1. Lista de rama remota con prefijo.

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

  1. Eliminar rama remota con prefijo

git branch -r | grep -Eo 'feature /.*' | xargs -I {} origen de inserción de git: {}

Naren
fuente
2
creo que querías escapar de los backticks en el paso 5
GPL
¿Cómo agregar backticks?
Naren
1
@Naren: el problema es que el formato de rebajas convierte tus backticks en un comando de estilo. Los reemplacé con un método de sustitución de comando diferente (por ejemplo, "$ (comando)" es equivalente a `comando` pero no se traduce por markdown en algo extraño). La otra cosa que podría hacer es escapar de los backticks con '\'
Stabledog
13

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

branch -rmuestra origin/prefix/branchname. Entonces tomará prefix/branchname.

Kirby
fuente
Creo que quisiste decir xargs -I {} git push origin :{}, no -i.
jojo
1
@jojo, AFAIK, ya -ique utiliza el reemplazo predeterminado para {}pero con -Iusted puede declarar el suyo propio. ... acabo de encontrar en el manual:-i ... the same as -I{}
Kirby
10

La solución de Neevek es elegante, pero puede ser mejor: la solución como se propone llama 'git push' una vez por rama, lo que significa que se eliminará un viaje de ida y vuelta de red adicional por rama. Dado que de todos modos está usando awk, ¿por qué no usarlo para prefijar el ':' y luego xargs puede llamar a 'git push' exactamente una vez y eliminar todas las ramas a la vez:

Ejecutar en seco para enumerar las ramas que se eliminarían:

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

Solución final para empujar realmente las eliminaciones:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin
carencia
fuente
2
Funciona perfectamente en la situación en la que no puede usar la opción "-I" para xargs cuando tiene una versión inferior bash o usa una versión de Windows git bash.
zchholmes
Tuve un problema xargs: replstr may not be emptycon la solución de Neevek, tal vez la versión git ... git version 1.9.5Pero esto funcionó muy bien para mí. Gracias a los dos
IamFace
8

recurso 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
Ashish Sajwan
fuente
Gracias, esto funcionó para mí. En mi caso, podría eliminar varias sucursales locales. ¡Gracias!
Prashant Kabade
5

Gracias a Steve y Neevek, encontré una solución que funcionó bastante bien para mí y pensé que valía la pena compartirla:

La solución de Steve funcionó para mí con un pequeño ajuste. Mis mandos a distancia fueron nombrados, origin/feature/some-feature-nameasí que recorté tu awk:

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

Ahora está haciendo un pequeño flujo de eliminación:

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

Sin embargo, me preguntaba si alguien tenía alguna idea para una solución más elegante, que podría generar algo como esto (mi secuencia de comandos CLI es bastante pobre, por lo que me tomaría un tiempo resolver esto):

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

Esto daría como resultado una salida única agradable con una solicitud de red:

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
andrewmart.in
fuente
4

Gracias a Neevek Esto funcionó bien después de reconfigurarlo para mi propósito:

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

También necesitaba tener en cuenta la estructura de la carpeta. Mis ramas de características están en una estructura de carpetas como origin / feature / PREFIX-FEATURENUMBER. Así que tuve que construir mi patrón desde $ 2 = carpeta + $ 3 = nombre de sucursal.

usuario3416278
fuente
4

Todos están usando awk, no estoy seguro de por qué. Siento que eso es más complejo. Esto es lo que uso para eliminar todas las ramas remotas en mi forkcontrol remoto:

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

Agregue grepentre xargsy sedsi necesita filtrar la lista solo a un subconjunto de ramas remotas.

void.pointer
fuente
1
Muchas gracias. Esta realmente funcionó para mí entre todas las soluciones ... grep también estaba devolviendo la rama completa con un nombre remoto origin/blaprefix_anotherbla. Pero el uso lo sedmanejó bien. Otra ventaja de este enfoque es que uso bitbucket y no necesito ingresar la contraseña de autenticación para cada eliminación de sucursal manualmente. Éste elimina todas las ramas en un solo lote.
Madhur Bhaiya
Para eliminar todas las ramas de greenkeepergit branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
abhisekp
4

Me doy cuenta de que esto es para el comando git, pero si está buscando una solución alternativa para hacer el mismo resultado o similar:

Puedes hacerlo desde aquí (Git Eliminar ramas remotas):

Luego seleccione las ramas que desea:

Asegúrese de tener los permisos para eliminar las ramas remotas.

Ewin Hong
fuente
Esta debería ser una respuesta excelente, es independiente de la plataforma.
karmington
¿Cuál es el software y está disponible para Linux?
abhisekp
1

Github también tiene una interfaz de usuario agradable y un mecanismo para eliminar ramas rápidamente, eso es si prefieres usar una interfaz de usuario

Alex
fuente
1
Sí, está documentado aquí , pero aún debe hacer clic una vez para cada rama individual. La solución más votada aquí es la mejor manera de hacer muchas ramas en las que puede escribir una expresión regular para que coincida.
thewoolleyman
0

Traté de eliminar todas las ramas remotas de origen / lanzamiento / r1-1 *, por lo tanto, la siguiente línea de comando funcionó muy bien.

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

No pude usar awk porque estamos usando una estructura de barra para el nombre de nuestras sucursales.

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

Esto obtiene todas las ramas remotas, obtiene solo la de un solo usuario, remueve la cadena "origin /" y ejecuta una eliminación en cada una de ellas.

Patrick Desjardins
fuente
0

Funcionamiento en seco:

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

Eliminar ramas remotas:

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

Eliminar solo ramas remotas completamente fusionadas:

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

Explicación:

sed "s/origin\///"se eliminará origin/del nombre de la sucursal. Sin quitar eso, obtuve:remote ref does not exist

Tobias Ernst
fuente
0

Las respuestas anteriores me ayudaron a eliminar todas las ramas de lanzamiento de 2018. Ejecuté esto en mi símbolo del sistema de Windows 10. He instalado clink , por lo que Linux como comandos funciona para mí.

Funcionamiento en seco:

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

Si la ejecución en seco muestra ramas que no están en remoto / origen. Ejecute debajo del comando git prune para corregir y verificar nuevamente.

git remote prune origin

Elimine una vez que esté satisfecho con el resultado anterior:

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

Si ves: error: unable to delete 'release-...2018': remote ref does not exist. Luego ejecute el comando de poda anterior e intente nuevamente.

Damodar Bashyal
fuente
-4

Advertencia: Esto eliminará todas las ramas remotas. Usar con precaución.

Creo que mi forma de eliminar ramas remotas es la mejor.

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

Advertencia: Esto eliminará todas las ramas remotas. Usar con precaución.

Dmytro Gorpynenko
fuente
44
Votado como un troll obvio. Eliminaría si tuviera los derechos.
Jake A. Smith
donde encontraste trolling?
Dmytro Gorpynenko
2
esto no es correcto, te faltan algunos argumentos vitales para xargs y no responde la pregunta.
Rob
@ JakeA.Smith Jake, supongo que pensaste que este código eliminará el maestro remoto, que no es el caso ya que grep -v master encuentra todo menos el maestro.
Vadim Samokhin
@Rob, ¿qué es incorrecto aquí? La declaración final ejecutada será algo así como git push: some_branch: another_branch, lo cual es absolutamente correcto.
Vadim Samokhin