Hooks de pre-commit
pre-commit ejecuta comprobaciones de linting, formato y tipos automáticamente antes de cada commit de git. Los problemas se detectan localmente en segundos en lugar de en minutos en CI.
Receta
uv add --group dev pre-commit
uv run pre-commit install# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-formatuv run pre-commit run --all-filesCuándo usar esto:
- Los desarrolladores olvidan ejecutar el linting antes de hacer push.
- La CI falla por detalles de formato que ralentizan las revisiones.
- Los nuevos miembros del equipo necesitan protecciones desde el primer día.
Ejemplo funcional
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.14.0
hooks:
- id: mypy
additional_dependencies: [pydantic>=2]
args: [src/]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
args: [--maxkb=500]uv run pre-commit install
git commit -m "feat: add billing module"
# ruff + mypy se ejecutan automáticamente; el commit se bloquea en caso de falloLo que esto demuestra:
- Los hooks se ejecutan solo en archivos preparados (rápido).
--fixcorrige automáticamente antes de bloquear.- El hook de mypy verifica tipos con las dependencias del proyecto.
- Los hooks genéricos detectan accidentes de espacios en blanco y archivos grandes.
Inmersión profunda
Cómo funciona
pre-commit installescribe un script en.git/hooks/pre-commit.- En
git commit, cada hook se ejecuta en un entorno aislado. - Los hooks fallidos bloquean el commit; los archivos corregidos pueden necesitar ser preparados de nuevo.
pre-commit run --all-filessimula una ejecución completa (útil en CI).
Rendimiento de los hooks
| Hook | Tiempo típico | Alcance |
|---|---|---|
| ruff | <1s | Archivos preparados |
| ruff-format | <1s | Archivos preparados |
| mypy | 5-30s | Rutas configuradas |
| trailing-whitespace | <1s | Archivos preparados |
Trampas comunes
- mypy lento en cada commit: frustrante para los desarrolladores. Solución: ejecutar mypy solo en CI; mantener ruff en pre-commit.
- No actualizar
revde los hooks: conjuntos de reglas obsoletos. Solución:pre-commit autoupdatetrimestralmente. - Hooks no instalados después de clonar: los commits omiten las comprobaciones. Solución: documentar
pre-commit installen README; añadirpre-commit run --all-filesen CI. - Los hooks de corrección cambian archivos pero el commit continúa:
--exit-non-zero-on-fixvuelve a preparar el problema. Solución: usar el argumento; volver a añadir los archivos corregidos. - Versiones de hooks diferentes localmente vs CI: resultados inconsistentes. Solución: fijar
reven la configuración; CI ejecuta la misma configuración.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| Solo CI | Equipo muy pequeño | Los desarrolladores envían código roto a menudo |
| lefthook | Necesita hooks paralelos más rápidos | El ecosistema es más pequeño |
| husky | Monorepo con JS + Python | Repositorio solo de Python |
Preguntas frecuentes
¿Cómo omito los hooks una vez?
git commit --no-verify (usar con moderación, nunca como política de equipo por defecto).
¿Cómo ejecuto los hooks manualmente?
pre-commit run --all-files o pre-commit run ruff --all-files.
¿Debería mypy estar en pre-commit?
Para proyectos pequeños, sí. Para bases de código grandes, mypy solo en CI es más rápido para el flujo de desarrollo.
¿Cómo añado un hook?
Añade una entrada de repositorio a .pre-commit-config.yaml y ejecuta pre-commit install.
¿Funcionan los hooks en Windows?
Sí. pre-commit soporta Windows con Python instalado.
¿Cómo comparto la configuración?
Haz commit de .pre-commit-config.yaml. Cada desarrollador ejecuta pre-commit install.
¿Pueden ejecutarse los hooks en CI?
Sí: pre-commit run --all-files como un paso de CI. Detecta a los desarrolladores que omiten la instalación.
¿Cómo excluyo un archivo?
exclude: ^migrations/ en la configuración del hook o el filtro types.
¿Qué pasa si un hook necesita dependencias del proyecto?
Usa additional_dependencies en la configuración del hook (como con mypy + pydantic).
¿Con qué frecuencia debo actualizar automáticamente?
Trimestralmente o al actualizar las versiones de ruff/mypy en pyproject.toml.
Relacionado
- Configuración de Ruff - configuración del hook de ruff
- mypy & pyright en CI - verificación de tipos
- Linting en CI/CD - pipeline de CI
- Integración con el editor - bucle de retroalimentación del IDE
Versiones de la pila: Esta página se escribió para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.