¿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ó.

Doug
fuente
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\..*'`
slebetman
fuente
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
Carl Norum
fuente
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\*`
gawi
fuente
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.*'`
50shadesofbae
fuente
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í .

KJ Gor
fuente
28

Utilizar

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Jakub Narębski
fuente
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.

Adi
fuente
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-*'`
Alan Tweedie
fuente
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.

Efpophis
fuente
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 .

Imtiaz Shakil Siddique
fuente
6

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

    git branch | grep -v "develop" | xargs git branch -D 
Daniel
fuente
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!

Logan
fuente
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

Yulin
fuente
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.
Crafter del Caos
fuente
3

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

codevision
fuente
2

funciona correctamente para mi:

git branch | xargs git branch -d

git branch | xargs git branch -D

eliminar todas las sucursales locales

velastiqui
fuente
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

ILYAS_Kerbal
fuente
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.

Mo Valipour
fuente
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.

Terry Truong
fuente
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.

RainCast
fuente
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.

peiz
fuente
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.

mdiin
fuente
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

code4kix
fuente
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.

Ankit Jindal
fuente
-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.

Debajit
fuente
-3

git branch -D <branchName>

Aakash Pahuja
fuente
-4

Puede eliminar todas las ramas eliminando todas las referencias innecesarias:

rm .git/refs/heads/3.2.*

Artur Owczarek
fuente
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