A logo showing the text blog.marcnuri.com
English
Inicio»Ingeniería de calidad»Conventional Commits: Guía Completa para Mejores Mensajes de Commit en Git

Entradas Recientes

  • Black Box vs White Box Testing: Cuándo Usar Cada Enfoque
  • Fabric8 Kubernetes Client 7.4.0 está disponible!
  • Kubernetes MCP Server se une a la organización Containers
  • MCP Tool Annotations: Añadiendo Metadatos y Contexto a Tus Herramientas de IA
  • Fabric8 Kubernetes Client 7.2.0 está disponible!

Categorías

  • Antiguo
  • Cloud Native
  • Desarrollo Backend
  • Desarrollo Frontend
  • Herramientas
  • Ingeniería de calidad
  • Inteligencia Artificial
  • JavaScript
  • Operaciones
  • Personal
  • Proyectos personales
  • Reflexiones sobre Ingeniería

Archivos

  • octubre 2025
  • septiembre 2025
  • julio 2025
  • mayo 2025
  • abril 2025
  • marzo 2025
  • febrero 2025
  • enero 2025
  • diciembre 2024
  • noviembre 2024
  • agosto 2024
  • junio 2024
  • mayo 2024
  • abril 2024
  • marzo 2024
  • febrero 2024
  • enero 2024
  • diciembre 2023
  • noviembre 2023
  • octubre 2023
  • septiembre 2023
  • agosto 2023
  • julio 2023
  • junio 2023
  • mayo 2023
  • abril 2023
  • marzo 2023
  • febrero 2023
  • enero 2023
  • diciembre 2022
  • noviembre 2022
  • octubre 2022
  • septiembre 2022
  • agosto 2022
  • julio 2022
  • junio 2022
  • mayo 2022
  • marzo 2022
  • febrero 2022
  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021
  • enero 2021
  • diciembre 2020
  • octubre 2020
  • septiembre 2020
  • agosto 2020
  • junio 2020
  • mayo 2020
  • marzo 2020
  • febrero 2020
  • enero 2020
  • noviembre 2019
  • septiembre 2019
  • julio 2019
  • diciembre 2018
  • agosto 2018
  • julio 2018
  • junio 2018
  • mayo 2018
  • marzo 2018
  • febrero 2018
  • noviembre 2017
  • octubre 2017
  • agosto 2017
  • julio 2017
  • enero 2017
  • julio 2016
  • enero 2016
  • diciembre 2015
  • noviembre 2015
  • diciembre 2014
  • noviembre 2014
  • octubre 2014
  • marzo 2014
  • febrero 2011
  • junio 2008
  • mayo 2008
  • abril 2008
  • enero 2008
  • junio 2007
  • mayo 2007
  • abril 2007
  • marzo 2007

Conventional Commits: Guía Completa para Mejores Mensajes de Commit en Git

2019-11-03 en Ingeniería de calidad etiquetado Git / Conventional Commits / Buenas Prácticas / Semantic Versioning (SemVer) / Changelog / CI por Marc Nuri | Última actualización: 2025-12-06
English version

Introducción

Escribir mensajes de commit significativos en Git es una de esas habilidades que separa a los desarrolladores junior de los profesionales experimentados. Sin embargo, la mayoría de nosotros hemos escrito commits como "fix bug", "update stuff", o el infame "WIP" en algún momento. Yo mismo lo he hecho.

Conventional Commits es una especificación que proporciona una convención sencilla para crear mensajes de commit explícitos y estandarizados. Siguiendo una estructura simple, puedes comunicar la intención de tus cambios de forma clara, automatizar el incremento de versiones y generar changelogs automáticamente.

En esta publicación, explicaré qué es Conventional Commits, cómo funciona, por qué deberías adoptarlo y cómo lo uso en mi flujo de trabajo de desarrollo diario.

¿Qué es Conventional Commits?

Conventional Commits es una especificación para escribir mensajes de commit estandarizados que siguen un formato específico. La convención está diseñada para ser legible tanto por humanos como por máquinas, permitiendo que las herramientas de automatización entiendan la naturaleza de los cambios en tu código.

La especificación fue creada por Benjamin E. Coe en 2017, inspirada en la necesidad de una documentación más clara en torno a los formatos de commit que ya estaban siendo utilizados por proyectos como Angular. El objetivo era eliminar la tediosa tarea de incrementar versiones y gestionar changelogs, al tiempo que se animaba a los desarrolladores a escribir mensajes de commit más reflexivos.

La Estructura del Mensaje de Commit

Un mensaje de commit convencional sigue esta estructura:

commit-structure.txt
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Analicemos cada componente:

  • type: Describe la categoría del cambio (obligatorio)
  • scope: Proporciona contexto adicional sobre qué parte del código se ve afectada (opcional)
  • description: Un breve resumen del cambio (obligatorio)
  • body: Una explicación más detallada del cambio (opcional)
  • footer: Metadatos adicionales como cambios de ruptura o referencias a issues (opcional)

Nota

La descripción debe seguir estas convenciones recomendadas:

  • Usa el modo imperativo: "add feature" no "added feature" o "adds feature"
  • Piensa en ello como completar la frase: "This commit will..."
  • Empieza con minúscula (no "Add feature" sino "add feature")
  • Sin punto al final

Tipos de Commit

La especificación define dos tipos obligatorios que se correlacionan directamente con Semantic Versioning (SemVer):

  • feat: Introduce una nueva funcionalidad (se correlaciona con MINOR en SemVer)
  • fix: Corrige un bug (se correlaciona con PATCH en SemVer)

Más allá de estos, la convención de Angular recomienda tipos adicionales que muchos proyectos adoptan:

TipoDescripción
buildCambios en el sistema de compilación o dependencias externas
choreTareas de mantenimiento que no modifican archivos src o test
ciCambios en archivos de configuración y scripts de CI
docsCambios únicamente en documentación
styleCambios de estilo de código (formateo, espacios en blanco, etc.)
refactorCambios de código que no corrigen bugs ni añaden funcionalidades
perfMejoras de rendimiento (un tipo especial de refactor)
testAñadir o corregir tests
opsOperaciones de infraestructura, despliegue, backup, recuperación
revertRevierte un commit anterior

Consejo

No tienes que usar todos estos tipos. Empieza con feat, fix y docs, luego añade más según las necesidades de tu equipo. La clave es la consistencia, no la completitud.

Ejemplos Prácticos

Veamos ejemplos reales de mensajes de commit convencionales, de simples a complejos. Considero que ver ejemplos reales es la forma más rápida de interiorizar el formato.

Commits Simples

Una corrección de bug básica:

fix-commit.txt
fix: prevent racing condition in user authentication

Una nueva funcionalidad:

feat-commit.txt
feat: add dark mode toggle to settings page

Una actualización de documentación:

docs-commit.txt
docs: correct spelling in README

Commits con Scope

Los scopes (alcances) proporcionan contexto sobre qué parte del código se ve afectada. Encuentro los scopes particularmente útiles en monorepos o proyectos con módulos distintos:

scoped-commits.txt
feat(api): add endpoint for user preferences

fix(auth): handle expired tokens gracefully

docs(readme): update installation instructions

Precaución

No uses identificadores de issues como scopes. Usa fix(auth): resolve token expiration con Fixes #123 en el footer, no fix(#123): resolve token expiration.

Breaking Changes

Los cambios de ruptura son significativos porque indican que los consumidores de tu código necesitan hacer cambios. Se correlacionan con incrementos de versión MAJOR en SemVer.

Puedes indicar breaking changes de dos formas:

Usando la notación !:

breaking-change-exclamation.txt
feat!: remove deprecated authentication endpoints
breaking-change-scoped.txt
feat(api)!: change response format for user endpoints

Usando un footer BREAKING CHANGE:

breaking-change-footer.txt
feat: allow provided config object to extend other configs

BREAKING CHANGE: `extends` key in config file is now used for
extending other config files instead of extending presets.

También puedes combinar ambos enfoques para máxima claridad:

breaking-change-combined.txt
refactor(runtime)!: drop support for Node 14

BREAKING CHANGE: Node 14 has reached end-of-life status.
Minimum supported version is now Node 18.

Precaución

Los cambios de ruptura deberían ser poco frecuentes y estar bien documentados. Al introducir uno, asegúrate de que el cuerpo del commit explique por qué fue necesario el cambio y cómo deben migrar los usuarios.

Commits Multilínea con Cuerpo y Footer

Para cambios complejos, usa el cuerpo para explicar el "qué" y el "por qué". Tomarse tu tiempo para escribir un buen cuerpo de commit compensa cuando hay que depurar problemas meses después.

El cuerpo debería:

  • Explicar la motivación del cambio
  • Contrastar el nuevo comportamiento con el anterior
  • Usar el modo imperativo, igual que la descripción

El footer se usa para:

  • Referencias a issues: Fixes #123, Closes #456, Refs JIRA-789
  • Descripciones de cambios de ruptura (cuando se necesita más detalle)
  • Coautores y revisores
multiline-commit.txt
fix(parser): handle edge case in markdown table parsing

The previous implementation failed when table cells contained
pipe characters. This fix properly escapes pipes within cell
content while maintaining backwards compatibility.

Fixes #1234
Reviewed-by: Jane Doe

Commits Especiales

Algunos commits siguen los patrones predeterminados de Git en lugar del formato convencional:

Commit inicial:

initial-commit.txt
chore: init

Commits de merge siguen el formato predeterminado de Git:

merge-commit.txt
Merge branch 'feature/user-auth' into main

Commits de revert siguen el formato predeterminado de Git:

revert-commit.txt
Revert "feat(auth): add OAuth support"

This reverts commit abc1234.

Más Ejemplos

Aquí hay ejemplos adicionales cubriendo diferentes tipos de commit:

perf-example.txt
perf: reduce memory footprint by using streaming parser
refactor-example.txt
refactor: extract validation logic into separate module
style-example.txt
style: apply consistent formatting to configuration files
test-example.txt
test(api): add integration tests for user endpoints
ops-example.txt
ops: configure automatic database backups

¿Por Qué Usar Conventional Commits?

Adoptar Conventional Commits aporta varios beneficios tangibles a tu flujo de trabajo de desarrollo. Aquí te cuento por qué lo he convertido en una práctica estándar en todos mis proyectos.

Generación Automática de Changelog

Herramientas como conventional-changelog y semantic-release pueden analizar tu historial de commits y generar automáticamente un changelog. Esto elimina el esfuerzo manual de mantener un archivo CHANGELOG.md y garantiza la precisión.

No uso herramientas automatizadas para todos los proyectos, pero incluso sin ellas, el formato vale la pena. Con un vistazo rápido al historial de commits, puedo determinar fácilmente la siguiente versión: fix significa patch, feat significa minor, y un cambio de ruptura (con ! o BREAKING CHANGE) significa una nueva versión major. Sin conjeturas, sin debates, los commits te dicen exactamente qué tipo de release estás preparando.

Incremento Automático de Versión

Al analizar los mensajes de commit, las herramientas pueden determinar el incremento de versión apropiado:

  • Los commits fix: disparan un incremento de versión PATCH (1.0.0 -> 1.0.1)
  • Los commits feat: disparan un incremento de versión MINOR (1.0.0 -> 1.1.0)
  • BREAKING CHANGE o ! dispara un incremento de versión MAJOR (1.0.0 -> 2.0.0)

Esto elimina el error humano de las decisiones de versionado y garantiza que tus releases sigan SemVer correctamente.

Consejo

Incluso si no automatizas el incremento de versiones, el ejercicio mental de elegir el tipo de commit correcto te ayuda a pensar sobre el impacto de tus cambios.

Mejor Comunicación en Equipo

Los mensajes de commit estandarizados facilitan a los miembros del equipo entender qué cambió y por qué. Al revisar pull requests o investigar problemas, los mensajes de commit significativos sirven como documentación que explica la evolución del código.

He visto equipos perder horas tratando de entender por qué se hizo un cambio particular, solo para encontrar un mensaje de commit que dice "fix stuff". Conventional Commits previene esto.

Navegación Mejorada del Historial de Git

Un historial de commits bien estructurado se convierte en un recurso valioso. Puedes filtrar fácilmente commits por tipo, encontrar todos los cambios de ruptura, o rastrear cuándo se introdujo una funcionalidad:

git-log-examples.sh
# Encontrar todos los cambios de ruptura
git log --oneline --grep="BREAKING CHANGE"

# Encontrar todas las nuevas funcionalidades
git log --oneline --grep="^feat"

# Encontrar todas las correcciones de bugs en el módulo auth
git log --oneline --grep="^fix(auth)"

Integración con CI/CD

Conventional Commits se integra perfectamente con pipelines de CI. Puedes configurar tu pipeline para:

  • Validar mensajes de commit antes de hacer merge
  • Publicar releases automáticamente basándote en los tipos de commit
  • Generar notas de release para releases de GitHub/GitLab
  • Disparar diferentes workflows basándote en los tipos de commit

Herramientas y Automatización

Varias herramientas ayudan a aplicar y aprovechar Conventional Commits en tus proyectos. Te guiaré a través de las que he encontrado más útiles.

Commitlint

commitlint valida que tus mensajes de commit sigan el formato convencional. Normalmente se usa con Git hooks para prevenir commits que no cumplan el formato.

Instala y configura commitlint:

install-commitlint.sh
npm install --save-dev @commitlint/cli @commitlint/config-conventional

Crea un commitlint.config.js:

commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
};

Husky

Husky facilita la configuración de Git hooks. Combinado con commitlint, valida los commits antes de que se creen:

setup-husky.sh
npm install --save-dev husky
npx husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

Nota

Husky 9+ usa una configuración más simple que las versiones anteriores. Si estás actualizando desde una versión anterior, consulta la guía de migración.

Semantic Release

semantic-release automatiza todo el flujo de trabajo de releases:

  • Determina el siguiente número de versión
  • Genera notas de release
  • Publica el paquete
  • Crea tags de Git y releases de GitHub

Esta herramienta es particularmente potente para autores de librerías que quieren releases totalmente automatizados. Lee tus commits convencionales y, por defecto, aplica semántica estilo Angular para decidir si un cambio es patch, minor o major. La uso en varios de mis proyectos de código abierto, y ha eliminado por completo los pasos manuales en mi proceso de releases.

Cómo Uso Conventional Commits

A lo largo de los años, he refinado mi enfoque para usar Conventional Commits en mis proyectos. Esto es lo que me funciona.

Mi Flujo de Trabajo Diario

No uso herramientas interactivas para cada commit. En cambio, he interiorizado el formato y escribo los commits directamente. Para commits complejos, uso mi editor para componer mensajes multilínea con el formato adecuado.

Mi flujo de trabajo típico:

  1. Hacer cambios enfocados y atómicos
  2. Añadir los cambios con git add -p para un control preciso
  3. Escribir un mensaje de commit convencional
  4. Hacer push cuando la funcionalidad o corrección está completa

Tiendo a centrarme en implementar funcionalidades o correcciones con alcances reducidos y pequeños pasos. Al escribir commits convencionales, me mantengo enfocado en cambios pequeños e incrementales de forma natural. Esto hace muy fácil para otros revisar mi trabajo, ya que cada commit tiene un propósito claro y único.

Consejo

Usar git add -p (modo patch) te ayuda a crear commits atómicos añadiendo solo los fragmentos relacionados con un único cambio. Esto lleva naturalmente a mejores mensajes de commit porque cada commit tiene un propósito claro.

Scopes que Uso Comúnmente

Defino los scopes basándome en la estructura del proyecto. Para una aplicación web típica, mis scopes podrían incluir:

  • api - Cambios en la API del backend
  • ui - Cambios en componentes del frontend
  • auth - Cambios relacionados con autenticación
  • deps - Actualizaciones de dependencias
  • config - Cambios de configuración

También uso el tipo de commit como scope cuando tiene sentido. Por ejemplo, para las modificaciones de archivos de build (como cambios en pom.xml o package.json) uso el scope build, y los cambios en workflows de GitHub uso ci:

type-as-scope.txt
chore(build): update maven-compiler-plugin to 3.12.1

chore(ci): add code coverage step to PR workflow

Para proyectos de Kubernetes como Eclipse JKube, uso scopes como:

  • kubernetes - Funcionalidad específica de Kubernetes
  • openshift - Funcionalidad específica de OpenShift
  • maven - Cambios en el plugin de Maven
  • gradle - Cambios en el plugin de Gradle

Aplicación en Proyectos Open Source

En proyectos de código abierto, puedes usar GitHub Actions para validar que los títulos de PR sigan el formato convencional. Esto es a menudo más práctico que validar cada commit ya que los contribuidores pueden hacer squash y rebase de su trabajo.

Aquí hay un enfoque simple usando una regex básica que funciona para cualquier proyecto sin dependencias externas:

.github/workflows/pr-title.yml
name: PR Title Check
on:
  pull_request:
    types: [opened, edited, synchronize]

jobs:
  check-title:
    runs-on: ubuntu-latest
    steps:
      - name: Validate PR title follows Conventional Commits
        run: |
          TITLE="${{ github.event.pull_request.title }}"
          PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?(!)?: .+$'
          if ! echo "$TITLE" | grep -qE "$PATTERN"; then
            echo "::error::PR title does not follow Conventional Commits format"
            echo "Expected: <type>[optional scope]: <description>"
            echo "Got: $TITLE"
            exit 1
          fi
          echo "PR title is valid: $TITLE"

Este workflow funciona para cualquier proyecto sin requerir Node.js o acciones externas. Si estás usando commitlint localmente, puedes añadir un commitlint.config.js a tu proyecto y usar npx -y commitlint en su lugar para una validación más completa.

Manejo de Squash Merges

Al usar squash merges, el título del PR se convierte en el mensaje de commit. Por eso validar los títulos de PR es crucial: asegura que tu rama main mantenga un historial limpio y convencional incluso cuando los contribuidores no sigan la convención en sus commits individuales.

Errores Comunes y Cómo Evitarlos

Aquí hay trampas que he encontrado (y a veces cometido yo mismo) y cómo evitarlas.

Usar el Tipo Incorrecto

Error: Usar fix para cualquier cosa que cambie código.

Solución: Reserva fix para correcciones de bugs reales. Usa refactor para reestructuración de código, perf para optimizaciones, y chore para tareas de mantenimiento.

Descripciones Demasiado Genéricas

Error: Escribir descripciones como "update code" o "fix issue".

Solución: Sé específico sobre los cambios. "Fix null pointer in user validation" es mucho más útil que "fix bug".

Scopes Inconsistentes

Error: Usar diferentes scopes para el mismo módulo (por ejemplo, auth, authentication, login).

Solución: Documenta tus scopes en tu guía de contribución y mantén la consistencia. Usa un plugin de commitlint para aplicar los scopes permitidos.

Mezclar Funcionalidades en Un Solo Commit

Error: Combinar una funcionalidad con un refactor en el mismo commit.

Solución: Mantén los commits atómicos. Si necesitas refactorizar para implementar una funcionalidad, haz commits separados:

atomic-commits.txt
refactor(auth): extract token validation to separate function

feat(auth): add support for refresh tokens

Consejo

Si te encuentras escribiendo "and" en la descripción de tu commit, probablemente estás tratando de hacer demasiado en un solo commit.

Primeros Pasos

¿Listo para adoptar Conventional Commits? Aquí hay un enfoque pragmático que recomiendo a los equipos nuevos en la convención.

Empieza Sencillo

No intentes configurar todas las herramientas de una vez. Empieza simplemente siguiendo el formato manualmente. Una vez que estés cómodo con la convención, añade herramientas gradualmente.

Documenta Tus Convenciones

Crea una sección en tu CONTRIBUTING.md que explique:

  • Qué tipos de commit usa tu proyecto
  • Qué scopes están disponibles
  • Ejemplos de buenos mensajes de commit

Configura Validación Básica

Una vez que tu equipo esté cómodo con el formato, añade commitlint con Husky para detectar errores temprano. Esto previene que commits no conformes entren en tu historial.

Automatiza Incrementalmente

Después de que la validación funcione, considera añadir:

  1. Generación automática de changelog
  2. Incremento automático de versiones
  3. Releases automatizados

Cada paso se construye sobre el anterior, así que tómate tu tiempo.

Conclusión

Conventional Commits transforma cómo los equipos se comunican a través de su historial de Git. Siguiendo un formato simple y estandarizado, ganas comunicación más clara, versionado automatizado y mejor integración de herramientas.

La especificación es intencionalmente ligera: puedes empezar a usarla hoy sin ninguna herramienta. A medida que tu equipo se sienta cómodo con la convención, añade automatización para desbloquear todo su potencial.

Ya sea que estés trabajando en un proyecto personal o manteniendo software empresarial, los mensajes de commit significativos hacen tu código más mantenible y tus releases más predecibles. Prueba Conventional Commits. Tu yo futuro (y tus compañeros de equipo) te lo agradecerán.

Referencias

  • Especificación de Conventional Commits v1.0.0
  • Semantic Versioning (SemVer)
  • Guía de Mensajes de Commit de Angular
  • commitlint - Lint de mensajes de commit
  • semantic-release - Gestión automatizada de versiones

Te Puede Interesar

  • Test-Driven Development (TDD): Una Introducción
  • Introducción a Model Context Protocol (MCP): El Futuro de la Integración de IA
Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Navegador de artículos
Isotope Mail: Cómo desplegar Isotope+Traefik en KubernetesFedora: Cómo instalar el entorno de escritorio Cinnamon - guía completa
© 2007 - 2025 Marc Nuri