¿Odias los anuncios? Ir Sin publicidad Hoy

Git Hooks Pre-commit, Pre-puls y la detención de código malo en la puerta

Actualizado en

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 Hooks: Pre-commit, Pre-push, y la detención de código malo en la puerta 1
ANUNCIO · ¿ELIMINAR?

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.

¿Quieres eliminar publicidad? Adiós publicidad hoy

Instalar extensiones

Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas

añadir Extensión de Chrome añadir Extensión de borde añadir Extensión de Firefox añadir Extensión de Opera

¡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!

ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?

Noticias Aspectos técnicos clave

Involucrarse

Ayúdanos a seguir brindando valiosas herramientas gratuitas

Invítame a un café
ANUNCIO · ¿ELIMINAR?