Comparador de texto (Diff)
Compara dos textos y encuentra las diferencias al instante.
Acerca de la comparación de textos
Esta herramienta de diff usa el algoritmo de la subsecuencia común más larga (LCS) para comparar dos textos línea a línea. Las adiciones se resaltan en verde y las eliminaciones en rojo. Elige la vista «En línea» para ver todos los cambios en una sola columna, o «Lado a lado» para comparar los textos original y modificado en paralelo.
Usos habituales
- Comparar cambios de código antes de confirmar
- Revisar documentos o contratos modificados
- Verificar diferencias de traducción
- Validar cambios en archivos de configuración
- Comparar respuestas de API
Preguntas frecuentes
¿Compara carácter a carácter?
Esta herramienta compara línea a línea. Si una línea tiene el más mínimo cambio (aunque sea un solo carácter), toda la línea se marca como modificada. Es el mismo enfoque que usan Git y la mayoría de las herramientas de diff.
¿Hay un límite de tamaño?
No hay un límite estricto, pero los textos muy voluminosos (más de 10 000 líneas) pueden tardar un momento en procesarse, ya que la comparación se ejecuta íntegramente en tu navegador.
Qué significa realmente «diff»
Un diff describe cómo convertir un texto en otro usando el menor conjunto de inserciones y eliminaciones. Hay infinitas maneras de hacerlo; la trivial es «borra cada carácter de A y luego inserta cada carácter de B». Un diff útil es la secuencia de edición más corta, que es el dual del problema de la subsecuencia común más larga: encontrar la secuencia más larga de líneas que aparece (en orden) en ambos textos; todo lo demás es una adición o una eliminación. La mayoría de los algoritmos de diff no son más que algoritmos de LCS con otro disfraz.
Un matiz sutil: la subsecuencia común más larga no es la subcadena común más larga. Una subsecuencia conserva el orden pero no la adyacencia, así que «ABCDE» y «AXBYCZD» comparten la subsecuencia «ABCD» aunque ninguna secuencia contigua de tres caracteres aparezca en ambas.
Una breve historia de los algoritmos de diff
El primer programa de comparación de archivos de uso generalizado fue el diff de Unix, escrito por Douglas McIlroy en los Bell Labs, con el algoritmo subyacente publicado por James W. Hunt y McIlroy como Informe Técnico de Ciencias de la Computación n.º 41 de los Bell Labs en junio de 1976. El propio McIlroy describió los cuatro meses de desarrollo como «un esfuerzo desesperado». El enfoque de Hunt-McIlroy calculaba el hash de cada línea del archivo B, indexaba dónde aparecía cada línea única y buscaba la cadena de coincidencias monótonamente creciente más larga. Se incluyó en la Versión 6 de Unix y siguió siendo esencialmente el mismo algoritmo en /usr/bin/diff en la mayoría de los sistemas Unix durante décadas.
Eugene W. Myers publicó el estándar moderno del sector en 1986: «An O(ND) Difference Algorithm and Its Variations», en Algorithmica vol. 1, n.º 2. Myers replanteó la LCS como un problema de camino más corto a través de un grafo de edición: coloca A en el eje superior y B en el lateral, dibuja una diagonal siempre que dos líneas coincidan y busca el camino desde la esquina superior izquierda hasta la inferior derecha con el menor número de aristas no diagonales. Cada arista no diagonal es una inserción o una eliminación; cada diagonal es gratis. Y lo más importante: el algoritmo se ejecuta en un tiempo de O((N+M)·D), donde D es el tamaño de la secuencia de edición; es decir, se vuelve más rápido cuanto más se parecen los archivos. Para los diffs habituales de control de versiones, D es minúsculo en comparación con N+M, por lo que Myers es, en la práctica, mucho más rápido que el peor caso O(N·M). Su artículo también incluye un refinamiento de espacio lineal mediante un truco de «middle snake» de tipo divide y vencerás. El algoritmo de Myers es el predeterminado tras GNU diff, git diff, Mercurial, Subversion, jsdiff, el módulo difflib de Python y la mayoría de los visores de diff con interfaz gráfica.
Bram Cohen (más tarde más conocido como el inventor de BitTorrent) diseñó patience diff para el sistema de control de versiones Bazaar alrededor de 2002. El problema que lo motivó: el diff de Myers alinea cualquier línea coincidente, incluidas las muy comunes, así que mover una función en C puede producir un diff ruidoso en el que la llave de cierre de la función movida se alinea con la llave de cierre de una función no relacionada. El patience diff ancla el diff en las líneas que aparecen exactamente una vez en cada archivo (normalmente firmas de función, cabeceras de comentario, mensajes de registro distintivos), calcula la LCS solo de esas anclas mediante patience sort y aplica la recursión a los huecos. El resultado se alinea en líneas significativas y se lee mejor para el código fuente. Git lo admite mediante git diff --patience. El histogram diff es un refinamiento añadido a git alrededor de 2010 que construye un histograma de apariciones de líneas y prefiere anclas de baja frecuencia en lugar de las estrictamente únicas; a partir de git 2.45 es el predeterminado en muchas configuraciones.
Levenshtein frente a LCS
Un concepto relacionado que conviene distinguir. La distancia de Levenshtein (Vladímir Levenshtein, 1965) cuenta el número mínimo de inserciones, eliminaciones y sustituciones de un solo carácter para convertir una cadena en otra. El diff basado en LCS está estrechamente relacionado, pero es ligeramente distinto: el diff clásico trata un «cambio» como un par de eliminación y luego inserción en lugar de como una sola sustitución, porque eso encaja mejor con los archivos orientados a líneas. Levenshtein responde a «¿cómo de diferentes son estas cadenas?» y te da un número; la LCS responde a «¿qué cambió exactamente?» y te da una secuencia de edición real. Los correctores ortográficos y las funciones de «¿quería decir?» quieren lo primero; las herramientas de diff quieren lo segundo. La variante Damerau-Levenshtein (1964) amplía Levenshtein con un operador de transposición para la detección de erratas.
Granularidad: línea, palabra y carácter
El diff se puede calcular con distintas granularidades, cada una con sus contrapartidas:
- A nivel de línea: cada línea es un token; dos líneas coinciden exactamente o no. Rápido, encaja limpiamente con la forma en que los programadores editan el código y produce parches concisos que
patch(1)puede aplicar. Coste: reformatear un carácter en una línea de 200 caracteres marca toda la línea como modificada. Es el predeterminado paradiff, git, SVN y esta herramienta. - A nivel de palabra: cada token delimitado por espacios en blanco es una unidad, así que una línea que cambió una palabra muestra resaltada solo esa palabra. Excelente para textos, contratos y borradores de blog. Lo usan
git diff --word-diff, el modo «Sugerencias» de Google Docs, el «Control de cambios» de Microsoft Word y el modo de comparación de palabras de Diffchecker. - A nivel de carácter: cada punto de código Unicode es una unidad. Detecta erratas de un solo carácter, ideal para el marcado de cambios jurídico donde una palabra puede invertir el significado. Lento con entradas grandes y, a veces, ilegible para ediciones largas.
Un patrón común en las interfaces de diff modernas es calcular primero el diff a nivel de línea y luego, para cualquier par de «vecinos eliminados/añadidos», ejecutar un diff secundario a nivel de palabra solo sobre esas dos líneas y resaltar los cambios dentro de la línea. Así es exactamente como funcionan tanto la vista de PR de GitHub como la biblioteca diff-match-patch.
Tres modos de visualización de diff que verás
- Diff unificado (el formato de todo archivo
.patch): fragmentos introducidos por@@ -oldStart,oldLen +newStart,newLen @@con tres líneas de contexto por encima y por debajo de forma predeterminada. Se originó con la opción-udel GNU diff de Wayne Davison alrededor de 1990. Compacto y legible por máquina mediantepatch(1), razón por la cual git, los parches por correo al estilo del kernel y SVN lo usan todos. - Lado a lado: el original a la izquierda, el modificado a la derecha, alineados línea por línea.
diff -yproduce una versión ASCII primitiva; Beyond Compare, Meld, WinMerge y la vista «Lado a lado» de arriba usan todos este formato. Lo mejor para la revisión visual y la corrección de textos. - En línea (apilado): una sola columna donde las líneas eliminadas y añadidas se intercalan. La vista de PR de GitHub usa esta de forma predeterminada. El formato que mejor aprovecha el espacio para pantallas estrechas y ediciones pequeñas.
Variantes útiles de git diff
git diff: el índice frente al árbol de trabajo.git diff --staged: HEAD frente al índice.git diff main..feature: las puntas de las ramas.main...featurecompara contra la base de fusión: lo que acabará integrando el PR.git diff --word-diffy--color-words: diff a nivel de palabra apto para marcado y con tinte de color.git diff --no-index a.txt b.txt: funciona con archivos fuera de cualquier repositorio de git. Práctico como diff independiente improvisado con los algoritmos patience o histogram.git diff -w: ignora todos los espacios en blanco (coincide con la casilla «Ignorar los espacios» de arriba).git diff --histogram: cambia el algoritmo por comando.
Cuándo recurrirías a un diff en el navegador
- Revisión de código. Pega dos versiones de un archivo, examina qué cambió y decide si el cambio tiene sentido.
- Revisión de código editado por IA. Compara tu original con la versión refactorizada de un LLM para detectar derivas o alucinaciones.
- Marcado de cambios en contratos jurídicos. Confirma que solo cambiaron las cláusulas acordadas entre la versión 3 y la versión 4.
- Control de calidad de traducciones. Compara dos traducciones al francés del mismo párrafo, o compara los archivos de localización anteriores y actualizados cuando solo deberían haber cambiado un puñado de cadenas.
- Deriva de configuración. Compara
nginx.confde producción con la de preproducción. - Comparación de esquemas SQL. Vuelca las sentencias
CREATE TABLEde dos bases de datos y compáralas para encontrar índices que faltan o derivas de tipos de columna. - Deriva de especificación. Compara dos versiones de un YAML de OpenAPI / Swagger para verificar que los cambios incompatibles estén documentados.
- Borradores de blog en Markdown. Detecta qué editó un coautor.
- Auditorías de cumplimiento. Compara una política de privacidad mes a mes para los reguladores.
- Análisis forense de archivos de bloqueo. Compara
package-lock.jsonoyarn.lockpara entender una actualización de dependencias.
Limitaciones honestas
- El diff de texto plano no tiene conciencia semántica. Renombrar
foocomobaren todo un archivo parece, en coste, idéntico a una reescritura totalmente ajena. Herramientas como difftastic analizan el AST del lenguaje y producen diffs estructurales («función añadida», «argumento reordenado»). Esta página no lo hace: es un simple diff de líneas por LCS. - Los espacios en blanco y los finales de línea provocan diffs espurios. CRLF frente a LF, espacios en blanco al final, tabulaciones frente a espacios. El conmutador «Ignorar los espacios» de arriba se corresponde con la opción
-wde git. - Los archivos binarios no encajan. El diff es un concepto de texto. Para el diff binario existen herramientas como
bsdiff,xdeltao VBinDiff. - Sensibilidad al orden. El diff de líneas asume que los documentos se editaron línea por línea. Para CSV sin ordenar o reordenaciones de claves de objetos JSON, conviene ordenar o normalizar primero.
- Detección de movimientos. El diff clásico por LCS no reconoce que una función se movió dentro de un archivo: muestra el movimiento como una eliminación más una inserción. Beyond Compare, Meld y difftastic intentan detectar movimientos; esta página no.
Más preguntas
¿Por qué esta página no muestra resaltados a nivel de carácter dentro de las líneas modificadas?
Porque la pasada a nivel de línea es suficiente para la mayoría de los casos de uso y se ejecuta mucho más rápido con entradas largas. Para el resaltado palabra por palabra dentro de la línea, el refinamiento en dos pasos es una práctica habitual, pero añade latencia. Si te importa toda la diferencia de la línea (marcado de cambios jurídico, corrección de textos), una herramienta específica a nivel de palabra (incluido git diff --word-diff en la línea de comandos) encaja mejor.
¿Cuál es la diferencia entre el diff unificado y el de lado a lado?
El diff unificado es el formato compacto y legible por máquina que usa todo archivo .patch: tres líneas de contexto, fragmentos marcados con @@. El de lado a lado muestra las dos versiones en columnas paralelas, lo que resulta más cómodo a la vista para la revisión visual, pero ocupa más espacio horizontal. El unificado es lo que enviarías por correo o confirmarías; el de lado a lado es lo que leerías en un monitor ancho.
¿Hay algoritmos mejores que Myers para el código fuente?
Para el código fuente con funciones movidas o grandes reorganizaciones, sí: el patience diff (Bram Cohen, 2002) y el histogram diff (git, alrededor de 2010) están diseñados para alinearse en líneas únicas significativas en lugar de en las comunes, lo que produce una salida más legible. Ambos están disponibles mediante git diff --patience y git diff --histogram. Las herramientas que conocen el AST, como difftastic, van más allá y analizan la estructura real del lenguaje.
¿Es seguro pegar texto confidencial aquí?
Sí: el diff se ejecuta enteramente en tu navegador mediante una implementación de LCS en JavaScript. No se sube nada, no hay analíticas sobre la entrada ni registro del lado del servidor del texto. Esta es la única categoría de herramienta de diff que es segura para acuerdos de confidencialidad, código fuente interno o cláusulas de contratos no publicadas; los servicios de diff en la nube ven todo lo que pegas.