Ramas, reset y revert: cómo experimentar con IA sin miedo a romper tu proyecto
En la primera parte de esta guía vimos qué es Git, por qué es tu red de seguridad cuando programas con IA y el flujo básico: status, diff, add y commit.
Ahora vamos con los dos superpoderes que de verdad te quitan el miedo a experimentar:
- Las ramas: para probar cosas sin arriesgar lo que ya funciona.
- Deshacer errores: para volver atrás cuando la IA (o tú) rompe algo.
Dos comandos me han salvado el pellejo más veces de las que me gustaría admitir: git reset y git revert. Al final de este artículo vas a saber exactamente cuándo usar cada uno.
¿Qué es una rama?
Una rama es una línea de trabajo paralela de tu proyecto. Imagina que tu código principal (main) es la versión que funciona y que está en producción. Cuando quieres probar algo nuevo, abres una rama: una copia independiente donde puedes hacer lo que quieras sin afectar a main.
Si el experimento sale bien, lo unes (merge) a main. Si sale mal, borras la rama y aquí no pasó nada.
gitGraph
commit id: "inicio"
commit id: "login"
branch experimento-ia
checkout experimento-ia
commit id: "IA: nuevo menú"
commit id: "IA: ajustes"
checkout main
commit id: "fix: correo"
merge experimento-ia id: "merge del menú"
commit id: "deploy"
En el diagrama, main sigue su camino (hasta se le hace un arreglo) mientras en experimento-ia la IA prueba un menú nuevo. Cuando el menú funciona, se une a main.
Por qué las ramas son perfectas para trabajar con IA
Cada vez que le vas a pedir a un agente algo grande o arriesgado (“migra todo a TypeScript”, “cambia la librería de gráficos”, “refactoriza el módulo de pagos”), hazlo en una rama. Si el resultado no te convence, ni siquiera tienes que deshacer nada: cambias a main y borras la rama.
Los comandos de ramas que vas a usar
| Qué quieres hacer | Comando |
|---|---|
Ver las ramas (la actual tiene un *) | git branch |
| Crear una rama y cambiarte a ella | git switch -c nombre-rama |
| Cambiarte a una rama que ya existe | git switch nombre-rama |
| Unir una rama a la rama en la que estás | git merge nombre-rama |
| Borrar una rama ya unida | git branch -d nombre-rama |
| Borrar una rama que no se unió (descartar el experimento) | git branch -D nombre-rama |
Si has visto tutoriales viejos, seguro te encontraste git checkout -b. Funciona igual, pero git switch (disponible desde Git 2.23) es más claro porque solo sirve para cambiar de rama, mientras que checkout hace demasiadas cosas distintas.
El flujo completo, paso a paso
# 1. Desde main, crea una rama para el experimento
git switch -c feature/menu-nuevo
# 2. Trabaja (tú o la IA) y guarda los cambios
git add .
git commit -m "feat: rediseñar menú de navegación"
# 3. ¿Funcionó? Vuelve a main y une los cambios
git switch main
git merge feature/menu-nuevo
# 4. Borra la rama, ya no la necesitas
git branch -d feature/menu-nuevo
¿No funcionó? Entonces el paso 3 es solo git switch main y el 4 es git branch -D feature/menu-nuevo. Experimento descartado, proyecto intacto.
Ponle nombres que digan algo
| ❌ Evita | ✅ Mejor |
|---|---|
pruebas, pruebas2, pruebas3 | feature/login-con-google |
cambios-final | fix/menu-movil-se-corta |
feature1_v2_fix_final | experimento/migracion-typescript |
Cuando dos cambios chocan: conflictos de merge
Tarde o temprano te va a pasar: en main y en tu rama se modificó la misma línea del mismo archivo. Git no puede adivinar cuál versión es la correcta, así que se detiene y te pregunta. Eso es un conflicto, y no es un error: es Git siendo prudente.
El archivo queda marcado así:
<<<<<<< HEAD
const titulo = "Bienvenido";
=======
const titulo = "Hola de nuevo";
>>>>>>> feature/menu-nuevo
- Lo que está entre
<<<<<<< HEADy=======es la versión de la rama donde estás (main). - Lo que está entre
=======y>>>>>>>es la versión de la rama que estás uniendo.
Para resolverlo: edita el archivo, deja la versión correcta (o una combinación), borra las marcas y guarda:
git add archivo.js
git commit
Editores como VS Code te muestran botones para elegir una versión u otra. Y sí, también puedes pedirle a la IA que te ayude, pero lee lo que propone: decidir cuál cambio es el correcto requiere entender qué hace cada uno.
Deshacer errores: el mapa completo
Aquí es donde mucha gente se enreda, porque Git tiene varias formas de deshacer y cada una sirve para un momento distinto. Esta tabla es el resumen que me hubiera gustado tener cuando empecé:
| ¿Qué te pasó? | Comando | ¿Pierdes algo? |
|---|---|---|
| Cambiaste un archivo y quieres dejarlo como en el último commit | git restore archivo.js | ⚠️ Sí, los cambios no guardados |
Hiciste git add de algo que no querías | git restore --staged archivo.js | No |
| Te equivocaste en el mensaje del último commit (y no lo has compartido) | git commit --amend -m "nuevo mensaje" | No |
| Quieres deshacer commits que solo están en tu máquina | git reset | Depende del modo (ver abajo) |
| Quieres deshacer un commit que ya compartiste | git revert <hash> | No, queda en el historial |
Hiciste un reset --hard y te arrepentiste | git reflog | Casi siempre puedes recuperarlo |
Vamos con los dos protagonistas.
git reset: la máquina del tiempo que reescribe la historia
git reset mueve tu rama a un commit anterior, como si los commits posteriores nunca hubieran existido. Tiene tres modos, y la diferencia está en qué pasa con tus archivos:
| Modo | Historial | Staging | Tus archivos | Cuándo usarlo |
|---|---|---|---|---|
--soft | Retrocede | Conserva los cambios preparados | Intactos | Quieres rehacer el último commit (por ejemplo, unir varios en uno) |
--mixed (el modo por defecto) | Retrocede | Se vacía | Intactos | Quieres deshacer el commit y volver a elegir qué agregar |
--hard | Retrocede | Se vacía | ⚠️ Se pierden los cambios | Quieres borrar todo y volver exactamente a ese punto |
Ejemplos:
git reset --soft HEAD~1 # deshace el último commit, conserva todo preparado
git reset HEAD~1 # deshace el último commit, conserva los archivos
git reset --hard a3f9c21 # vuelve exactamente al commit a3f9c21 y borra lo posterior
HEAD~1 significa “un commit antes del actual”. Y el hash (a3f9c21) lo sacas de git log --oneline.
⚠️ La regla de oro: usa reset solo en commits que no has compartido. Si ya hiciste push y alguien más trabaja sobre esa rama, reescribir la historia le va a romper el repositorio a tus compañeros. Y git reset --hard es un botón de autodestrucción para tus cambios sin guardar: piénsalo dos veces.
git revert: deshacer con responsabilidad
Si reset borra el pasado, revert lo respeta. En vez de eliminar el commit problemático, crea un commit nuevo que hace exactamente lo contrario. El error sigue en el historial, pero anulado.
gitGraph
commit id: "login"
commit id: "pagos (con bug)"
commit id: "menú"
commit id: "Revert pagos" type: HIGHLIGHT
git log --oneline # busca el hash del commit con el error
git revert 7be0d14 # crea un commit que anula 7be0d14
Git abre un editor para que escribas el mensaje del revert. Sé humano: “Revierte los pagos: causaban cobros dobles en producción. Se corrige en otra rama.”
Úsalo siempre que el commit ya esté compartido (en GitHub, en main, en producción). Nadie pierde nada y queda registro de qué se deshizo y por qué.
Reset vs. revert en una tabla
| Situación | ¿Reset o revert? |
|---|---|
| Trabajo local, antes de hacer push | ✅ reset |
Rama compartida o main | ✅ revert |
| Quieres borrar por completo los cambios | ✅ reset --hard (con cuidado) |
| Quieres conservar el historial y deshacer un cambio puntual | ✅ revert |
git reflog: tu última esperanza
¿Hiciste un reset --hard y borraste algo que sí necesitabas? Respira. Git guarda un registro de todos los movimientos de tu rama, incluso los que ya no aparecen en git log. Se llama reflog, y por defecto conserva unos 90 días de historia.
git reflog
a3f9c21 HEAD@{0}: reset: moving to a3f9c21
e81b4d2 HEAD@{1}: commit: feat: agregar pagos con tarjeta
7be0d14 HEAD@{2}: commit: fix: corregir validación del correo
¿Ves el commit e81b4d2 que “borraste”? Sigue ahí. Para recuperarlo:
git reset --hard e81b4d2
Ojo: el reflog solo recuerda commits. Si nunca hiciste commit de un cambio y lo borraste con restore o reset --hard, ese cambio sí se perdió. Otra razón para hacer commits pequeños y frecuentes.
Práctica guiada: rompe cosas a propósito
La mejor forma de perderle el miedo a Git es romper algo en un proyecto de prueba. Abre una terminal:
# Prepara un repositorio de juguete
mkdir practica-git && cd practica-git
git init
echo "versión buena" > app.txt
git add . && git commit -m "feat: versión inicial"
# Ejercicio 1: revert
echo "código con bug" >> app.txt
git commit -am "feat: cambio con bug"
git revert HEAD --no-edit # anula el último commit
cat app.txt # vuelve a decir "versión buena"
git log --oneline # el bug y su revert quedan en la historia
# Ejercicio 2: reset + reflog
echo "experimento" > prueba.txt
git add . && git commit -m "feat: experimento"
git reset --hard HEAD~1 # el experimento desaparece
git reflog # ...pero aquí sigue
git reset --hard HEAD@{1} # y lo recuperas
Hazlo una vez y nunca más vas a sentir pánico frente a la terminal.
Bonus: varios agentes trabajando al tiempo con worktrees
Si ya estás en un nivel donde pones a dos agentes de IA a trabajar en paralelo, hay un problema: los dos estarían editando la misma carpeta. Para eso existe git worktree, que crea una segunda carpeta de trabajo conectada al mismo repositorio, cada una en su propia rama:
git worktree add ../mi-proyecto-pagos -b feature/pagos
Ahora tienes mi-proyecto (en main) y mi-proyecto-pagos (en feature/pagos). Un agente trabaja en cada carpeta sin pisarse. Cuando terminas, unes la rama como siempre y eliminas la carpeta extra con git worktree remove ../mi-proyecto-pagos.
En resumen
- Una rama por experimento. Si sale bien,
merge; si sale mal,git branch -Dy listo. - Los conflictos no son errores: son Git pidiéndote que decidas.
restorepara cambios sin guardar,resetpara commits locales,revertpara commits compartidos yreflogpara cuando todo lo demás falla.- Commits pequeños y frecuentes son la mejor póliza de seguro.
Es la misma lógica de trabajar en unidades pequeñas y verificables que defendí en desarrollo modular con IA. Y algo más: antes de pedirle a la IA que “reescriba todo desde cero” en una rama, recuerda la lección de Netscape que conté en La IA abarató el conocimiento, no el criterio. Que algo se pueda deshacer con un comando no significa que sea buena idea hacerlo.
Git no es solo una herramienta técnica: también es una herramienta para pensar. Aprende a equivocarte y a revertir con clase.
Fuentes y lecturas recomendadas
- Pro Git (libro oficial, gratuito y en español): capítulo de ramificaciones y el resto del libro.
- Documentación oficial de Git: git branch, git switch, git merge, git reset, git revert, git reflog y git worktree.
- GitHub Docs: Resolver un conflicto de fusión mediante la línea de comandos.
- Artículos relacionados en este blog:
Ideas, sistemas y lecturas de diseño web que merecen ser probadas
Guía sencilla de Git para quienes programan con IA: qué es un sistema de control de versiones, la diferencia entre Git y GitHub, las tres áreas de Git, el flujo básico (init, add, commit, log) y una rutina para que el agente no te destruya el proyecto.
Aprende a diseñar la arquitectura de tu sitio web: silos temáticos, profundidad de clics vs URLs, navegación facetada sin problemas de indexación y migas de pan con Schema.
Análisis sencillo del paper Transformer de 2017: qué problema resolvió, cómo funciona la atención (Query, Key, Value), por qué cambió la IA y cinco formas prácticas de aprovechar ese conocimiento para escribir mejores prompts.
