Los hooks de git son scripts que podemos definir en nuestro repositorio para que se disparen cuando git realiza una acción. Creo que se trata de una feature de git bastante olvidada por la gran mayoría de developers y muy desaprovechada. Como técnicos debemos procurar eliminar tareas repetitivas en nuestro workflow y ultimamente por una casuística en el trabajo me he decidido a investigar un poco más los hooks de git.

En mi caso estoy realizando varias webapps usando Backbone.js, Marionette y RequireJs. Require tiene una serie de herramientas para optimizar nuestro código que incluyen minificado de Javascript y CSS, limpieza de comentarios, ofuscación de código... que debemos lanzar antes de comitear/pushear. Además nosotros hemos añadido alguna feature más a este script como la generación de arrays de traducciones.

Los casos de uso de los hooks son infinitos: compilar coffeescript a js (aunque se puede hacer con grunt por ejemplo), limpiar la caché cuando hacemos un pull o cambiamos de branch, optimizar el autoloading al hacer push, integrar git con un sistema de gestión de proyectos como JIRA o Redmine, etc.

Git hooks

Como comentaba, los git hooks son simplemente scripts que git ejecuta cuando pasa un determinado evento. Los eventos que git proporciona por defecto son:

  • applypatch-msg
  • pre-applypatch
  • post-applypath
  • pre-commit
  • prepare-commit-msg
  • post-commit
  • pre-rebase
  • post-checkout
  • post-merge
  • pre-recieve
  • update
  • post-recieve
  • post-update
  • pre-auto-gc
  • post-rewrite

Para más información podéis consultar la documentación oficial, pero con los nombres os podéis hacer una idea

Para ilustrar su uso vamos a generar un hook para que artisan me borre la caché y composer me optimice el autoload cuando cambio de branch, mergeo o hago pull de nuevos cambios. Como todos los pulls que introducen cambios incluyen un merge podemos simplificarlo a borrar caché y optimizar en los checkouts y los merges.

$ cd .git/hooks
$ mv post-checkout.sample post-checkout
$ chmod +x post-update
$ vim post-checkout

Borramos el contenido del archivo e incluimos lo siguiente:

#!/bin/bash

echo "---CLEARING CACHE---"
php artisan cache:clear

echo "---OPTIMIZE AUTOLOAD---"
composer dump-autoload --optimize

Para el archivo post-merge dentro del directorio hooks deberíamos hacer lo mismo. En este caso limpiar la caché y optimizar son dos simples comandos, pero a veces no será así... vamos a refactorizar para hacerlo más reutilizable y tenerlo más organizado.

Volvemos al root de nuestro proyecto y creamos una carpeta para nuestros scripts.

$ mkdir scripts && cd scripts
$ vim clear_cache

En este archivo incluimos nuestro código para limpiar caché:

#!/bin/bash

echo "---CLEARING CACHE---"
php artisan cache:clear

Creamos nuestro fichero optimize y hacemos lo propio

#!/bin/bash

echo "---OPTIMIZE AUTOLOAD---"
composer dump-autoload --optimize

Les damos permisos de ejecución con:

$ chmod +x optimize clear_cache

Ahora debemos modificar nuestros hooks para que queden así:

#!/bin/bash

. scripts/clear_cache
. scripts/optimize

Como veis se trata de una herramienta bastante potente. ¿Qué más casos se os ocurren donde podríais usar un hook de git?