Normalmente no respondería una pregunta que ya tiene 16 respuestas, pero todas las demás respuestas son incorrectas, y la respuesta correcta es muy simple. La pregunta dice: "¿Hay una manera simple de eliminar todas las ramas de seguimiento cuyo equivalente remoto ya no existe?"
Si "simple" significa eliminarlos de una vez, no son frágiles, no son peligrosos y no dependen de herramientas que no todos los lectores tendrán, entonces la respuesta correcta es: no.
Algunas respuestas son simples, pero no hacen lo que se les pidió. Otros hacen lo que se les pidió, pero no son simples: todos confían en analizar la salida de Git a través de comandos de manipulación de texto o lenguajes de script, que pueden no estar presentes en todos los sistemas. Además de eso, la mayoría de las sugerencias usan comandos de porcelana, cuya salida no está diseñada para ser analizada por script ("porcelain" se refiere a los comandos destinados a la operación humana; los scripts deben usar los comandos de "plomería" de nivel inferior).
Otras lecturas:
Si desea hacer esto de forma segura, para el caso de uso en la pregunta (ramas de seguimiento de recolección de basura que se han eliminado en el servidor pero que todavía existen como ramas locales) y solo con comandos Git de alto nivel, debe
git fetch --prune
(o git fetch -p
, que es un alias, o git prune remote origin
que hace lo mismo sin buscar, y probablemente no es lo que quieres la mayor parte del tiempo).
- Tenga en cuenta las ramas remotas que se informan como eliminadas. O, para encontrarlos más adelante,
git branch -v
(cualquier rama de seguimiento huérfana se marcará "[desaparecido]").
git branch -d [branch_name]
en cada rama de seguimiento huérfana
(que es lo que proponen algunas de las otras respuestas).
Si desea escribir una solución, entonces for-each-ref
es su punto de partida, como en la respuesta de Mark Longair aquí y esta respuesta a otra pregunta , pero no puedo ver una manera de explotarla sin escribir un bucle de script de shell, o usar xargs o algo .
Explicación de fondo
Para comprender lo que está sucediendo, debe apreciar que, en la situación de rastrear sucursales, no tiene una, sino tres. (Y recuerde que "rama" significa simplemente un puntero a una confirmación).
Dada una rama de seguimiento feature/X
, el repositorio remoto (servidor) tendrá esta rama y la llamará feature/X
. Su repositorio local tiene una rama remotes/origin/feature/X
que significa: "Esto es lo que el control remoto me dijo que era su característica / rama X, la última vez que hablamos", y finalmente, el repositorio local tiene una rama feature/X
que apunta a su último commit y está configurado para "seguimiento" remotes/origin/feature/X
, lo que significa que puede tirar y empujar para mantenerlos alineados.
En algún momento, alguien ha eliminado el feature/X
en el control remoto. A partir de ese momento, te quedarás con tu local feature/X
(que probablemente ya no quieras más, ya que presumiblemente el trabajo en la función X está presumiblemente terminado), y tu remotes/origin/feature/X
que sin duda es inútil porque su único propósito era recordar el estado de la rama del servidor .
Y Git le permitirá limpiar automáticamente el redundante remotes/origin/feature/X
, eso es lo que git fetch --prune
hace, pero por alguna razón, no le permite eliminar automáticamente el suyo feature/X
... a pesar de que feature/X
todavía contiene la información de seguimiento huérfana, por lo que tiene la información para identificar antiguas ramas de seguimiento que se han fusionado completamente. (Después de todo, se puede dar que la información que le permite hacer la operación por sí mismo la mano.)
* master
en mi sistema. El siguiente comando funcionó para mí:git branch -d $(git branch --merged |tail -n +2)