Git Hooks Pre-commit, Pre-puls y la detención de código malo en la puerta
Los hooks pre-commit, commit-msg y pre-push son scripts de shell que se ejecutan antes de que git escriba un commit o envíe un push. A continuación se muestra cómo configurarlos para detectar fallos de análisis de código, mensajes de commit incorrectos y secretos filtrados — con ejemplos reales que puedes integrar hoy mismo.
Git incluye hooks — scripts en shell que se ejecutan en puntos específicos de tu flujo de trabajo. La mayoría de los repositorios los tienen inactivos en .git/hooks/ como .sample archivos. La mayoría de los desarrolladores los ignoran hasta que un commit defectuoso o una clave API revelada les hacen desear que no lo hicieran.
Esto abarca los tres hooks que vale la pena conectar en cada proyecto: pre-commit, commit-msgy pre-push. Cada uno detecta un tipo diferente de error. Cada uno es un script en shell que puedes pegar y usar hoy.
Dónde se encuentran los hooks
Cada repositorio de git tiene un .git/hooks/ directorio. Ejecuta ls .git/hooks/ y verás archivos de ejemplo. Git ignora cualquier archivo con el .sample sufijo. Para activar un hook, elimina el sufijo y hazlo ejecutable:
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
El contrato es simple: salir con cero y git continúa. Salir con un valor distinto de cero y git aborta, mostrando lo que escribiste en stderr.
pre-commit: tu hook de mayor valor
pre-commit se ejecuta después de que escribas git commit pero antes de que se escriba el objeto de commit. No puede ver el mensaje del commit — ese aún no se ha escrito. Lo que hace es inspeccionar los archivos estudiados y rechazar si algo parece incorrecto. hacerlo La detalle crítico: usar
para obtener solo los archivos que realmente estás estudiando. Realizar una revisión del proyecto completo en cada commit es lento y detecta problemas que no introdujiste. git diff --cached --name-only Ejemplo de linter (ESLint)
flag salta los archivos eliminados — no tiene sentido intentar revisar algo que acaba de eliminar.
#!/bin/sh
# Lint only staged JS files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
echo "Running ESLint on staged files..."
echo "$STAGED_FILES" | xargs ./node_modules/.bin/eslint
if [ $? -ne 0 ]; then
echo "ESLint failed. Fix errors before committing."
exit 1
fi
exit 0
El --diff-filter=ACM Ejemplo de escaneo secreto
Un escaneo directo de patrones que detecta los errores evidentes — claves API codificadas, contraseñas en archivos de configuración cometidas por accidente:
Para proyectos más allá de ejemplos simples, combínalo con un escáner dedicado.
#!/bin/sh
# Block commits with obvious secrets
PATTERNS="(AWS_SECRET|api_key\s*=|password\s*=|PRIVATE KEY)"
if git diff --cached | grep -qiP "$PATTERNS"; then
echo "Potential secret detected in staged changes. Aborting commit."
exit 1
fi
exit 0
detect-secrets de Yelp funciona bien como hook pre-commit — mantiene un archivo de referencia para que las cadenas marcadas no bloqueen cada commit. trufflehog es mejor para escanear el historial después de que se haya producido o ejecutarse en CI. commit-msg: imponer formato del mensaje
Este hook recibe un argumento: la ruta a un archivo temporal que contiene tu mensaje de commit provisional. Lee el archivo, valida el mensaje y salta con código 1 para rechazarlo. El archivo es escribible — puedes normalizar el mensaje en lugar de rechazarlo, aunque eso sorprende a las personas por primera vez.
Imponer
Conventional Commits es el uso más común. El beneficio es cambios automatizados, salida legible y pipelines de CI que pueden analizar los tipos de commit para decidir qué liberar: Esto no detectará un mensaje válido pero sin significado, como git log . Eso es un problema de cultura, no de herramientas.
#!/bin/sh
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# type(scope): description — scope is optional
PATTERN="^(feat|fix|chore|docs|style|refactor|test|perf|ci|build|revert)(\(.+\))?: .{1,72}"
if ! echo "$COMMIT_MSG" | grep -qP "$PATTERN"; then
echo ""
echo "Invalid commit message. Use Conventional Commits format:"
echo " type(scope): short description"
echo ""
echo "Valid types: feat, fix, chore, docs, style, refactor, test, perf, ci, build, revert"
echo "Example: feat(auth): add OAuth2 login flow"
echo ""
echo "Your message: $COMMIT_MSG"
exit 1
fi
exit 0
pre-push: la última puerta antes de la fuente fix: fix thingspre-push se ejecuta después de que
se invoque pero antes de que se envíe cualquier dato al remoto. Recibe el nombre y la URL del remoto por stdin. Aquí deben estar los tests — no un linter (que se ejecuta en pre-commit), sino pruebas reales que verifican el comportamiento.
Una verdad dura: si tu suite de pruebas tarda más de 60 a 90 segundos, las personas usarán git push . Ejecuta solo pruebas unitarias rápidas aquí. Las pruebas de integración y E2E deben estar en CI, donde el tiempo lento es aceptable. Un hook que sea lento suficiente para ser ignorado es peor que no tener ningún hook.
#!/bin/sh
echo "Running tests before push..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
exit 0
Ignorar los hooks — y cuándo eso es adecuado --no-verifyAmbas banderas existen por una razón. Un hook defectuoso que bloquee una corrección de emergencia es el tipo de cosa que hace que toda la equipo se vuelva en contra de los hooks de git. Usa
cuando tengas una razón legítima: un hook que falle en archivos no relacionados o una emergencia en la que la corrección importa más que la puerta.
git commit --no-verify
git push --no-verify
Si estás usando frecuentemente esta opción, los hooks necesitan ser ajustados. Los culpables más comunes: ejecutarse demasiado lentamente, fallar en archivos que no fueron modificados, o coincidencias falsas que nunca has limpiado. --no-verify Compartir hooks con tu equipo
es local en cada clon — está intencionalmente no cometido al repositorio. Dos enfoques para que los hooks se queden:
Opción 1: core.hooksPath
.git/hooks/ Almacena los hooks en un directorio cometido (por ejemplo,
), luego apunta git hacia él:
Para automatizar esto en nuevos clones, agrega un .githooks/script a
git config core.hooksPath .githooks
— npm lo ejecuta automáticamente en prepare Hacer que los scripts sean ejecutables, cometerlos y cualquier persona que clone y ejecute package.json obtiene los hooks configurados automáticamente. npm install:
{
"scripts": {
"prepare": "git config core.hooksPath .githooks"
}
}
Opción 2: Husky npm install Husky
es la elección estándar para proyectos en JavaScript/Node. Maneja la
conexión para ti y da a cada hook su propio archivo en Luego agrega hooks como scripts en shell simples: core.hooksPath Husky 9 (lanzada al inicio de 2024) eliminó por completo la configuración en JSON en favor de scripts en shell sin formato. Más simple que v4/v8 para nuevos entornos, pero migrar de Husky 4 es un cambio quebrante que el guía oficial subestima — el formato anterior ya no funciona en absoluto. Si estás actualizando un repositorio existente, reserva tiempo para ello. .husky/:
npx husky init
Los repositorios no en JavaScript se benefician más con el
echo "npm test" > .husky/pre-push
chmod +x .husky/pre-push
enfoque. No hay razón para traer una dependencia en Node solo para la gestión de hooks. .huskyrc Revisar tu diferencia antes de que se ejecute el hook
muestra los cambios estudiados en la terminal. Cuando estás comparando dos versiones de un archivo de configuración o verificando qué cambió realmente en una refactorización a través de múltiples ediciones, una diferencia visual es más rápida de escanear. core.hooksPath IO Tools’ Text Diff
te permite pegar dos versiones y ver exactamente qué cambió — útil cuando quieres auditar qué entra en un commit antes de que se ejecute cualquier hook.
git diff --cached Los hooks de git son una de las pocas herramientas de automatización que viven completamente dentro de tu flujo de trabajo existente — sin necesidad de una cuenta de CI, sin servicio extra, sin costo. Un hook pre-commit que rechaza un error de linter es tan confiable como el script que escribiste. Eso es una característica: puedes leerlo, depurarlo y modificarlo en un minuto. Conecta los tres hooks mencionados anteriormente y has cerrado la mayor brecha entre “funciona localmente” y “funciona en main”. Git Hooks: Pre-commit, Pre-push, y la detención de código malo en la puerta 2 Git Hooks: Pre-commit, Pre-push, y la detención de código malo en la puerta 1
Los hooks pre-commit, commit-msg y pre-push son scripts en shell que se ejecutan antes de que git escriba un commit o envíe un push. Aquí te muestro cómo conectarlos para detectar fallos de linter, mensajes de commit incorrectos y claves reveladas — con ejemplos reales que puedes usar hoy.
Instalar extensiones
Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas
恵 ¡El marcador ha llegado!
Marcador es una forma divertida de llevar un registro de tus juegos, todos los datos se almacenan en tu navegador. ¡Próximamente habrá más funciones!
Herramientas clave
Ver todo Los recién llegados
Ver todoActualizar: Nuestro última herramienta se agregó el 15 de junio de 2026
