post thumbnail

Git desde Cero: Git hooks.

Publicado Por: Alberto Grespan, El 19/09/2013


Detalles del Curso:

Dificultad: Heroe

Duración: 20 min


Hemos habilitado un repo en GitHub para que puedas descargar el código de esta entrada:

Échale un vistazo aquí.

Bienvenidos a un nuevo capítulo de Git desde cero en este curso hablaremos sobre algunos de los "hooks" (ganchos) más populares que tiene git.


¿Qué son git hooks?

Como se habrán dado cuenta a lo largo de toda esta serie, git tiene una innumerable cantidad de funciones. Los "hooks" o ganchos son otras de estas tantas funciones extremadamente útiles pero poco utilizadas por muchos de nosotros. Los "hooks" son un conjunto de acciones que se ejecutan antes o después de un comando particular de git, es decir, si estamos utilizando un "pre-commit hook" se ejecutará una acción antes de realizar el "commit", si dicha acción realizada antes del "commit" tiene una respuesta negativa podemos cancelar el "commit", arrojar un error y viceversa. Podemos decir que los "hooks" son una capa extra que nos ayudan a no pasar por alto ciertos detalles.


Tipos de hooks

Existen una gran cantidad de "hooks" disponibles para aplicar, haremos un pequeño resumen de cada uno:

  • applypatch-msg: ayuda a formatear un mensaje para cumplir un estándar deseado del proyecto (si existe). También puede ser utilizado para rechazar un "commit" después de inspeccionar el mensaje. Si se encuentra activado el "hook" commit-msg, applypatch-msg lo invoca.
  • pre-applypatch: es usado para inspeccionar la rama donde se está trabajando y no permite un "commit" si el mismo no pasa unas pruebas. Si se encuentra activado pre-commit "hook" lo invoca.
  • post-applypatch: es usado principalmente para notificaciones (escribe un mensaje que se desee por la consola).
  • pre-commit: es invocado por git commit, la utilidad por defecto de este "hook" es atrapar espacios en blanco al final de cada línea y abortar el "commit" si esto llega a ocurrir. Pero se puede agregar cualquier cantidad de pruebas a este "hook" para asegurar que nuestros "commits" se encuentran como queremos que estén. Se puede ignorar este "hook" utilizando la bandera --no-verfy al final del "commit".
  • prepare-commit-msg: el propósito de este "hook" es preparar el comentario con un formato por defecto que uno desee que tenga (si existe). Un ejemplo de un comportamiento similar de este "hook" es cuando generamos un merge de una rama y git nos genera de manera automática un comentario referente al merge.
  • commit-msg: funciona de la misma manera que applypatch-msg. Podemos ignorarlo haciendo uso de la bandera --no-verfy.
  • post-commit: funciona de la misma manera que post-applypatch (imprime un mensaje de notificación) pero actúa una vez que se realizó el "commit".
  • pre-rebase: éste gancho es activado por el comando git rebase y puede ser usado para prevenir que una rama sea rebasada.
  • post-checkout: éste gancho se activa cuando se utiliza git checkout y puede ser usado para mostrar las diferencias entre las diferentes ramas o setear alguna metadata necesaria.
  • post-merge: es invocado por el comando git merge y puede ser usado para salvar o restablecer cualquier metadata asociada con una rama de trabajo.
  • pre-receive: este gancho es invocado por git-receive-pack en el repositorio remoto, y ocurre cuando se realiza un git push. Es el encargado de actualizar las referencias de los objetos y el estado del update (actualización).
  • update: de la misma manera que el pre-receive se invoca con git-receive-pack y ocurre con el comando git-push. Este gancho actualiza las referencias del repositorio remoto y puede ser utilizado para prevenir un git push -f (forzado).
  • post-receive: es ejecutado por git-receive-pack y ocurre cuando utilizamos el comando git push. A diferencia de los otro dos update y pre-receive actúa del lado del servidor. Se puede utilizar este gancho para enviar emails después de realizar el "commit" o verificar cualquier información de relevancia.
  • post-rewrite: es invocado por los comandos que reescriben commits tales como git commit --amend o git rebase.

Esta información fue tomada de kernel.org.


¿Cómo se usan los hooks?

Para poder utilizar algún "hook" debemos crearlos manualmente. La mayoría de los "hooks" son scripts de "shell", aunque podemos utilizar otros lenguajes de "scripting" si queremos. Absolutamente todos los "hooks" que necesitemos o creemos deben estar en la carpeta .git/hooks/ dentro del repositorio de git de nuestro interés. Por defecto todos los proyectos de git se crean con "hooks" pero hay que renombrarlos correctamente para que funcionen.

Hagamos una pequeña demostración de como se usan:

Entremos primero en la carpeta para observar cuales son los ganchos que por defecto que vienen con la creación del repositorio git.

$ cd .git/hooks
$ ls -la
total 40
drwxr-xr-x 11 albertogg  374 Sep 18 14:27 .
drwxr-xr-x 15 albertogg  510 Sep 18 14:27 ..
-rwxr-xr-x  1 albertogg  452 Jun 26 23:08 applypatch-msg.sample
-rwxr-xr-x  1 albertogg  896 Jun 26 23:08 commit-msg.sample
-rwxr-xr-x  1 albertogg  189 Jun 26 23:08 post-update.sample
-rwxr-xr-x  1 albertogg  398 Jun 26 23:08 pre-applypatch.sample
-rwxr-xr-x  1 albertogg  640 Sep 18 14:27 pre-commit
-rw-r--r--  1 albertogg 1348 Jun 26 23:08 pre-push.sample
-rwxr-xr-x  1 albertogg 4951 Jun 26 23:08 pre-rebase.sample
-rwxr-xr-x  1 albertogg 1239 Jun 26 23:08 prepare-commit-msg.sample
-rwxr-xr-x  1 albertogg 3611 Jun 26 23:08 update.sample

Vamos a utilizar en este caso el "pre-commit hook". Debemos renombrar los archivos y quitarles la terminación ".sample" para que git los reconozca normalmente.

$ mv pre-commit.sample pre-commit

Ahora voy a agregar unos espacios en blanco a cualquier línea dentro de uno de los archivos del repositorio y luego a intentar realizar un "commit" para que observen lo que sucede.

$ nano Archivo2_cambio_de_nombre.txt # agrego unos espacios en blanco al final de la segunda línea.

# intento realizar un "commit" y esto es lo que ocurre.

$ git commit -am "Prueba de hook"
Archivo2_cambio_de_nombre.txt:2: trailing whitespace.
+Agregando una segunda linea

Se canceló el "commit" ya que no pasó la prueba que realiza el "pre-commit hook". A partir de este momento debemos corregir y volver a realizar el "commit" para observar si hemos solventado todos los problemas existentes, de ser así se realizará el "commit" normalmente y sin espacios en blanco.


¿Quién utiliza git hooks?

Si han llegado a utilizar servicios como heroku.com muy seguramente se habrán dado cuenta que cada vez que uno realiza un git push hacia el repositorio git de heroku, el mismo utiliza varios "hooks" para detectar que tipo de proyecto es (lenguaje, framework, estructura de carpetas) y de esa manera buscar el buildpack adecuado para nuestro proyecto y así descargarse las librerías adecuadas y construir el proyecto en el servidor. Si alguna vez han subido un proyecto que heroku no reconoce también se habrán dado cuenta que el "hook" no permite la actualización y subida de las referencias del proyecto al servidor, cancelando el push.


Conclusión

En este último capítulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder entender que son estos "hooks" y para que nos pueden ayudar en un proyecto. Capaz cuando leas el contenido de este curso no pienses que necesitas "hooks", pero en un proyecto donde trabajan muchas personas es muy probaba que podamos prevenir comportamientos no deseados si los usamos. Si te surge algún tipo de duda no te detengas y déjanos un comentario, que gustosamente lo responderemos.

¡Hasta la semana entrante!


¿Te ha gustado esta publicación?

Compártela:

Por Alberto Grespan

Conoce más sobre este autor aquí


comments powered by Disqus