Skip to content

Git Hooks y Automatización

Qué Son

Scripts que se ejecutan en eventos del ciclo Git (local o del lado servidor) para reforzar políticas y automatizar tareas repetitivas.

Ubicación

.git/hooks/

Ejemplos .sample presentes al inicializar un repo.

Hooks Locales Más Útiles

HookMomentoUso Común
pre-commitAntes de crear commitLint, format, tests rápidos
commit-msgDespués de redactar mensajeValidar convención
pre-pushAntes de enviar a remotoTests más lentos, build
prepare-commit-msgAntes de abrir editorPrefill mensaje

Ejemplo pre-commit (lint + formato)

bash
#!/usr/bin/env bash
set -e
pnpm lint
pnpm format:check

Dar permisos:

bash
chmod +x .git/hooks/pre-commit

Validar Mensaje (commit-msg)

bash
#!/usr/bin/env bash
msgFile=$1
pattern='^(feat|fix|refactor|docs|test|chore)(\(.+\))?: '
if ! grep -Eq "$pattern" "$msgFile"; then
  echo "Mensaje inválido. Usa: feat(scope): resumen" >&2
  exit 1
fi

Saltar Hooks

bash
git commit --no-verify

Úsalo solo si hay razón clara.

Hooks Compartidos (core.hooksPath)

bash
mkdir -p .githooks
git config core.hooksPath .githooks

Versiona .githooks/ en el repo.

Ejemplo pre-push

bash
#!/usr/bin/env bash
set -e
pnpm test -- --bail

Seguridad

  • Revisa scripts antes de ejecutar (repos externos)
  • No insertar secretos en hooks

Del Lado Servidor (ejemplos)

HookUso
pre-receiveValidar política (branch protegida)
updateChecks por rama
post-receiveDespliegue continuo, notificaciones

Flujo con Husky (Proyecto JS)

bash
pnpm add -D husky
pnpm husky install
npx husky add .husky/pre-commit "pnpm lint"

Diferencia CI vs Hooks

AspectoHooksCI
ÁmbitoLocal inmediatoCentralizado
Tiempo feedbackInstantáneoMinutos
GarantíaDepende del devFuerte
Uso idealFiltros rápidosValidación integral

Buenas Prácticas

  • Mantener hooks rápidos (<2s)
  • Fail fast con mensajes claros
  • Documentar bypass permitido

Troubleshooting

ProblemaSolución
Hook no correPermisos + ruta shebang
LentoPerfilado + caché
Falsos positivosAjustar reglas lint

Ejemplo Avanzado: Bloquear main

pre-push (simplificado):

bash
#!/usr/bin/env bash
branch=$(git symbolic-ref --short HEAD)
if [ "$branch" = "main" ]; then
  echo "Push directo a main bloqueado." >&2
  exit 1
fi

Resumen

Hooks incrementan calidad temprano. Úsalos ligeros, versionados y alineados con pipeline CI.