Buenas prácticas de Git en 2026: la checklist del profesional

Commits atómicos, mensajes claros, secretos fuera del repo y force push seguro: la checklist de buenas prácticas de Git para trabajar con IA.

Buenas prácticas de Git en 2026: la checklist del profesional

Tu historial de Git no es un diario personal. Es la documentación que lee tu equipo cuando algo se rompe a las tres de la tarde, y la que lees tú dentro de seis meses cuando no recuerdas por qué esa línea existe. En 2026, con un agente escribiendo buena parte de tus diffs, esa documentación se llena de cambios que tú no has tecleado. Por eso las buenas prácticas de Git importan más ahora, no menos. Aquí tienes la checklist que aplico y que puedes empezar a usar hoy mismo.

¿Por qué la disciplina de Git importa más ahora que la IA escribe tus diffs?

Porque un agente produce cambios más rápido de lo que tú los revisas, y Git es el único sitio donde queda constancia de qué entró y por qué. Cuando tecleabas cada línea, entendías cada cambio por el simple hecho de haberlo escrito. Ese entendimiento gratis desapareció.

Ahora le pides a la IA «añade paginación al listado de facturas» y te devuelve doscientas líneas repartidas en cinco archivos. Algunas son exactamente lo que querías. Otras tocan un helper compartido «de paso», o meten una dependencia que no habías pedido. Si aceptas todo el bloque y lo commiteas con un «wip», acabas de meter en la historia del proyecto algo que nadie ha leído.

La disciplina de Git es lo que te devuelve el control. No frena a la IA. Convierte su velocidad en algo que tu equipo puede revisar, revertir y entender. El resto de este post es cómo hacerlo, comando a comando.

Commits atómicos: una idea por commit

Un commit atómico contiene un único cambio lógico completo, y nada más. Si arreglas un bug y de camino renombras tres variables y actualizas una dependencia, eso son tres commits, no uno.

La prueba práctica es la frase: si para describir lo que hace un commit necesitas la palabra «y» («arregla el login y refactoriza el router»), casi siempre son dos. Sepáralos.

¿Por qué molestarse? Porque el día que ese arreglo del login rompa producción, quieres poder hacer git revert de esa corrección sin arrastrar también el refactor del router. Un commit que mezcla cosas no se puede deshacer en parte. O te lo quedas todo, o lo pierdes todo. La granularidad que metes hoy es la libertad que tienes mañana para revertir, revisar y hacer git bisect.

Esto engancha directo con cómo trabajas con la IA: si le pides una sola cosa por sesión, sus diffs ya salen casi atómicos. Si le pides cuatro, tú tendrás que separarlos después. El trabajo fino de partir un cambio grande en commits que cuentan una historia lo desarrollo en la guía de commits atómicos; aquí me quedo con la regla: una idea, un commit.

Diagrama que compara dos historiales de Git: uno con tres commits atómicos donde revertir el primero no afecta a los demás, y otro con un único commit mezclado donde revertir borra también el arreglo que querías conservar.
La diferencia entre un commit atómico y uno mezclado se nota en el momento de revertir: uno se deshace en parte, el otro se pierde entero.

¿Cómo se escribe un mensaje de commit que sirva a tu equipo?

El asunto va en imperativo y describe qué hace el commit; el cuerpo explica por qué. El imperativo no es un capricho de estilo: los propios mensajes que genera Git («Merge branch…», «Revert…») están en imperativo, así que el tuyo encaja con el resto.

Compara estos dos:

# Mal: pretérito, sin contexto, inútil dentro de seis meses
Arreglado el bug del IVA

# Bien: asunto en imperativo + cuerpo con el porqué
Corrige el IVA en facturas de clientes exentos

El total aplicaba el 21% aunque el cliente tuviera
tax_exempt=true. Ahora se comprueba la exención antes
de calcular el tipo. Detectado en la factura #482.

El asunto malo te dice qué pasó. El bueno te dice qué buscar cuando el mismo bug reaparezca. Esa diferencia es la que separa un historial que se lee de uno que se ignora.

Un detalle que ahorra discusiones de equipo: el asunto, corto (apunta a unos 50 caracteres), una línea en blanco, y luego el cuerpo. Esa línea en blanco no es decorativa. Git usa la primera línea como resumen en git log --oneline, en las notificaciones de GitHub y en git blame --porcelain. Si la juntas con el cuerpo, rompes ese resumen.

Secretos fuera del repo: el .gitignore que deberías tener

Un secreto commiteado sigue en la historia aunque lo borres después, así que la única defensa real es que nunca entre. Y entra siempre por el mismo sitio: el .env con la clave de la base de datos o el token de la API que subes «sin querer» junto al resto del cambio.

Un .gitignore mínimo para cualquier proyecto:

# Secretos y entorno: nunca en el repo
.env
.env.*
*.pem
config/credentials.json

# Artefactos y dependencias
node_modules/
dist/
.DS_Store

Si ya has commiteado un .env, añadirlo al .gitignore no lo saca de la historia: Git sigue rastreando lo que ya rastreaba. Tienes que quitarlo del índice con git rm --cached .env, commitear esa salida, y (esto es lo importante) rotar el secreto, porque cualquiera con acceso al historial ya lo ha visto. Un secreto filtrado se considera quemado desde el segundo en que tocó el repo.

Con la IA esto se vuelve más traicionero. Le pides un script de despliegue y te lo devuelve con la contraseña «de ejemplo» hardcodeada, o con un .env.production de regalo. Si aceptas el diff sin mirarlo, ese secreto de ejemplo puede acabar en el repo. Que es la razón de la siguiente sección.

Nombres de rama: una convención que tu equipo pueda leer

Una rama bien nombrada dice de un vistazo qué tipo de cambio es y de qué va, sin que tengas que abrir nada. El patrón que mejor funciona en equipo es tipo/descripción-corta:

# git switch es la forma moderna y estable de crear y cambiar de rama
git switch -c feat/exportar-facturas-pdf

Prefijos habituales: feat/ para funcionalidad nueva, fix/ para correcciones, chore/ para tareas de mantenimiento, docs/ para documentación. Lo importante no es cuál eliges, sino que todo el equipo use el mismo y lo respete. Una convención que solo sigues tú no es una convención.

Uso git switch en lugar de git checkout a propósito. checkout hace demasiadas cosas distintas (cambia de rama, restaura archivos, mueve el HEAD), y esa sobrecarga es una fuente clásica de sustos. git switch solo cambia de rama y git restore solo restaura archivos. Separar esas dos operaciones en dos comandos hace mucho más difícil pisar tu trabajo por error. Cómo encaja cada convención de ramas en un flujo de equipo completo (Gitflow, GitHub Flow, trunk-based) lo comparo en la guía de flujos de trabajo con Git.

Nunca reescribas historia que otros ya tienen

Reescribir un commit que ya está en una rama compartida rompe el historial de todos los que lo tienen. La regla es simple: puedes reescribir lo que solo vive en tu máquina; en cuanto algo está en main o en una rama que otros usan, es historia pública y no se toca.

El peligro concreto tiene nombre: git push --force. Sobrescribe la rama remota pase lo que pase, incluidos los commits que un compañero subió mientras tú trabajabas. Se los borra sin avisar. Existe una versión mucho más segura, --force-with-lease, y esta es la diferencia:

Situación--force--force-with-lease
Comportamiento baseSobrescribe el remoto siempreSobrescribe solo si el remoto está donde tú crees que está
Un compañero subió commits que tú no tienesLos pierde sin avisarFalla y aborta el push, así te enteras
Cuándo tiene sentidoCasi nuncaAl re-subir tu propia rama después de un rebase

--force-with-lease no es magia infalible. Compara el remoto contra tu rama de seguimiento local, y algunos editores hacen git fetch en segundo plano; si eso actualiza tu referencia de seguimiento justo antes del push, el «cerrojo» ya no protege nada. Para blindarlo del todo, Git tiene --force-if-includes, que además exige que hayas integrado localmente lo que hay en el remoto. Pero el hábito que quiero que te lleves es más básico: sustituye --force por --force-with-lease en tu memoria muscular y en los alias del equipo. Ese cambio de una palabra evita la mayoría de los desastres.

Revisa los diffs de la IA antes de commitear

Aceptar un diff generado sin leerlo es la forma más rápida de meter un bug con tu nombre en el git blame. El agente firma la sugerencia; el commit lo firmas tú. Y Git ya trae las herramientas para revisar antes de que nada entre en la historia.

git add -p          # aprueba trozo a trozo, no el archivo entero
git diff --staged   # mira exactamente lo que vas a commitear
git commit

git add -p te presenta el cambio por trozos (hunks) y te pregunta por cada uno si lo quieres. Aquí es donde cazas la línea de más que metió la IA, el console.log olvidado, la dependencia que no pediste. En vez de tragarte doscientas líneas de golpe, apruebas las que entiendes y dejas fuera las que no.

git diff --staged es el último control antes de disparar: muestra lo que está preparado para el commit, ni más ni menos. Si lo que ves ahí no lo sabrías explicar en la revisión de código, no lo commitees todavía. Este par de comandos convierte «confío en que la IA lo hizo bien» en «he visto exactamente qué entra». Con un agente de por medio, ese paso deja de ser opcional.

Diagrama de flujo horizontal que muestra un diff generado por IA pasando por las puertas git add -p y git diff --staged, con los hunks rechazados desviados a un nodo de descarte y los aceptados avanzando hasta git commit y el historial del repositorio.
Un diff de IA no entra directo al historial: pasa por dos puertas de revisión, git add -p (trozo a trozo) y git diff —staged (control final), antes de convertirse en un commit.

Errores comunes que arruinan un historial

El commit «wip» de doscientas líneas. Es el más común y el más caro. Mezcla features, arreglos y ruido en un bloque imposible de revisar y de revertir por partes. La cura es un hábito, no tecnología: commitea cuando termines una idea, no cuando te acuerdes.

El mensaje «fix» o «cambios». No documenta nada. Dentro de un mes, git log es una lista de «fix, fix, cambios, fix» que no le sirve a nadie, empezando por ti.

Creer que git commit -am añade archivos nuevos. No lo hace, y este malentendido cuesta bugs de verdad. El flag -a prepara los archivos modificados o borrados que Git ya estaba rastreando; los archivos nuevos que Git nunca ha visto se quedan fuera hasta que haces git add[1]. Crees que subiste ese utils/pdf.ts recién creado y en realidad se quedó en tu máquina. La build de tu compañero peta con un import que no existe.

--force sobre una rama compartida. Ya tiene su sección entera arriba. Si solo te llevas una cosa de este post, que sea sustituirlo por --force-with-lease.

La checklist del profesional

  • Cada commit contiene un único cambio lógico (si necesitas «y» para describirlo, sepáralo)
  • El asunto del mensaje va en imperativo y el cuerpo explica el porqué
  • .env, *.pem y credenciales están en .gitignore antes del primer commit
  • Las ramas siguen una convención de equipo del tipo feat/descripcion-corta
  • Nunca haces --force sobre una rama compartida; usas --force-with-lease
  • Revisas cada diff de la IA con git add -p y git diff --staged antes de commitear
  • Un secreto que tocó el repo se rota, no solo se borra

Aplica estos siete puntos durante una semana y tu historial pasa de ser un vertedero a ser documentación que tu equipo agradece. Si trabajas en equipo, el siguiente paso es acordar estas reglas entre todos: cómo se revisan los PRs, quién mergea y cuándo, todo eso lo desarrollo en la guía para trabajar en equipo con Git y GitHub.

Leer la checklist es el primer paso; interiorizarla se consigue practicando con un repositorio de verdad. Si quieres montar estos hábitos desde cero, con ejercicios guiados y correcciones sobre commits reales, los trabajamos paso a paso en el curso de Git de cero a profesional.

Si quieres que te avise cuando publique el resto de las guías de esta serie sobre Git, déjame tu correo:

Un concepto nuevo cada semana

Fuentes

  1. git commit (documentación oficial de Git): respalda que el flag -a solo prepara archivos ya rastreados y no añade archivos nuevos.
  2. git switch (documentación oficial de Git): comando estándar para crear (-c) y cambiar de rama; ya no lleva la nota de experimental.
  3. git push (documentación oficial de Git): describe --force-with-lease y cómo comprueba el valor esperado del remoto antes de sobrescribir.
  4. git blame (documentación oficial de Git): el formato por defecto anota hash, autor, fecha y número de línea; el mensaje del commit solo aparece con --porcelain.

Preguntas Frecuentes

¿git commit -a añade los archivos nuevos que he creado?

No. -a (y por tanto -am) solo prepara cambios en archivos que Git ya estaba rastreando: los modificados y los borrados[1]. Un archivo nuevo que nunca has añadido con git add se queda fuera del commit por mucho -a que le pongas. Es uno de los malentendidos más caros entre quienes empiezan con buenas prácticas de Git, porque el commit «parece» completo y no lo está.

¿git blame muestra el mensaje del commit de cada línea?

En su formato por defecto, no: te da el hash abreviado, el autor, la fecha y el número de línea[4]. Para ver el resumen del mensaje asociado a cada línea necesitas git blame --porcelain, que sí incluye el campo summary. Si quieres el mensaje completo, copia el hash que te da blame y haz git show <hash>.

¿git switch sigue siendo experimental?

No. Se introdujo como experimental en 2019, pero es una parte estable y recomendada de Git desde hace años; la nota de «experimental» se retiró de la documentación oficial[2]. Puedes usar git switch y git restore con total confianza en cualquier versión razonablemente actual. git checkout sigue existiendo por compatibilidad, pero para el día a día los dos comandos nuevos son más claros y más seguros.

¿Puedo hacer force push en mi propia rama de feature?

Sí, y es habitual. Después de un rebase o un commit --amend en tu rama personal, tienes que reescribir lo que ya subiste, y ahí el force push es legítimo. Hazlo siempre con --force-with-lease en vez de --force[3]: si nadie más ha tocado la rama, funciona igual; si alguien la tocó, falla y te avisa en lugar de borrar su trabajo. Forzar tu propia rama es legítimo; forzar una que otros usan puede borrar su trabajo.

¿Cada cuánto debo commitear si quiero seguir buenas prácticas de Git?

Cuando termines una idea completa, no por reloj ni por número de líneas. Un commit debería dejar el proyecto en un estado coherente: compila, los tests que había pasan, y el cambio se puede describir en una frase sin «y». Eso suele caer en varias veces al día si trabajas en cosas pequeñas. Si llevas horas sin commitear, casi seguro que ya tienes dentro más de un cambio lógico esperando a que los separes.