Aunque compares los mismos dos archivos, el resultado puede variar según el algoritmo diff. Todos son diffs «correctos», pero cambian las líneas que emparejan como iguales, y con ello lo fácil que resulta leerlos. git ofrece cuatro mediante la opción --diff-algorithm.
| Valor | Descripción en la documentación de git | Características |
|---|---|---|
myers (default) | El algoritmo voraz (greedy) básico; el valor por defecto actual | Rápido y, en general, cercano al mínimo |
minimal | Dedica más tiempo para producir el diff más pequeño posible | Siempre mínimo; puede ser lento con entradas grandes |
patience | El algoritmo patience diff | Usa las líneas únicas como puntos de anclaje |
histogram | Extiende patience para admitir elementos comunes poco frecuentes | Usa las líneas poco frecuentes como anclaje |
También existen formas cortas como git diff --patience y git diff --histogram, y puedes cambiar el valor por defecto con git config diff.algorithm histogram.
Myers: el valor por defecto que busca la edición mínima
El algoritmo de Myers busca el camino que minimiza el número de eliminaciones y adiciones (el principio se explica en Cómo funciona diff). El problema aparece cuando hay varias formas posibles de decidir qué líneas son iguales. El código está lleno de líneas muy comunes como }, {, líneas en blanco o return, así que el algoritmo puede emparejar líneas sin relación de significado y el número de ediciones seguir siendo igualmente mínimo.
El mismo cambio, dos resultados
Supongamos que añadimos una función h entre las funciones f y g, como se ve abajo. Los dos diffs siguientes tienen el mismo número de ediciones: 4 líneas añadidas.
@@ -1,6 +1,10 @@ int f() { return 1; }++int h() {+ return 3;+} int g() { return 2;
@@ -1,5 +1,9 @@ int f() { return 1;+}++int h() {+ return 3; } int g() {
En el primero la función nueva se ve entera; en el segundo, la llave de cierre de la función existente f se trata como la llave de la función nueva y la parte añadida queda cortada de forma extraña. Estas formas dependen del orden de exploración, y las versiones recientes de git corrigen buena parte de ellas con una heurística que mira la sangría para mover los límites del tramo cambiado a un sitio más legible (--indent-heuristic, activada por defecto).
Patience: primero alinea las líneas únicas
El patience diff, propuesto por Bram Cohen, empieza buscando las líneas que aparecen exactamente una vez en cada archivo. Una línea única, como la declaración int h() {, tiene una pareja inequívoca. Entre esas líneas únicas elige la lista más larga que respeta el orden (la subsecuencia creciente más larga), la usa como puntos de anclaje y solo vuelve a comparar los tramos pequeños que quedan entre ellos.
- Ventaja: no se deja arrastrar por líneas comunes como
}o las líneas en blanco, así que los cambios se ven como bloques de función o de párrafo. - Inconveniente: en entradas casi sin líneas únicas (datos con líneas repetidas, logs) no encuentra anclajes y no mejora al diff normal, o incluso agrupa el resultado en bloques demasiado grandes.
Histogram: da prioridad a las líneas poco frecuentes
El algoritmo histogram se desarrolló en JGit (una implementación de git en Java) y después se incorporó a git. Mientras patience solo considera «las líneas que aparecen exactamente una vez», histogram cuenta cuántas veces aparece cada línea y elige como anclaje la que menos aparece. Así puede usar como referencia líneas relativamente raras aunque no haya ninguna única. La documentación de git lo describe como una extensión del algoritmo patience «para admitir elementos comunes poco frecuentes». En la práctica suele dar, como patience, resultados que respetan bien la estructura del código.
¿Cuál usar?
- Revisión de código habitual: basta con el valor por defecto. Si el resultado aparece cortado de forma rara, vuelve a mirarlo con
--histogram. - Refactorizaciones grandes en las que se mueven o añaden varias funciones:
--histogramo--patiencemantienen mejor los bloques. - Cuando necesitas contar exactamente el mínimo de líneas cambiadas:
--minimal. - Archivos de datos con muchas repeticiones: ordenar y normalizar puede importar más que el algoritmo. Si es JSON, consulta Cómo comparar JSON.
Sea cual sea el algoritmo, el archivo resultante se reconstruye igual. Lo único que cambia es la forma en que lo lee una persona.
En esta herramienta
Este sitio compara las líneas con un algoritmo de la familia Myers; después evalúa la similitud de contenido entre las líneas cambiadas para emparejarlas como «modificadas» y vuelve a comparar su interior. Así, aunque el resultado por líneas quede algo mal cortado, se ve enseguida qué palabra cambió. Introduce el ejemplo anterior en el comparador de textos y compara cómo se ve en la vista unificada y en la dividida. Cómo leer el resultado se explica en Cómo leer un diff unificado.