Los parches que circulan en revisiones de código, informes de incidencias o por correo suelen estar en formato diff unificado. git diff, diff -u y el «raw diff» de GitHub usan este formato. Al principio parece lleno de símbolos, pero las reglas son sencillas.
Aspecto general
@@ -1,5 +1,6 @@ def greet(name):- print("Hello " + name)+ message = f"Hello, {name}!"+ print(message) def main(): greet("world")
De arriba abajo aparecen la cabecera extendida de git, la cabecera de archivo (---, +++) y los hunks (bloques que empiezan por @@). Un archivo puede tener varios hunks, y un parche puede incluir varios archivos.
Cabecera de archivo: --- y +++
--- a/greet.pyes el archivo antes del cambio y+++ b/greet.py, el archivo después.- git antepone
a/yb/a las rutas. Por eso, al aplicarlo con el comandopatch, se usa-p1para quitar el primer componente de la ruta. - Un archivo nuevo se indica con
--- /dev/nully uno eliminado, con+++ /dev/null. - GNU diff a veces añade la fecha de modificación tras el nombre del archivo.
Cabecera de hunk @@ -a,b +c,d @@
@@ -1,5 +1,6 @@ significa que se muestran «5 líneas del archivo anterior a partir de la línea 1 y 6 líneas del archivo nuevo a partir de la línea 1».
- El primer número es el número de línea inicial; el que va tras la coma es el número de líneas que ocupa el hunk (incluidas las de contexto).
- Si el número de líneas es 1, se omite junto con la coma.
@@ -7 +7 @@es un hunk de una sola línea, la 7. - Si el número de líneas es 0, significa que en ese lado no hay líneas.
@@ -3,0 +4,2 @@quiere decir que se insertaron dos líneas nuevas tras la línea 3 del original. Al comparar con un archivo vacío aparece-0,0. - Tras el segundo
@@a veces aparece texto como el nombre de una función (@@ -40,7 +40,8 @@ def main():). Es información orientativa sobre en qué función está el hunk y se ignora al aplicarlo.
Si lo contamos, en el ejemplo anterior hay 4 líneas de contexto (las que empiezan por un espacio): def greet(name):, una línea en blanco, def main(): y greet("world"). Antes del cambio hay 4 de contexto más 1 línea -, es decir 5; después, 4 de contexto más 2 líneas +, es decir 6. Por eso la cabecera es -1,5 +1,6.
Los tres tipos de línea del cuerpo
| Primer carácter | Significado |
|---|---|
| Espacio | Línea de contexto, idéntica en ambos lados |
- | Línea que solo está antes del cambio (eliminada) |
+ | Línea que solo está después del cambio (añadida) |
Por defecto se muestran 3 líneas de contexto antes y después de cada cambio (se puede cambiar, por ejemplo con git diff -U5). Las líneas de contexto sirven para encontrar la posición correcta al aplicar el parche. Aunque los números de línea no coincidan del todo, si el contexto encaja patch desplaza la posición (offset) y lo aplica.
Una línea corregida aparece como una pareja: una línea - seguida de una línea +. El formato unificado no tiene un símbolo propio para «modificado», así que el truco es leer emparejando de arriba abajo el grupo de líneas - con el grupo de líneas +.
\ No newline at end of file
@@ -1,2 +1,2 @@ host=example.com-port=8080\ No newline at end of file+port=8080
Indica que la línea inmediatamente anterior es la última del archivo y no termina en un carácter de salto de línea. En el ejemplo, el contenido es el mismo y solo el archivo nuevo tiene el salto de línea final. Encontrarás más detalles en Caracteres de fin de línea y diferencias invisibles.
Cabeceras extendidas de git
Las líneas que siguen a diff --git a/ruta b/ruta son información adicional propia de git.
index 3b18e51..a6f4c2d 100644— el inicio de los hashes del contenido antes y después, y el modo del archivo (100644 es un archivo normal; 100755, un ejecutable)new file mode 100644/deleted file mode 100644— archivo creado o eliminadoold mode 100644/new mode 100755— solo cambian los permisos de ejecución (puede aparecer sin hunks de contenido)similarity index 90%,rename from ruta-antigua,rename to ruta-nueva— cambio de nombre (el contenido coincide en un 90 %)Binary files a/logo.png and b/logo.png differ— en los archivos binarios solo aparece esta línea en lugar del contenido
Trucos útiles para revisar
- Mirar primero la diferencia de líneas en la cabecera del hunk da una idea del tamaño del cambio.
-10,7 +10,30significa que se añadieron 23 líneas. - Para filtrar los hunks en los que solo cambian espacios, usa
git diff -w. Es especialmente útil en commits que mezclan cambios reales con arreglos de sangría (Opciones para ignorar espacios). - Para ver qué cambió dentro de una línea, usa
git diff --word-diffo pega el texto en una herramienta que resalte dentro de la línea, como este sitio. - Antes de aplicar un parche, comprueba con
git apply --check archivo.patchque se aplica limpiamente. Fuera de un repositorio git, usapatch -p1 --dry-run < archivo.patch.
Pruébalo en esta herramienta
La vista unificada del comparador de textos muestra, en el mismo orden que este formato, el grupo - seguido del grupo +, y resalta además las palabras cambiadas dentro de la línea. El botón patch de la barra de resultados copia el texto diff unificado estándar, y el botón de guardar que tiene al lado lo descarga como archivo diff.patch. Un patch generado con todas las opciones de ignorar desactivadas se puede aplicar al original con patch -p1 o git apply.