Con git remote prune origin
puedo eliminar las ramas locales que ya no están en el control remoto.
Pero también quiero eliminar las ramas locales que se crearon a partir de esas ramas remotas (sería bueno verificar si están sin fusionar).
¿Cómo puedo hacer esto?
npx git-removed-branches
(funcionamiento en seco) onpx git-removed-branches --prune
(de verdad). Necesitas tener ya instalado node.js. Vea las respuestas a continuación para más detalles.Respuestas:
Después de la poda, puede obtener la lista de ramas remotas con
git branch -r
. La lista de ramas con su rama de seguimiento remoto se puede recuperar congit branch -vv
. Entonces, utilizando estas dos listas, puede encontrar las ramas de seguimiento remoto que no están en la lista de controles remotos.Esta línea debería hacer el truco (requiere
bash
ozsh
no funcionará con el shell Bourne estándar):git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
Esta cadena obtiene la lista de ramas remotas y la pasa a
egrep
través de la entrada estándar. Y filtra las ramas que tienen una rama de seguimiento remota (usandogit branch -vv
y filtrando las que tienenorigin
) y luego obtiene la primera columna de esa salida, que será el nombre de la rama. Finalmente pasando todos los nombres de rama en el comando borrar rama.Como está utilizando la
-d
opción, no eliminará las ramas que no se han fusionado en la rama en la que se encuentra cuando ejecuta este comando.También recuerde que
git fetch --prune
primero deberá ejecutarlo , de lo contrariogit branch -r
aún verá las ramas remotas.fuente
git fetch -p
¿no siempre es suficiente?sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required
¿Algunas ideas?alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
git branch -D
al final del comando funcionó mejor para nosotros, ya que tendemos a aplastar las confirmaciones al fusionar, lo que nosThe branch x is not fully merged
genera errores al ejecutar con-d
.Si desea eliminar todas las sucursales locales que ya están fusionadas en master, puede usar el siguiente comando:
Más información .
fuente
xargs -r git branch -d
para que no se ejecute nada si no hay ramas para eliminar. Tenga en cuenta que la-r
bandera puede no estar disponible en todas partesgit branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
git branch --merged master
enumera las ramas que se fusionan en master, luego la parte grep del medio excluye al master en sí mismo (¡no queremos eliminar master!), Y la última parte xargs se ejecutagit branch -d
(eliminar branch) en cada una Los resultados. O simplemente puede leer el enlace Más información proporcionado en la respuesta;)git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d
. La salida de git v2.10.1 mostrará "* master" cuando master esté desprotegido. Me deshago del maestro con o sin asterisco.En medio de la información presentada por
git help fetch
, hay este pequeño artículo:Así que tal vez,
git fetch -p
¿es lo que estás buscando?EDITAR: Ok, para aquellos que aún debaten esta respuesta 3 años después del hecho, aquí hay un poco más de información sobre por qué presenté esta respuesta ...
Primero, el OP dice que quieren "eliminar también aquellas ramas locales que se crearon a partir de esas ramas remotas [que ya no están en el remoto]". Esto no es inequívocamente posible en
git
. Aquí hay un ejemplo.Digamos que tengo un repositorio en un servidor central, y tiene dos ramas, llamadas
A
yB
. Si clono ese repositorio en mi sistema local, mi clon tendrá referencias locales (aún no ramas reales) llamadasorigin/A
yorigin/B
. Ahora digamos que hago lo siguiente:Los hechos pertinentes aquí son que por alguna razón elegí crear una sucursal en mi repositorio local que tenga un nombre diferente a su origen, y también tengo una sucursal local que (todavía) no existe en el repositorio de origen.
Ahora supongamos que elimino las ramas
A
yB
en el repositorio remoto y actualizo mi repositorio local (git fetch
de alguna forma), lo que hace que mis referencias localesorigin/A
yorigin/B
desaparezcan. Ahora, mi repo local tiene tres ramas todavía,A
,Z
, yC
. Ninguno de estos tiene una rama correspondiente en el repositorio remoto. Dos de ellos fueron "creados a partir de ... ramas remotas", pero incluso si sé que solía haber una rama llamadaB
en el origen, no tengo forma de saber queZ
se creó a partir deB
, porque fue renombrado en el proceso, probablemente por una buena razón. Entonces, realmente, sin algún proceso externo que registre metadatos de origen de rama, o un ser humano que conozca la historia, es imposible saber cuál de las tres ramas, si es que hay alguna, el OP está apuntando para su eliminación. Sin cierta información externa quegit
no se mantiene automáticamente para usted,git fetch -p
es lo más cercano posible, y cualquier método automático para intentar literalmente lo que solicitó el OP corre el riesgo de eliminar demasiadas ramas o de perder algunas que el OP de otro modo quiere eliminarTambién hay otros escenarios, como si creo tres ramas separadas
origin/A
para probar tres enfoques diferentes de algo, y luegoorigin/A
desaparece. Ahora tengo tres ramas, que obviamente no pueden coincidir con el nombre, pero se crearon a partir de ellasorigin/A
, por lo que una interpretación literal de la pregunta de los OP requeriría eliminar las tres. Sin embargo, eso puede no ser deseable, si incluso pudiera encontrar una forma confiable de combinarlos ...fuente
Esto eliminará las ramas locales para las que se han podado las ramas de seguimiento remoto. (¡Asegúrate de estar en la
master
rama!)Detalles:
git branch -vv
muestra "desaparecido" para las sucursales locales que el control remoto ha sido podado.-d
comprobará si se ha fusionado (-D
lo eliminará independientemente)fuente
git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
git branch -d
compara las ramas conHEAD
.prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
Se puede configurar Git para eliminar automáticamente las referencias a las ramas remotas eliminadas al buscar:
Al llamar
git fetch
ogit pull
después, las referencias a sucursales remotas eliminadas se eliminan automáticamente.fuente
git branch -r
.Hay un paquete ordenado de NPM que lo hace por usted (y debería funcionar multiplataforma).
Instalarlo con:
npm install -g git-removed-branches
Y luego
git removed-branches
le mostrará todas las ramas locales obsoletas, ygit removed-branches --prune
eliminarlas realmente.Más información aquí.
fuente
npx git-removed-branches
Funciona como un sueño.Solución de Windows
Para Microsoft Windows Powershell:
git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Explicación
git checkout master
cambia a la rama maestragit remote update origin --prune
ciruelas pasas ramas remotasgit branch -vv
obtiene una salida detallada de todas las ramas ( referencia de git )Select-String -Pattern ": gone]"
obtiene solo los registros donde se han eliminado del control remoto.% { $_.toString().Split(" ")[0]}
obtener el nombre de la sucursal% {git branch -d $_}
elimina la ramafuente
git remote prune origin
, también, select-string no parece coincidir con la última versión de git. Considere usarConvertFrom-String -TemplateContent
git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Enumerará las ramas locales cuya rama de seguimiento remoto se elimina de
Si desea desreferenciar estas ramas locales de las locales que no se rastrean
fuente
Como señala @tzacks ... hay un paquete npm que es útil para esto. Solo haz:
(Hubiera comentado pero no suficiente reputación)
fuente
Si usa Windows y Powershell, puede usar lo siguiente para eliminar todas las ramas locales que se han fusionado en la rama actualmente desprotegida:
Explicación
git
salida para cada nombre de rama restanteVale la pena ejecutarlo
git branch --merged
solo primero para asegurarse de que solo eliminará lo que espera.(Portado / automatizado de http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/ .)
fuente
Una línea más corta y segura:
Asegúrese de pagar a la rama que aún no está fusionada, antes de ejecutarla. Porque no puede eliminar la rama en la que está registrado actualmente.
fuente
git branch -d $(git branch --merged | cut -c 3- | grep -v master)
Quería algo que purgara todas las sucursales locales que estaban rastreando una rama remota, en
origin
, donde se ha eliminado la rama remota (gone
). No quería eliminar ramas locales que nunca se configuraron para rastrear una rama remota (es decir, mis ramas de desarrollo local). Además, quería una línea simple que solo usegit
, u otras herramientas simples de CLI, en lugar de escribir scripts personalizados. Terminé usando un poco degrep
yawk
para hacer este comando simple, luego lo agregué como un alias en mi~/.gitconfig
.Aquí hay un
git config --global ...
comando para agregar esto fácilmente comogit prune-branches
:NOTA: El uso de la
-D
banderagit branch
puede ser muy peligroso. Entonces, en el comando de configuración anterior, uso la-d
opción paragit branch
lugar de-D
; Yo uso-D
en mi configuración actual. Lo uso-D
porque no quiero escuchar a Git quejarse de ramas no fusionadas, solo quiero que se vayan. Es posible que también desee esta funcionalidad. Si es así, simplemente use en-D
lugar de-d
al final de ese comando de configuración.fuente
Para eliminar ramas remotas:
Para eliminar sucursales locales que ya están fusionadas:
fuente
No parece haber una línea segura, demasiados casos extremos (como una rama que tiene "maestro" como parte de su nombre, etc.). Lo más seguro es estos pasos:
git branch -vv | grep 'gone]' > stale_branches.txt
awk '{print $1}' stale_branches.txt | xargs git branch -d
fuente
Según las respuestas anteriores, estoy usando este revestimiento más corto:
Además, si ya podaste y tienes ramas colgantes locales, entonces esto las limpiará:
fuente
/
en ellosNo estoy seguro de cómo hacerlo todo a la vez, pero git
git branch -d <branchname>
eliminará una rama local SOLAMENTE si está completamente combinada. Tenga en cuenta las minúsculas d.git branch -D <branchname>
(tenga en cuenta que la D mayúscula) eliminará una sucursal local independientemente de su estado combinado.fuente
Puedes usar este comando:
Git Clean: Eliminar ramas ya fusionadas, incluido el desglose del comando
fuente
Basado en las respuestas anteriores, vine con esta solución de una línea:
fuente
Usando una variante en la respuesta de @ wisbucky, agregué lo siguiente como un alias a mi
~/.gitconfig
archivo:Con esto, un simple
git pruneitgood
limpiará las sucursales locales y remotas que ya no son necesarias después de las fusiones.fuente
La versión Powershell de
git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d
git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}
Esto eliminará cualquier sucursal local que se haya fusionado en maestra, mientras usted esté en la sucursal maestra .
git checkout master
para cambiarfuente
La variante de Schleis no funciona para mí (Ubuntu 12.04), así que permítanme proponer mis variantes (claras y brillantes :):
Variante 1 (preferiría esta opción):
Variante 2:
a. Funcionamiento en seco:
si. Eliminar ramas:
fuente
La siguiente es una adaptación de la respuesta de @ wisbucky para los usuarios de Windows:
for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d
Uso posh-git y desafortunadamente a PS no le gusta el desnudo
for
, así que creé un script de comando simple llamado PruneOrphanBranches.cmd:Llámelo sin parámetros para ver una lista y luego llámelo con "-d" para realizar la eliminación real o "-D" para cualquier rama que no esté completamente fusionada pero que quiera eliminar de todos modos.
fuente
:
o:
(con un espacio)findstr
hizo que coincidiera con todo cada vez, casi borré el master. Sin embargo, usar una expresión regular funcionó bien:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
Pruebe esto en git bash, para buscar y podar referencias a ramas eliminadas, y luego pode las ramas locales que estaban rastreando las eliminadas:
Recuerde verificar primero una rama que no se eliminará, para que no bloquee la eliminación de la rama.
fuente
He convertido la respuesta aceptada en un guión robusto. Lo encontrarás en mi repositorio de git-extensions .
fuente
Llegué a esta página buscando la respuesta para "¿cómo elimino sucursales localmente desprotegidas que ya no tienen una sucursal ascendente?"
Tampoco me importaba si la sucursal local se había fusionado o no todavía, ya que la tubería
git branch -d
simplemente advertirá en lugar de eliminar sucursales locales no fusionadas .fuente
En Powershell :
fuente
Aquí está mi solución:
-p es eliminar cualquier referencia de seguimiento remoto que ya no exista en el control remoto. Entonces, el primer paso eliminará las referencias a ramas remotas.
-vv es para mostrar la línea de asunto sha1 y commit para cada encabezado, junto con la relación con la rama ascendente (si la hay). El segundo paso obtendrá todas las ramas locales y el comando grep filtrará las ramas que se han eliminado.
fuente
git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
Eliminar cualquier rama que no esté actualizada con master
fuente
Estoy bastante seguro de que eso
git remote prune origin
es lo que quieres.Puede ejecutarlo
git remote prune origin --dry-run
para ver qué haría sin realizar ningún cambio.fuente
¿Usando la GUI? Procedimiento manual, pero rápido y fácil.
Seleccione "Rama -> Eliminar". Puede seleccionar múltiples ramas con Ctrl-clic (Windows) y eliminarlas todas.
fuente