Ir al contenido principal

Mantener Git limpio

Si has utilizado git de manera habitual estarás familiarizado con los repositorios con miles de ramas ya mergeadas, tanto en local como en el repositorio remoto.

Esto hace que por ejemplo cuando quieras hacer un merge request sea muy pesado buscar la rama que quieres mergear.

En esta tarea nos propusimos revisar como hacer una limpieza automática.

Como aún le estamos quitando el polvo a nuestra nueva mascota, drone (os podéis logar con los credenciales de gitea), pensamos que estaría bien que un paso de la integración continua fuese el limpiar las ramas mergeadas.

Nos pusimos manos a la obra, hicimos un docker para que drone lo lanzase durante este paso. Este tenía git y ssh ya que como es un proceso automático no se podía clonar con credenciales https.

Por lo tanto el docker cogía la clave ssh de unos secretos de drone para hacer el pull y el push necesario para borrar las ramas. No obstante por problemas de conectividad no terminó de funcionar. Además de que habría que dar manualmente permiso al usuario de gitea de integración continua a cada repositorio para que este pudiese modificar el repositorio.

Ello hizo que desechasemos a priori esta aproximación. Lo siguiente que pensamos fue hacer un cron job que borrase localmente las ramas mergeadas en el servidor donde tenemos gitea. El problema es que la información almacenada son repositorios git bare, no lo que ven los clientes, por lo tanto todas las herramientas o comandos de limpieza fallaban.

Por último se nos ocurrió que lo más fácil era instalar un hook de git en los clientes. Como es pesado agregar el hook en cada repositorio que utilicemos se pueden establecer hooks genéricos para todos los repositorios con el siguiente comando:

git config --global core.hooksPath /path/to/hooks

Donde /path/to/hooks/ puede ser ~/.git/hooks. La desventaja de esta medida es que se desactivan los hooks de los repositorios en particular, a no ser que los actives manualmente (y entonces no funcionarán los globales).

Utilizaremos el hook post-merge que se dispara cuando tras hace run git pull hay alguna rama que se ha mergeado.

Dentro de este script podemos poner cualquier script nosotros utilizaremos dos herramientas git-sweep y git-extras para instalarlas haremos:

pip install --user git-sweep
sudo apt-get install git-extras

git-sweep es un programa para borrar ramas mergeadas en remoto, y utilizaremos el comando git delete-merged-branches de git-extras para borrar las ramas en local.

Por lo tanto el archivo ~/.git/hooks/post-merge quedará como:

#!/bin/sh

git-sweep cleanup --force
git delete-merged-branches

Por lo que vemos, la ñapa es bastante fea. Ya va siendo hora de que esta "feature" tan necesaria esté integrada en los gestores de git como gitea o gitlab.