HDP115

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.

CE

Cristian Escalante

Última actualización: 28 de abril de 2025

git
control de versiones
desarrollo
automatización

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 o git 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

  1. Instala Husky:
npm install husky --save-dev
npx husky install
  1. Añade un script a package.json:
{
  "scripts": {
    "prepare": "husky install"
  }
}
  1. 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.

Convención de ramas
Aprende a establecer y seguir convenciones de nomenclatura p...
Uso de .gitignore efectivo
Aprende a configurar y utilizar el archivo .gitignore de man...
Referencias
Typicode. Husky - Git hooks made easy. https://typicode.github.io/husky/
Atlassian Git Tutorial. Customizing Git - Git Hooks. https://www.atlassian.com/git/tutorials/git-hooks
pre-commit. pre-commit: A framework for managing and maintaining multi-language pre-commit hooks. https://pre-commit.com/

Conceptos Básicos de HTML

Aprende los conceptos básicos de HTML

Conceptos Básicos de CSS

Aprende los conceptos básicos de CSS

Conceptos Básicos de JavaScript

Aprende los conceptos básicos de JavaScript

Conceptos Básicos SQL

Aprende los conceptos básicos de SQL

Conceptos Básicos de Python

Aprende los conceptos básicos de Python

Conceptos Básicos de UML

Aprende los conceptos básicos de UML

Refuerzo Academico de Herramientas de Productividad 2025