Revisión de Código Generado por IA con Difftastic
Usa Difftastic para revisar código generado por IA con diffs estructurales, integrarlo en git y aislar cambios de comportamiento del formato.
Las herramientas de codificación con IA suelen combinar un cambio de lógica real con un reformateo masivo en un único commit, y un git diff basado en líneas ahoga la única línea que modifica el comportamiento en una pantalla de rojo y verde. Difftastic es una herramienta de diff estructural que analiza el código en árboles de sintaxis y compara los árboles en lugar del texto, de modo que el reformateo puro, el reajuste de líneas y los cambios de espaciado se registran como sin cambios, dejando únicamente las ediciones que alteran el comportamiento. Este artículo explica qué es difftastic, cómo integrarlo en git y un flujo de trabajo concreto para revisar los commits que genera un agente.
Conclusiones Clave
- Difftastic compara el árbol de sintaxis abstracto mediante tree-sitter, por lo que el reformateo y el reajuste de líneas no aparecen como cambios, mientras que un nuevo argumento sí se detecta como tal.
- Difftastic admite más de 30 lenguajes y recurre a un diff orientado a líneas con resaltado de palabras cuando encuentra extensiones no reconocidas o archivos con errores de análisis sintáctico.
- Configúralo con
[diff] external = difften~/.gitconfigy luego lee el commit de un agente congit show <commit> --ext-diff. La configuración recomendada de git cambió en difftastic 0.61 (octubre de 2024), así que cópiala directamente desde el manual. - Difftastic es una herramienta de diff externo, no un paginador de git, por lo que conviene combinarlo con delta para la visualización cotidiana y recurrir a difftastic en los diffs de IA con mucho reformateo.
difft --check-only --exit-codeactúa como filtro en un commit respondiendo a la pregunta: “¿este cambio modifica el comportamiento o es solo reformateo?”
El problema: los diffs de IA ocultan la línea que importa
Los agentes y asistentes como Cursor, GitHub Copilot y Claude Code reformatean con frecuencia una función completa —o redistribuyen una llamada larga en varias líneas— en el mismo commit en que modifican una condición. Un diff orientado a líneas no puede distinguir la diferencia: marca cada línea tocada como modificada. El resultado es una pared de rojo y verde, y la única edición que altera el comportamiento en tiempo de ejecución queda enterrada en algún punto de ese muro. Revisar código generado por IA es exactamente la situación en la que la relación señal-ruido más importa, porque el reformateo es ruido generado por la máquina y el cambio de comportamiento es aquello de lo que eres responsable al hacer el merge.
¿Qué es difftastic?
Discover how at OpenReplay.com.
Difftastic es un diff estructural que compara archivos basándose en su sintaxis en lugar de su texto. Analiza cada versión con tree-sitter, construye un árbol de sintaxis abstracto y compara los árboles. La consecuencia práctica: si reformateas código de modo que ahora ocupa varias líneas, difftastic muestra únicamente lo que realmente cambió, y un bloque movido o renombrado se reporta como un movimiento en lugar de una eliminación más una adición.
Difftastic está escrito en Rust, fue creado por Wilfred Hughes y es de código abierto bajo la licencia MIT. Admite más de 30 lenguajes de programación mediante parsers de tree-sitter —no los “50+” que afirman algunas reseñas—. Cuando un archivo tiene una extensión no reconocida, degrada de forma elegante a un diff orientado a líneas con resaltado de palabras, de modo que nada falla en lenguajes que no puede analizar.
Instalar difftastic e integrarlo en git
Instala el binario difft mediante un gestor de paquetes o cargo, y luego regístralo como diff externo de git:
# macOS
brew install difftastic
# Toolchain de Rust (requiere Rust 1.85+ a partir de la versión 0.69)
cargo install difftastic
Para un uso puntual, pasa la configuración en línea sin modificar nada de forma permanente:
git -c diff.external=difft diff
git -c diff.external=difft show --ext-diff
Para establecer difftastic como opción predeterminada, añade esto a ~/.gitconfig, directamente desde el manual:
[diff]
external = difft
Esto hace que git diff use difftastic; los demás subcomandos solo necesitan el flag --ext-diff, por ejemplo git show --ext-diff y git log -p --ext-diff. La configuración recomendada cambió en difftastic 0.61 (octubre de 2024), así que si estás copiando un fragmento de un blog antiguo, sustitúyelo por la versión actual del manual. Prefiere la salida en línea frente a la presentación en dos columnas predeterminada con --display inline:
difft old.js new.js --display inline
¿Por qué difftastic es la mejor opción para revisar código de IA?
El diff estructural se centra en los nodos de sintaxis modificados y elimina el ruido de las ediciones no esenciales. La demostración más clara es el caso de reformateo más un argumento adicional. Supongamos que un agente toma una firma de función de una sola línea y, porque ahora supera el límite de longitud de línea, un formateador la distribuye en varias líneas —y el agente añade un argumento:
// antes
function createUser(name, email) {}
// después
function createUser(
name,
email,
role,
) {}
Un diff de líneas resalta el bloque completo, porque cada línea cambió textualmente. Difftastic resalta únicamente el nuevo argumento role —la única edición que modifica el comportamiento—. Es precisamente el tipo de adición sutil que un agente puede colar a un revisor que está hojeando un diff ruidoso. La misma lógica se aplica a las extracciones: cuando un agente mueve un bloque a una nueva función auxiliar, difftastic marca el nuevo nombre de función como añadido en lugar de mostrar el envoltorio y el cuerpo como una enredada eliminación más adición.
Un flujo de trabajo de revisión de commits para la salida de agentes
Para leer únicamente los cambios semánticos que produjo un agente, apunta a su commit exacto:
git show <agent-commit> --ext-diff
# o revisa toda la rama
git log -p --ext-diff main..agent-branch
Busca tres cosas: las adiciones y eliminaciones que difftastic marca realmente como cambios; los bloques reportados como movimientos o renombrados en lugar de reescrituras; y cualquier fragmento que revierta a un diff de líneas plano —esa es la señal de que difftastic encontró una extensión no reconocida o un error de análisis sintáctico—. Por defecto, difftastic recurre a un diff orientado a líneas cuando encuentra errores de análisis, una elección conservadora para que nunca afirme que dos archivos sintácticamente diferentes son iguales. Esto es relevante para la salida de IA a mitad de una refactorización, que puede no analizarse correctamente; aumenta la tolerancia con export DFT_PARSE_ERROR_LIMIT=20 si un archivo casi válido recurre al fallback innecesariamente.
Para la automatización, difftastic puede comprobar si dos archivos comparten el mismo AST sin renderizar un diff:
difft --check-only --exit-code before.js after.js
Esto establece el código de salida en 0 cuando no hay cambios sintácticos y en 1 cuando los hay —un filtro rápido para un hook pre-merge o un paso de CI que responde a la pregunta “¿el agente cambió el comportamiento o solo reformateó?”—.
Limitaciones y combinación de difftastic con delta
Hay que ser honesto sobre las compensaciones. Difftastic escala relativamente mal en archivos con un gran número de cambios y puede consumir mucha memoria, así que trátalo como una herramienta de revisión para commits específicos, no como un reemplazo total de git diff. Su presentación en dos columnas suele ser buena, pero ocasionalmente puede resultar confusa. Es una herramienta de diff externo, no un paginador de git, y no se renderiza dentro de la pestaña de archivos de un PR en GitHub ni en la mayoría de los paneles de diff de los IDEs —es una herramienta de línea de comandos local—.
La solución práctica es usar ambas. Mantén un paginador de texto rápido para la visualización cotidiana y cambia a difftastic para los diffs complicados con mucho reformateo.
| Herramienta | Tipo de diff | ¿Funciona como paginador? | Ideal para |
|---|---|---|---|
| difftastic | Estructural (AST) | No (solo diff externo) | Diffs de IA con mucho reformateo |
| delta | Texto con resaltado sintáctico | Sí | Diffs cotidianos |
| diff-so-fancy | Texto embellecido | Sí | Limpieza ligera |
Delta y diff-so-fancy están basados en texto; ninguno realiza diff de AST. Usa delta como paginador predeterminado y recurre a difftastic cuando el diff está ahogado en ruido de formateo.
Un diff estructural limpio es un filtro pre-merge: detecta la línea que cambia el comportamiento antes de que apruebes el cambio. Las modificaciones que aun así se escapan —la edición de lógica sutil que un diff ruidoso de IA ocultó— son las que acabas reconstruyendo después de que se despliegan en producción, y revisar una reproducción de sesión de la interacción fallida es una de las formas más directas de detectar esa clase de regresión. Configura [diff] external = difft hoy mismo, luego revisa tu próximo commit de agente con git show <commit> --ext-diff y lee únicamente lo que cambió.
Preguntas Frecuentes
¿Cuál es la diferencia entre difftastic y delta?
Difftastic es un diff estructural que analiza el código con tree-sitter y compara árboles de sintaxis abstractos, de modo que el reformateo y el reajuste de líneas no se registran como cambios. Delta es un paginador basado en texto con resaltado sintáctico que sigue comparando líneas. Difftastic no puede actuar como paginador de git y solo funciona como herramienta de diff externo, mientras que delta funciona como paginador para la visualización cotidiana. Usa delta por defecto y difftastic para los diffs de IA con mucho reformateo.
¿Qué ocurre cuando difftastic encuentra un archivo que no puede analizar?
Difftastic recurre a un diff orientado a líneas con resaltado de palabras en dos casos: cuando un archivo tiene una extensión no reconocida y cuando encuentra errores de análisis sintáctico. El fallback por errores de análisis es una elección deliberada y conservadora para que difftastic nunca afirme que dos archivos sintácticamente diferentes son iguales. Esto es relevante para la salida de IA a mitad de una refactorización, que puede no analizarse correctamente. Aumenta la tolerancia con la variable de entorno DFT_PARSE_ERROR_LIMIT cuando un archivo casi válido recurre al fallback innecesariamente.
¿Puede difftastic mostrar diffs dentro de la pestaña de archivos de un PR en GitHub?
No. Difftastic es una herramienta de línea de comandos local que funciona como herramienta de diff externo de git, no como capa de renderizado dentro de la pestaña de archivos de un PR en GitHub ni en la mayoría de los paneles de diff de los IDEs. Se ejecuta mediante comandos como git show con el flag --ext-diff o git log -p --ext-diff. Existen integraciones de terceros para algunas herramientas como magit, pero el soporte en pestañas de PR e IDEs es limitado, por lo que difftastic se trata mejor como un paso de revisión en la terminal.
¿Cómo puedo comprobar si un commit de IA cambió el comportamiento o solo reformateó el código?
Ejecuta difft con los flags --check-only y --exit-code sobre las dos versiones de un archivo. Difftastic comprueba si los archivos comparten el mismo árbol de sintaxis abstracto sin renderizar un diff, estableciendo el código de salida en 0 cuando no hay cambios sintácticos y en 1 cuando los hay. Esto es mucho más rápido que un diff completo y constituye un filtro limpio para un hook pre-merge o un paso de CI que distingue los cambios de comportamiento reales del reformateo puro.