Revisar código generado por IA con Git como red de seguridad
Un flujo Git para revisar código generado por IA: checkpoint antes del agente, leer el diff, commits pequeños y revert barato para deshacer sin drama.
El agente responde «hecho, ya funciona» y ha tocado catorce archivos. Puedes leer los catorce diffs o puedes creerle. La segunda opción es el error más caro que se comete hoy en desarrollo asistido, y revisar código generado por IA con Git es lo que lo hace barato. Git no evita que el modelo se equivoque. Convierte tu desconfianza en algo casi gratis: un checkpoint al que volver, un diff que no miente y un revert de un solo comando.
¿Por qué revisar el diff de la IA es la habilidad de mayor impacto hoy?
Porque el modelo ya escribe la sintaxis más rápido que tú; lo que no puede hacer por ti es decidir si ese cambio debe entrar en tu código. Ese juicio es tu trabajo ahora.
El agente te cuenta una historia: “he refactorizado el middleware de auth y actualizado los tests”. Suena bien. Pero la narración y el cambio real son dos cosas distintas, y solo una compila. Un agente que dice haber tocado el token de sesión puede haber cambiado también, de paso, el timeout por defecto porque le pareció “más consistente”. El resumen no lo menciona. El diff sí.
Cuando el coste de teclear tiende a cero, el cuello de botella se mueve a la revisión. Un senior con criterio que lee diffs rápido rinde más que otro que escribe rápido. Ese es el patrón completo del desarrollo asistido con Git: el modelo produce, tú verificas, y Git guarda cada estado por si hay que retroceder.
¿Por qué hacer commit antes de lanzar al agente?
Porque un árbol limpio es el único punto de retorno conocido. Si el agente destroza algo, quieres volver a un estado del que estás seguro, y ese estado tiene que existir antes de que empiece el desastre.
El ritual es de dos comandos:
git status # nothing to commit, working tree clean
git add -A && git commit -m "checkpoint antes del refactor de auth"
Fíjate en el git add -A. Un git commit -am no basta aquí: -a solo prepara modificaciones y borrados de archivos que Git ya trackea, nunca los nuevos sin trackear. Si tenías un archivo a medias sin añadir, -am lo dejaría fuera y tu “checkpoint” no sería completo. Con -A entra todo, y git status te confirma el árbol limpio.
Lanzar al agente sobre un árbol sucio es empezar con deuda. Si arrancas con cambios tuyos sin commitear, el diff que leas después mezclará tu trabajo con el del agente y no podrás separar quién tocó qué. Commit o git stash primero. Siempre.
¿Cómo leer lo que la IA cambió de verdad, no lo que dice que cambió?
Con git diff, que compara byte a byte tus cambios sin preparar contra lo que Git ya tiene registrado en el índice, sin pasar por el filtro de la narración del agente. Justo después de un checkpoint limpio ese índice coincide con el último commit, así que lees exactamente lo que el agente tocó. Si en algún momento ya has preparado hunks con git add, usa git diff HEAD para ver todo lo cambiado desde el checkpoint (preparado y sin preparar). Empieza por el panorama y baja al detalle:
git diff --stat # qué archivos y cuántas líneas por archivo
git diff # el cambio real, hunk a hunk
git diff src/auth/ # acota la lectura a una carpeta
git diff --stat te dice de un vistazo si “un pequeño ajuste” fueron 12 líneas o 800 repartidas en catorce archivos. Esa cifra ya te dice cuánto desconfiar. Luego lees los hunks. Un hunk que no entiendes es un hunk que no puedes aprobar, por muy convincente que suene el resumen.
Una trampa concreta: git diff no muestra los archivos nuevos que el agente creó si siguen sin trackear. Compara contra lo que Git ya conoce, y un archivo recién nacido no está en ese índice. Por eso git status es tu primer control: lista los archivos sin trackear aparte. Si además quieres ver el contenido de ese archivo dentro del diff, git add -N archivo.nuevo lo registra como “por añadir” (con contenido vacío en el índice) y a partir de ahí git diff lo enseña entero.
Y una tentación que hay que cortar: no uses git blame para reconstruir “qué pretendía” el agente. git blame te da el hash, el autor, la fecha y la línea, nunca el mensaje del commit ni la intención detrás. Para el porqué de un cambio, git show <hash> o git log te dan el mensaje completo.
¿Por qué commits pequeños y revisables ganan a un mega-commit del agente?
Porque la superficie que puedes revisar de verdad es pequeña, y un commit que mezcla seis intenciones no la respeta. Cuando el agente entrega 300 líneas en un solo bloque, revisar entero es agotador, así que la mayoría no revisa: aprueba. Ahí es donde entran los bugs.
La herramienta para trocear es git add -p. Te presenta el cambio hunk a hunk y decides cuál va a cada commit:
git add -p # y para cada hunk: y / n / s (split) / q
git commit -m "auth: extrae validación de token a un helper"
git add -p
git commit -m "auth: sube el timeout de sesión a 30 min"
El resultado es un historial donde cada commit cuenta una sola cosa y se puede revertir solo. Si mañana el timeout de sesión resulta ser un error, lo tiras sin arrastrar el refactor del helper. Esta disciplina merece su propio espacio; la desarrollo en commits atómicos y buenas prácticas. Aplicada a diffs de IA, su valor es doble: acota lo que revisas y acota lo que puedes deshacer.
Pruébalo tú: lee un diff de un agente y decide qué entra en cada commit.
Cargando ejercicio...
¿Cómo deshacer lo que la IA rompió sin drama?
Con el comando correcto según dónde esté el trabajo: en tu disco, en el staging o ya compartido. El coste de tirar lo que el agente hizo es casi cero si eliges bien.
| Comando | Qué deshace | Cuándo usarlo | ¿Seguro tras compartir? |
|---|---|---|---|
git restore <archivo> | Descarta los cambios sin preparar de ese archivo en el working tree | El agente tocó un archivo y quieres el estado del último commit | Sí, es puramente local |
git restore --staged <archivo> | Saca el archivo del staging pero conserva el cambio en disco | Preparaste algo con git add y quieres quitarlo del próximo commit | Sí, es local |
git reset --hard <hash> | Mueve la rama a <hash> y borra todo lo posterior en el índice y el working tree | Volver al checkpoint limpio de antes del agente, tirando su trabajo entero | No: reescribe historia; peligroso si ya hiciste push |
git revert <hash> | Crea un commit nuevo que invierte los cambios de <hash> | Deshacer un commit que ya está en el remoto | Sí, no reescribe la historia |
La regla mental es sencilla. Si el trabajo del agente sigue solo en tu máquina, git reset --hard a1b2c3d te devuelve al checkpoint y es lo más limpio que hay. Si esos commits ya salieron en un push, reset --hard reescribiría una historia que tus compañeros ya tienen, y su próximo pull se romperá. Para eso está git revert: registra un commit que invierte el cambio, sin borrar nada del pasado.
¿Cómo aislar al agente con git worktrees?
Con git worktree, que te da varios directorios de trabajo sobre el mismo repositorio, cada uno en su propia rama. El agente trabaja en uno mientras tu directorio principal sigue exactamente donde lo dejaste.
git worktree add -b agente-refactor ../repo-agente-refactor
Ese comando crea la rama agente-refactor y la saca en el directorio hermano ../repo-agente-refactor. Apuntas al agente ahí, y pase lo que pase en esos archivos, tu carpeta principal no se entera: sin git stash, sin cambiar de rama, sin pisarte. Cuando el diff te convence, mergeas; cuando no, borras el worktree con git worktree remove y no ha pasado nada. Este patrón da para mucho cuando corres varios agentes en paralelo, y lo detallo en worktrees con Claude Code.
El flujo de revisión en cinco pasos
Todo lo anterior se resume en un hábito que aplicas cada vez que le pasas trabajo a un agente:
- Checkpoint:
git statuslimpio y un commit antes de que el agente escriba una sola línea - Lanzar: una tarea acotada, no “arréglalo todo de una vez”
- Diff:
git diff --statpara el panorama ygit diffpara leer hunk a hunk lo que cambió de verdad - Trocear:
git add -ppara separar el cambio en commits pequeños, cada uno con su mensaje - Verificar o revertir: pasa los tests; si algo huele mal,
git reset --hardal checkpoint ogit revertsi ya lo compartiste
Cinco pasos que, con práctica, tardas menos en ejecutar que en leer el resumen del agente. Si quieres interiorizarlo con ejercicios reales, lo trabajo entero en el curso Git de cero a profesional.
Errores comunes
Aceptar el resumen del agente sin leer el diff
El agente narra lo que quería hacer. El diff enseña lo que hizo. Cuando divergen, gana el diff.
Lanzar al agente sobre un árbol sucio
Empiezas con cambios tuyos sin commitear y el diff resultante mezcla tu trabajo con el del agente. Ya no distingues quién tocó qué, que es justo lo que necesitabas distinguir. Commit o stash antes de arrancar.
Un commit gigante con seis intenciones dentro
Si el commit toca auth, logging, un typo del README y dos features, no puedes revertir uno sin llevarte los otros. Trocea con git add -p.
git reset —hard sobre algo que ya compartiste
reset --hard reescribe la historia local. Si esos commits ya están en el remoto, el próximo pull de tus compañeros chocará contra una historia que no reconocen. Para deshacer algo ya empujado, git revert crea un commit que invierte el cambio sin tocar el pasado.
Fiarte de git blame para saber qué pretendía un cambio
git blame da hash, autor, fecha y línea, y nada más. No verás ahí el mensaje del commit ni el razonamiento del agente. Para eso, git show <hash>.
Preguntas Frecuentes
¿Al revisar código generado por IA con Git, git diff me muestra los archivos nuevos del agente?
No mientras sigan sin trackear. git diff compara contra lo que Git ya trackea, así que un archivo recién creado por el agente no aparece hasta que lo registras. git status sí los lista aparte. Si además quieres ver su contenido dentro del diff, git add -N archivo.nuevo lo marca como pendiente de añadir y entonces git diff lo muestra.
¿Uso git reset —hard o git revert para deshacer al agente?
Depende de si el commit ya salió de tu máquina. Si el trabajo del agente sigue siendo local, git reset --hard <hash> te devuelve al checkpoint y es lo más limpio. Si ya hiciste push, usa git revert, que invierte el cambio con un commit nuevo sin reescribir una historia que otros ya tienen.
¿Worktree o rama normal para aislar un agente?
Una rama normal basta si trabajas de una cosa cada vez y no te importa cambiar de contexto. El worktree gana cuando quieres que el agente opere en su directorio mientras tú sigues en el tuyo sin cambiar de rama ni hacer stash, y sobre todo cuando corres varios agentes a la vez, cada uno con su árbol de archivos aislado.
¿Cada cuánto hago commit al revisar código generado por IA con Git?
Un commit por intención completa que ya has validado con el diff. En la práctica, después de cada tarea acotada que el agente termina y tú apruebas leyendo los hunks. Commits frecuentes y pequeños son lo que hace toda esta red de seguridad barata: cuanto más fino trocees, menos duele tirar lo que no sirve.