Limpiar viejas ramas remotas de git

Resuelto Jayesh asked hace 14 años • 10 respuestas

Trabajo desde dos computadoras diferentes (A y B) y almaceno un control remoto git común en el directorio de Dropbox.

Digamos que tengo dos ramas, master y devel. Ambos están rastreando a sus contrapartes remotas origen/maestro y origen/desarrollo.

Ahora, mientras estoy en la computadora A, elimino el desarrollo de la rama, en local y remoto.

git push origin :heads/devel
git branch -d devel

Al ejecutarlo git branch -aen la computadora A, obtengo la siguiente lista de sucursales.

  • maestro
  • origen/CABEZA
  • origen/maestro

Al ejecutar git fetchen la computadora B, puedo eliminar la rama de desarrollo local con git branch -d devel, pero no puedo eliminar la rama de desarrollo remoto.

git push origin :heads/develdevuelve los siguientes mensajes de error.

error: no se puede enviar a un destino no calificado: heads/proxy3d
La especificación de referencia de destino no coincide con una referencia existente en el control remoto ni comienza con refs/, y no podemos adivinar un prefijo basado en la referencia de origen.
fatal: el extremo remoto se colgó inesperadamente

git branch -atodavía enumera origen/desarrollo en las ramas remotas.

¿Cómo puedo limpiar las ramas remotas de la computadora B?

Jayesh avatar Jul 06 '10 15:07 Jayesh
Aceptado

Primero, ¿cuál es el resultado de git branch -aen la máquina B?

heads/develEn segundo lugar, ya lo ha eliminado origin, por eso no puede eliminarlo de la máquina B.

Intentar

git branch -r -d origin/devel

o

git remote prune origin

o

git fetch origin --prune

y siéntase libre de agregarlo --dry-runal final de su gitdeclaración para ver el resultado de ejecutarlo sin ejecutarlo realmente.

Documentos para git remote pruney git branch.

Jakub Narębski avatar Jul 06 '2010 08:07 Jakub Narębski

Considere ejecutar:

git fetch --prune

De forma regular en cada repositorio para eliminar las sucursales locales que han estado rastreando una sucursal remota que se elimina (ya no existe en el repositorio GIT remoto).

Esto se puede simplificar aún más mediante

git config remote.origin.prune true

Esta es una per-repoconfiguración que hará que cualquier futuro se podegit fetch or git pull automáticamente .

Para configurar esto para su usuario, también puede editar el .gitconfig global y agregar

[fetch]
    prune = true

Sin embargo, se recomienda que esto se haga usando el siguiente comando:

git config --global fetch.prune true

o aplicarlo en todo el sistema (no solo para el usuario)

git config --system fetch.prune true
Arif avatar May 23 '2017 08:05 Arif

Tendré que agregar una respuesta aquí, porque las otras respuestas no cubren mi caso o son innecesariamente complicadas. Utilizo github con otros desarrolladores y solo quiero que todas las sucursales locales cuyos controles remotos fueron (posiblemente fusionados y) eliminados de un PR de github se eliminen de una sola vez de mi máquina. No, cosas como git branch -r --mergedno cubren las sucursales que no se fusionaron localmente, o las que no se fusionaron en absoluto (abandonadas), etc., por lo que se necesita una solución diferente.

De todos modos, el primer paso lo obtuve de otras respuestas:

git fetch --prune

Parecía que un ensayo git remote prune originharía lo mismo en mi caso, así que elegí la versión más corta para mantenerlo simple.

Ahora, se git branch -vdeben marcar las ramas cuyos controles remotos se eliminan como [gone]. Por lo tanto, todo lo que necesito hacer es:

git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}

Tan simple como eso, elimina todo lo que quiero para el escenario anterior.

La xargssintaxis menos común es que también funcione en Mac y BSD además de Linux. Cuidado, este comando no es un ensayo, por lo que forzará la eliminación de todas las ramas marcadas como [gone]. Obviamente, al ser git nada desaparece para siempre, si ves ramas eliminadas que recuerdas que querías conservar, siempre puedes recuperarlas (el comando anterior habrá enumerado su hash al eliminarlas, por lo que un simple archivo git checkout -b <branch> <hash>.

Editar: simplemente agregue este alias a su .bashrc/.bash_profile, los dos comandos se convirtieron en uno y actualicé el segundo para que funcione en todos los shells:

alias old_branch_delete='git fetch -p && git branch -vv | awk "/: gone]/{print \$1}" | xargs git branch -D'
Ecuador avatar Feb 07 '2019 16:02 Ecuador

Este comando eliminará mediante una "ejecución de prueba" todas las originramas remotas ( ) fusionadas, excepto master. Puede cambiar eso o agregar ramas adicionales después de master:grep -v for-example-your-branch-here |

git branch -r --merged | 
  grep origin | 
  grep -v '>' | 
  grep -v master | 
  xargs -L1 | 
  awk '{sub(/origin\//,"");print}'| 
  xargs git push origin --delete --dry-run

Si se ve bien, retire el --dry-run. Además, es posible que desees probar esto primero en un tenedor.

weston avatar Oct 24 '2016 19:10 weston

Aquí hay un script bash que puede hacerlo por usted. Es una versión modificada del script http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git . Mi modificación le permite admitir diferentes ubicaciones remotas.

#!/bin/bash

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
  echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching merged branches...\n"

git remote update --prune
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
  echo "No existing branches have been merged into $current_branch."
else
  echo "This will remove the following branches:"
  if [ -n "$remote_branches" ]; then
echo "$remote_branches"
  fi
  if [ -n "$local_branches" ]; then
echo "$local_branches"
  fi
  read -p "Continue? (y/n): " -n 1 choice
  echo
  if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`
# Remove remote branches
for remote in $remotes
do
        branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`
        git push $remote $branches 
done

# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
  else
echo "No branches removed."
  fi
fi
 avatar Mar 16 '2012 14:03