- Se descubrió un comando simple para resolver el antiguo problema de limpiar ramas de Git en documentos internos de desarrollo de la CIA
git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d
- El comando elimina en lote las ramas fusionadas del resultado de
git branch --merged, excepto la rama actual y master
- También existe una versión modificada para proyectos modernos que excluye las ramas
main y develop
- Puede registrarse como alias de Git para automatizar tareas repetitivas, y es una herramienta útil para mejorar de forma constante la eficiencia del trabajo y mantener limpio el repositorio
Un tip de Git encontrado en Vault7
- Los documentos Vault7 publicados por WikiLeaks en 2017 incluían herramientas de hacking de la CIA y documentación interna de desarrollo
- Entre ellos había una página con una colección de tips y trucos de Git, y la mayoría eran usos comunes como modificar commits, usar stash o bisect
- El comando de una sola línea encontrado en ese documento ha permanecido en mi
~/.zshrc hasta hoy
El problema de limpiar ramas viejas
- En los repositorios locales de Git, con el tiempo se acumulan ramas fusionadas, lo que dificulta mantener todo ordenado
- Ramas de funcionalidades, hotfixes y ramas experimentales siguen quedándose después de fusionarse, haciendo que la lista de
git branch se vuelva complicada
- Con el comando
git branch --merged se pueden ver las ramas fusionadas, pero borrarlas manualmente es tedioso
El comando original del documento de la CIA
Versión modernizada del comando
- Como la mayoría de los proyectos usan la rama
main, el comando puede modificarse así
git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d
- Si se ejecuta en la rama
main después de desplegar, decenas de ramas pueden reducirse a solo unas pocas
- También puede registrarse como alias de Git para ejecutarlo más fácilmente
alias ciaclean='git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d'
- Después, solo hace falta escribir
ciaclean en el repositorio para realizar la limpieza automáticamente
Eficiencia y practicidad
- Este comando ayuda a ahorrar unos minutos cada semana y a mantener ordenada la lista de ramas
- Se considera una herramienta práctica que, aunque simple, ofrece una mejora continua de la productividad
4 comentarios
Entre los comentarios de HN, hay alguien que dice que usa un programa que hice yo.
> Yo uso git-trim para eso:
> https://github.com/foriequal0/git-trim
> El Readme también explica por qué en algunos casos es mejor que un bash-oneliner.
> https://news.ycombinator.com/item?id=47089533
Yo también tengo configurado un alias llamado
git gone. Es muy práctico- alias.gone = ! git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git branch -D
Yo no uso git puro, pero hago la limpieza con una herramienta llamada gh-poi.
https://github.com/seachicken/gh-poi
Opiniones en Hacker News
Yo uso un alias llamado
git tidypara limpiar ramasNo borra la rama base (
main,master), ni toca la rama actual ni las ramas de otros worktreeTambién elimina automáticamente las ramas que desaparecieron del remoto, y el código está en mi configuración de dotfiles
init.defaultBranches riesgoso. El nombre de la rama base puede variar según el repositorio, y esa configuración es global, así que hay que definirla de antemanoYo hice un alias llamado
git defaultpara detectar automáticamente la rama base real desde el remoto (origin)Yo uso un comando de cleanup integrado con
fzfPermite seleccionar de antemano las ramas ya fusionadas para borrarlas de una vez, y si quieres también puedes excluir algunas
También limpia las ramas remotas, y el código está en mi configuración de .gitconfig
Además uso la variable
user.primaryBranchpara definir una rama base distinta según el repositorioinit.defaultBranchen su lugar. Incluso en repositorios ya inicializados funciona si configurasgit config --local init.defaultBranch mainpulldesde otra rama sin cambiarse a ella. Por ejemplo,git pull origin main:mainy luegogit rebase maingit branch --mergedno funciona bien en repositorios que usan squash mergeEso pasa porque el SHA del commit squash no coincide con el HEAD original de la rama
Me interesa saber si existe alguna herramienta para detectar con seguridad ramas ya integradas mediante squash
No es perfecto, pero es bastante práctico, y siempre muestra una confirmación antes de borrar
Tomé como referencia la configuración de borrado automático de ramas de GitHub
La mayoría lo resuelve enganchándose al evento de borrado de la rama remota
Uso un alias llamado
git goneque hacegit fetch -py luego limpia las ramas con estado[gone]Por eso uso un script que combina
git branch --merged,git cherryygit log grepAun así, puede dar falsos positivos si hubo
amenden commits o si hay varios commitsYo limpio ramas fusionadas con un alias llamado
git lintExcluye
main,masterystable, y borra el resto. Uso bastante la combinacióngit pull --prune && git lintEl comando de Git en sí es normal, pero me pareció curioso haber llegado a un documento con fuente en Wikileaks por estar haciendo clic
El proyecto “Fine Dining” de la CIA era una herramienta para disfrazar malware oculto en un USB como si fuera una app
En realidad, el problema original también se podía resolver simplemente imprimiendo la lista de ramas no fusionadas
Se siente raro que una tarea tan natural necesite varias líneas de bash
Da pena que, con un código base tan grande como el de Git, esto no venga como funcionalidad incorporada
También mencionan este post relacionado
xargso de los loopsfor, esto es algo trivialSi se hiciera como comando incorporado, habría que manejar muchos casos borde y podría terminar siendo más complejo
Al final también hubo reacciones del tipo “parece alguien que recién aprendió
xargs”Yo también aprendí cosas así antes por blogs o textos
xargs, eso ya es genialÚltimamente ando obsesionado con las TUI. Si algo me incomoda, le pido a Claude-code que me haga una TUI
Usando la librería Textual hice una TUI para administrar Git worktree, y Claude maneja bastante bien el código en Python
tig, una TUI antigua para Git. Incluso sirve para sacar ideasVale la pena ver este artículo sobre la función de rebase en Magit
Yo hice algo parecido en Fish shell
Es una función para seleccionar con
fzfy borrar ramas que ya desaparecieron del remotoEstá en mi código de dotfiles