¿Se pueden eliminar varias ramas en un comando con Git?


355

Me gustaría limpiar mi repositorio local, que tiene un montón de ramas viejas: por ejemplo 3.2, 3.2.1, 3.2.2, etc.

Esperaba una forma astuta de eliminar muchos de ellos a la vez. Dado que en su mayoría siguen una convención de lanzamiento de puntos, pensé que tal vez había un atajo para decir:

git branch -D 3.2.*

y mata todas las ramas 3.2.x.

Intenté ese comando y, por supuesto, no funcionó.


11
git branch -D $(git branch | grep 3.2*)- Esto funcionó para mí. Elimina las ramas cuyo nombre comienza con "3.2". grep- coincidencia de patrones en la salida (de git branchen este caso). $()- significa ejecutar y colocar el resultado. |- encadenamiento
Eduard

44
A tener en cuenta para aquellos que no saben, que -Des una fuerza de eliminación, debe utilizar -den la mayoría de los casos a ser más seguro en primer lugar.
redfox05

Respuestas:


363

No con esa sintaxis. Pero puedes hacerlo así:

git branch -D 3.2 3.2.1 3.2.2

Básicamente, git branch eliminará múltiples sucursales para usted con una sola invocación. Lamentablemente, no completa el nombre de sucursal. Aunque, en bash, puedes hacer:

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

3
La finalización de git branch -D/-dfunciona bien para mí. Es posible que desee actualizar la suya (tal vez desde el directorio más reciente de git.git contrib).
Cascabel

19
En lugar de que git branch | ...puedas usar $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). Es más largo, lo sé, pero está garantizado que será un resultado adecuado, mientras que git branchtiene un resultado bastante bueno con cosas como *y ->(para symrefs) que pueden confundirlo en scripts / líneas simples.
Cascabel

3
Tal vez soy el único con este problema, pero he tenido el grepalias de incluir siempre la bandera --color=always, git branch -Dlancé error: branch 'my_branch' not found.hasta que corrí sin la bandera de color.
eebbesen

@eebbesen ¿Lo deshabilitó globalmente? Me encuentro con el mismo problema al ejecutargit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr

2
Con la expansión de llaves puede escribir git branch -D 3.2{,.1,.2}para eliminar las tres ramas gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck

147

Bueno, en el peor de los casos, podrías usar:

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

22
Este es prácticamente el método perfecto para cualquiera que use una notación de prefijo estandarizada para nombres de sucursal (por ejemplo, "arreglo / ..." o "característica / ...").
Haz

44
Simple y eficiente! Sin embargo, recomendaría ejecutar primero sin la | xargs git branch -dparte para verificar qué se va a eliminar realmente.
mathielo

Se recomienda no a grepla salida de git branch, ya que está destinado a leer, no a analizar. Podría cambiar en cualquier momento. use for-each-refjunto con los --formatparámetros, como se sugiere en otras respuestas, y luego combine con las sugerencias en esta respuesta.
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

EDITAR:

Una versión más segura (sugerida por Jakub Narębski y Jefromi), ya que la salida de git branch no está destinada a ser utilizada en scripts:

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

... o sin xargs:

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

14
No use la git branchsalida para las secuencias de comandos. Uso git for-each-ref.
Jakub Narębski

1
Para eliminar etiquetas con el símbolo @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt

Tiene un error tipográfico. Debe ser "/3.2/*" no "/3.2*". Además, parece que has copiado otras respuestas pegadas en la tuya.
Max MacLeod

No hay error tipográfico aquí. Desde la página de manual: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
A tener en cuenta para aquellos que no saben, que -Des una fuerza de eliminación, debe utilizar -den la mayoría de los casos a ser más seguro en primer lugar.
redfox05

115

Puede usar git branch --list para enumerar las ramas elegibles, y usar git branch -D / -d para eliminar las ramas elegibles.

Un ejemplo de línea:

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

Cuando intento esto, recibo un montón de mensajes de error como error: branch 'package.json' not found.. Parece que el * se expande demasiado pronto e intenta eliminar una rama correspondiente al nombre de cada archivo y directorio.
Antimonio

Esto funciona bien! Aunque tengo problemas para usar esto como un alias con gitconfig...
whomaniac

66
Esta respuesta debe ser más alta en la lista, super limpia, funciona, no grep
jemiloii

1
Es bueno que este sea fácil de probar primero simplemente emitiendogit branch --list '3.2.*'
Will

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

38

Recientemente, estaba buscando la solución del mismo problema, finalmente encontré una respuesta y está funcionando muy bien:

  1. Abra la terminal, o equivalente.
  2. Escriba git branch | grep "patrón" para obtener una vista previa de las ramas que se eliminarán.
  3. Escriba git branch | grep "patrón" | xargs git branch -D

Esta solución es increíble y si desea una explicación completa de cada comando y cómo está funcionando, se proporciona aquí .


28

Utilizar

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

77
Un pequeño consejo es que si elimina la última parte del comando "| xargs git branch -D", entonces solo generará las ramas coincidentes. Por lo tanto, puede obtener una vista previa de las ramas que se eliminarán
Max MacLeod

1
También agregué un alias para simplificar esto: alias grefs='git for-each-ref --format="%(refname:short)"'así puedo hacerlogrefs | grep 'regexpattern' | xargs git branch -D
angularsen

Me encantó. Agradable y simple!
Bhargav Ponnapalli

15

Tal vez le resulte útil:

Si desea eliminar todas las ramas que no son, por ejemplo, 'master', 'foo' y 'bar'

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

grep -v 'algo' es un emparejador con inversión.


Personalmente, me gusta la -Dopción en comparación con otra respuesta. Gracias por la respuesta aquí @Adi. Las soluciones me funcionan.
AMIC MING

9

Puse mis iniciales y un guión (at-) como los primeros tres caracteres del nombre de la rama por esta razón exacta:

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

Todas las respuestas básicamente dicen esto, esto resulta ser el más simple.
tfantina

7

Si no está limitado a usar el símbolo del sistema git, siempre puede ejecutar git guiy usar el elemento de menú Rama-> Eliminar. Seleccione todas las ramas que desea eliminar y deje que se rasgue.


sin embargo
Stealth Rabbi

7

Solución Powershell:

Si está ejecutando Windows, puede usar PowerShell para eliminar varias ramas a la vez ...

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.

También puede ajustar cómo debería funcionar la coincidencia de patrones con el comando Seleccionar cadena de Powershell. Echa un vistazo a los documentos de PowerShell .


6

Mantener "desarrollar" y eliminar todos los demás en local

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

5

Hice una pequeña función que podría ser útil en función de la respuesta proporcionada por @gawi (arriba).

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

Agregue eso a su .bash_profiley reinicie su terminal. Luego puede llamar desde la línea de comandos de esta manera:

removeBranchesWithPrefix somePrefix

Nota

Actualmente lo tengo configurado para una eliminación suave, lo que significa que no eliminará las ramas a menos que ya se hayan fusionado. Si te gusta vivir en el borde, el cambio -dde -Dy va a eliminar todo con el prefijo sin tener en cuenta!


5

Si realmente necesita limpiar todas sus ramas, intente

git branch -d $(git branch)

Eliminará todas sus sucursales locales fusionadas, excepto la que está registrando actualmente.

Es una buena manera de limpiar tu local


Esto funcionó bastante bien para mí. Dejó dos ramas excepto la que yo era una que luego eliminé usando el mismo comando pero usando una "-D" mayúscula en lugar de "-d". Recibí algunos errores acerca de que git no encuentra archivos, pero las ramas se eliminaron.
Lurifaxel

3

Puede que le guste este pequeño elemento ... Extrae la lista y solicita la confirmación de cada elemento antes de eliminar finalmente todas las selecciones ...

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`

Use -D para forzar eliminaciones (como de costumbre).

Para facilitar la lectura, aquí está esa línea dividida línea por línea ...

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`

aquí está el enfoque 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

finalmente, me gusta tener esto en mi .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'

De esa manera solo puedo decir

gitSelect | xargs git branch -D.

3

Para las almas puras que usan PowerShell aquí, el pequeño script git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })


2

funciona correctamente para mi:

git branch | xargs git branch -d

git branch | xargs git branch -D

eliminar todas las sucursales locales


2

Use el siguiente comando para eliminar todas las ramas (la rama desprotegida no se eliminará).

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

Editar: estoy usando un Mac Os


0

Si estás en Windows, puedes usar PowerShell para hacer esto:

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

reemplace feature/*con cualquier patrón que desee.


66
grep es un cmdlet no reconocido para mí ... así que he cambiado por esta rama git | donde {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} y funcionó!
Alex


0

Puede usar git guipara eliminar varias ramas a la vez. Desde Símbolo del sistema / Bash -> git gui-> Remoto -> Eliminar rama ... -> seleccione ramas remotas que desea eliminar -> Eliminar.


0

Hoy limpié un gran conjunto de sucursales locales / remotas obsoletas.

A continuación se muestra cómo lo hice:

1. enumere todos los nombres de las ramas en un archivo de texto:

git branch -a >> BranchNames.txt

2. agregue las ramas que quiero eliminar al comando "git branch -D -r":

git branch -D -r origin / dirA / branch01 origin / dirB / branch02 origin / dirC / branch03 (... agregue cualquier nombre de rama)

3. ejecutar el cmd

Y este funciona mucho más rápido y confiable que " git push origin --delete ".

Puede que esta no sea la forma más inteligente como se enumera en otras respuestas, pero esta es bastante sencilla y fácil de usar.


0

Si ha instalado Git GUI, que es un complemento predeterminado para Windows, entonces es el más simple. Puede usar ctrl para elegir varias ramas y eliminarlas con un solo clic.


0

Si está utilizando Fish Shell, puede aprovechar las stringfunciones :

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

Esto no es muy diferente de las opciones de Powershell en algunas de las otras respuestas.


0

Si tuviera que eliminar todas las ramas en un archivo de texto (sucursales a del.txt) (una rama por línea), podría hacer esto para eliminar todas las ramas del control remoto (origen): xargs -a branches-to-del.txt git push --delete origin


0

Para eliminar varias ramas en función de un patrón especificado, haga lo siguiente:

Abra el terminal o equivalente y escriba los siguientes comandos:

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)

Elimine todas las ramas 3.2.x, debe escribir

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

¡Eso es todo!

tú eres bueno para irte.


-1

Como en Git, todas las ramas no son nada por referencias al repositorio de git, ¿por qué no eliminas las ramas que van .git/refy luego, si queda algo fuera que no sea interesante en el repositorio, automáticamente se recolectará basura para que no lo hagas? Necesito molestar.



-4

Puede eliminar todas las ramas eliminando todas las referencias innecesarias:

rm .git/refs/heads/3.2.*


2
Votado en contra por dos razones: 1. utiliza un detalle de implementación (el hecho de que las versiones actuales de Git almacenan las ramas como archivos en un determinado directorio). Esto puede cambiar en futuras versiones, haciendo que la respuesta sea inválida. 2. No funciona si el repositorio se encuentra en un directorio separado .
axiac

Además, esto produce resultados muy inesperados si ejecuta esto en un repositorio empaquetado ( git gc). No hagas eso.
Matthieu Moy
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.