Introducción a Git Hooks
Aprende a utilizar Git Hooks para automatizar tareas, validar cambios y mejorar tu flujo de trabajo con Git mediante scripts personalizados que se ejecutan en momentos específicos del ciclo de vida de Git.
Cristian Escalante
Última actualización: 28 de abril de 2025
Introducción a Git Hooks
Git Hooks son scripts que Git ejecuta automáticamente antes o después de eventos específicos como commit, push o merge. Estos hooks te permiten personalizar el comportamiento interno de Git, automatizar tareas repetitivas y garantizar la calidad del código mediante validaciones automáticas.
¿Qué son los Git Hooks?
Los Git Hooks son programas ejecutables (generalmente scripts) que se activan cuando ocurren ciertos eventos en el flujo de trabajo de Git. Estos scripts pueden:
- Validar que los cambios cumplan con ciertos criterios antes de permitir un commit
- Ejecutar pruebas automáticamente antes de un push
- Notificar a sistemas externos después de un commit
- Formatear código automáticamente
- Verificar mensajes de commit
- Y mucho más...
Git proporciona hooks tanto del lado del cliente (en tu repositorio local) como del lado del servidor (en repositorios remotos), lo que permite automatizar procesos en diferentes etapas del flujo de trabajo.
Ubicación de los Git Hooks
Los hooks se almacenan en el directorio .git/hooks/
de cada repositorio Git. Cuando inicializas un repositorio, Git crea ejemplos de hooks con la extensión .sample
:
.git/hooks/
├── applypatch-msg.sample
├── commit-msg.sample
├── fsmonitor-watchman.sample
├── post-update.sample
├── pre-applypatch.sample
├── pre-commit.sample
├── pre-merge-commit.sample
├── pre-push.sample
├── pre-rebase.sample
├── pre-receive.sample
├── prepare-commit-msg.sample
├── push-to-checkout.sample
└── update.sample
Para activar un hook, simplemente elimina la extensión .sample
y asegúrate de que el archivo sea ejecutable:
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
Tipos de Git Hooks
Los hooks se dividen en dos categorías principales:
Hooks del lado del cliente
Se ejecutan en tu máquina local y afectan tus operaciones de Git.
Hooks de commit
- pre-commit: Se ejecuta antes de que comience el proceso de commit. Útil para validar el código que se va a incluir.
- prepare-commit-msg: Se ejecuta después de que se genera el mensaje de commit predeterminado pero antes de que se lance el editor.
- commit-msg: Se ejecuta después de que escribes un mensaje de commit. Útil para validar el formato del mensaje.
- post-commit: Se ejecuta después de que se completa el proceso de commit. Útil para notificaciones.
Hooks de email
- applypatch-msg: Se ejecuta antes de aplicar un parche por email.
- pre-applypatch: Se ejecuta después de aplicar un parche pero antes de hacer commit.
- post-applypatch: Se ejecuta después de que se completa un commit desde un parche.
Hooks de otros comandos
- pre-rebase: Se ejecuta antes de rebasar una rama.
- post-rewrite: Se ejecuta después de comandos que reescriben commits (como
git commit --amend
ogit rebase
). - post-checkout: Se ejecuta después de
git checkout
. Útil para configurar entornos de trabajo. - post-merge: Se ejecuta después de una fusión exitosa.
- pre-push: Se ejecuta antes de enviar commits a un repositorio remoto. Útil para validaciones finales.
- pre-auto-gc: Se ejecuta antes de la recolección de basura automática.
Hooks del lado del servidor
Se ejecutan en el servidor remoto y afectan las operaciones de push.
- pre-receive: Se ejecuta cuando el servidor recibe un push pero antes de actualizar referencias.
- update: Similar a pre-receive, pero se ejecuta una vez por cada rama que se actualiza.
- post-receive: Se ejecuta después de que todas las referencias se han actualizado. Útil para despliegues automáticos.
Ejemplos prácticos de Git Hooks
1. Validar formato de código con pre-commit
Este hook verifica que el código cumple con las reglas de estilo antes de permitir un commit:
#!/bin/bash
# .git/hooks/pre-commit
# Guardar archivos staged
files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -n "$files" ]; then
# Ejecutar ESLint en los archivos JavaScript staged
echo "Validando archivos JavaScript con ESLint..."
npx eslint $files
if [ $? -ne 0 ]; then
echo "❌ Error: La validación de ESLint falló. Por favor, corrige los errores antes de hacer commit."
exit 1
fi
fi
echo "✅ Validación de código exitosa"
exit 0
2. Validar mensajes de commit con commit-msg
Este hook verifica que los mensajes de commit sigan el formato de Conventional Commits:
#!/bin/bash
# .git/hooks/commit-msg
commit_msg_file=$1
commit_msg=$(cat $commit_msg_file)
# Patrón para Conventional Commits
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9-]+\))?: .{1,100}$'
if ! echo "$commit_msg" | head -1 | grep -qE "$pattern"; then
echo "❌ Error: El mensaje de commit no sigue el formato de Conventional Commits."
echo "Debe ser: <tipo>(<ámbito>): <descripción>"
echo "Ejemplo: feat(auth): implementa inicio de sesión con Google"
exit 1
fi
echo "✅ Formato de mensaje de commit válido"
exit 0
3. Ejecutar pruebas antes de push con pre-push
Este hook ejecuta las pruebas antes de permitir un push:
#!/bin/bash
# .git/hooks/pre-push
echo "Ejecutando pruebas antes de push..."
npm test
if [ $? -ne 0 ]; then
echo "❌ Error: Las pruebas han fallado. No se puede hacer push."
exit 1
fi
echo "✅ Todas las pruebas pasaron correctamente"
exit 0
4. Notificar después de un commit con post-commit
Este hook envía una notificación después de cada commit:
#!/bin/bash
# .git/hooks/post-commit
commit_hash=$(git rev-parse HEAD)
commit_msg=$(git log -1 --pretty=%B)
author=$(git log -1 --pretty=%an)
# Enviar notificación (ejemplo con curl)
curl -X POST -H "Content-Type: application/json" \
-d "{\"text\":\"Nuevo commit por $author: $commit_msg ($commit_hash)\"}" \
https://hooks.slack.com/services/your/webhook/url
echo "✅ Notificación enviada"
exit 0
5. Despliegue automático con post-receive
Este hook en el servidor despliega automáticamente después de recibir un push:
#!/bin/bash
# En el servidor: hooks/post-receive
while read oldrev newrev refname
do
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
if [ "$branch" = "main" ]; then
echo "Desplegando rama main..."
# Directorio de trabajo
WORK_DIR=/var/www/mi-aplicacion
# Actualizar el código
GIT_DIR=$WORK_DIR/.git
GIT_WORK_TREE=$WORK_DIR
git --git-dir=$GIT_DIR --work-tree=$GIT_WORK_TREE pull origin main
# Reconstruir la aplicación
cd $WORK_DIR
npm install
npm run build
# Reiniciar servicios
systemctl restart mi-aplicacion
echo "✅ Despliegue completado"
fi
done
Hooks compartidos en un equipo
Por defecto, los hooks no se incluyen en el repositorio Git (están en .git/hooks
, que no forma parte del control de versiones). Para compartir hooks con tu equipo, puedes:
1. Usar un directorio personalizado
Configura Git para buscar hooks en un directorio que sí esté bajo control de versiones:
# Configuración en el repositorio
git config core.hooksPath .githooks
# Crea el directorio y añade tus hooks
mkdir -p .githooks
touch .githooks/pre-commit
chmod +x .githooks/pre-commit
2. Usar herramientas de gestión de hooks
Existen herramientas que facilitan compartir y gestionar hooks:
- Husky: Integra Git hooks con el ecosistema npm
- pre-commit: Framework para gestionar hooks de pre-commit
- commitlint: Verifica que los mensajes de commit sigan convenciones
Ejemplo con Husky
- Instala Husky:
npm install husky --save-dev
npx husky install
- Añade un script a
package.json
:
{
"scripts": {
"prepare": "husky install"
}
}
- Añade un hook:
npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit
Buenas prácticas para Git Hooks
1. Mantén los hooks simples y rápidos
Los hooks que tardan mucho en ejecutarse pueden frustrar a los desarrolladores y tentarlos a saltarse las validaciones.
2. Proporciona mensajes claros
Cuando un hook falla, asegúrate de que el mensaje explique claramente:
- Qué falló
- Por qué falló
- Cómo solucionarlo
3. Permite anular hooks en casos excepcionales
A veces es necesario saltarse un hook. Proporciona una forma de hacerlo:
# Saltarse hooks de pre-commit
git commit --no-verify -m "Commit urgente"
4. Documenta tus hooks
Asegúrate de que todos los miembros del equipo entiendan:
- Qué hooks están configurados
- Qué hace cada uno
- Cómo instalarlos
- Cómo solucionar problemas comunes
5. Prueba tus hooks
Antes de compartir un hook, asegúrate de que funcione correctamente en diferentes escenarios.
6. Versiona tus hooks
Mantén tus hooks bajo control de versiones para seguir su evolución y facilitar la colaboración.
Limitaciones y consideraciones
Seguridad
Los hooks pueden ejecutar cualquier código, lo que representa un riesgo de seguridad potencial. Nunca ejecutes hooks de fuentes no confiables sin revisarlos primero.
Rendimiento
Los hooks que realizan operaciones costosas pueden ralentizar significativamente el flujo de trabajo. Optimiza tus scripts para que sean lo más eficientes posible.
Portabilidad
Los hooks pueden depender del entorno (sistema operativo, herramientas instaladas). Asegúrate de que funcionen en todos los entornos que utiliza tu equipo.
Mantenimiento
Como cualquier código, los hooks requieren mantenimiento. Revísalos periódicamente para asegurarte de que siguen siendo relevantes y funcionan correctamente.
Casos de uso avanzados
Integración con CI/CD
Los hooks pueden complementar (no reemplazar) tu sistema de CI/CD:
- Los hooks locales proporcionan feedback inmediato
- CI/CD proporciona validaciones más exhaustivas
Automatización de tareas de documentación
#!/bin/bash
# .git/hooks/post-commit
# Generar documentación automáticamente
if git diff-tree --name-only -r HEAD@{1} HEAD | grep -q "src/"; then
echo "Generando documentación..."
npm run docs
# Commit automático de la documentación
if git status --porcelain | grep -q "docs/"; then
git add docs/
git commit --no-verify -m "docs: actualiza documentación automáticamente"
fi
fi
Verificación de seguridad
#!/bin/bash
# .git/hooks/pre-commit
# Buscar credenciales o tokens expuestos
if git diff --cached -G"(API_KEY|SECRET|PASSWORD|TOKEN)" --name-only | grep -q .; then
echo "⚠️ Advertencia: Posibles credenciales o tokens en el código"
echo "Por favor, verifica los siguientes archivos:"
git diff --cached -G"(API_KEY|SECRET|PASSWORD|TOKEN)" --name-only
read -p "¿Continuar con el commit? (s/N): " confirm
if [ "$confirm" != "s" ] && [ "$confirm" != "S" ]; then
exit 1
fi
fi
Conclusión
Los Git Hooks son una herramienta poderosa que te permite personalizar y automatizar tu flujo de trabajo con Git. Desde validaciones simples hasta integraciones complejas, los hooks pueden ayudarte a mantener la calidad del código, aplicar estándares de equipo y ahorrar tiempo en tareas repetitivas.
Aunque configurar hooks requiere un esfuerzo inicial, los beneficios a largo plazo son significativos: menos errores, mayor consistencia y un proceso de desarrollo más fluido. Como con cualquier herramienta de automatización, la clave está en encontrar el equilibrio adecuado entre validaciones útiles y un flujo de trabajo ágil.
A medida que te familiarices con los Git Hooks, descubrirás nuevas formas de optimizar tu proceso de desarrollo y garantizar que tu código cumpla con los estándares que tú y tu equipo han establecido.