Comparador de texto (Diff)

Compara dos textos y encuentra las diferencias al instante.

Tus datos no salen de tu dispositivo

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

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:

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

Variantes útiles de git diff

Cuándo recurrirías a un diff en el navegador

Limitaciones honestas

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.

Herramientas relacionadas