27 de Noviembre, 2004

Las diferencias cuentan

El amigo r0sk hablaba ayer de cómo usar patch. Le lanzé el guante de explicar cómo va diff, la herramienta 'pareja' de patch, pero me lo ha devuelto. No iba a explicar nada aquí porque no le puedo hacer un trackback, pero he cambiado de idea. Lo voy a explicar por encima pero a cambio de un shame on r0sk!: a ver cuando implementas los trackbacks :D.

Una vez motivado al personal, vamos a ver que hace esto de diff. En realidad es muy simple: muestra las diferencias entre dos archivos.

Esto en sí mismo puede ser útil, pero en realidad su principal utilidad es gracias a patch, que sabiendo las diferencias entre A y B permite conseguir B a partir de A (sin tener B completo, claro). Bueno, para la aplicación del parche ya tenemos el artículo de r0sk, que está muy bien.

La creación de un parche es sencilla:

$ diff -u fichero.original fichero.modificado

Vamos a partir de un fichero con este contenido:

Este es el fichero original
que vamos a modificar un poco
para ver como va la histoira
esta de diff...

En el fichero modificado nos vamos a limitar a corregir la palabra mal escrita (en rojo). Copiamos fichero.org a fichero.mod y rectificamos el error.

Ejecutamos diff sobre los ficheros:

$ diff -u fichero.org fichero.mod
--- fichero.org Sat Nov 27 11:58:17 2004
+++ fichero.mod Sat Nov 27 11:59:21 2004
@@ -1,5 +1,5 @@
 Este es el fichero original
 que vamos a modificar un poco
-para ver como va la histoira
+para ver como va la historia
 esta de diff...

Por defecto el resultado va a la salida estándar (pantalla). Solo tenemos que redirigir a un fichero y tendremos nuestro parche (diff -u fichero.org fichero.mod > fichero.patch, aunque la extensión .diff también se usa).

La opción -u es para que la salida sea en formato unificado. Esto es porque patch necesita, al menos, dos lineas de contexto, y el formato unificado las proporciona. Además es bueno ese contexto para que entendamos un poco qué hace el parche.

Como vemos la salida, y simplificando un poco, nos indica el fichero original (---) y el modificado (+++), precedida con un - la linea original y con un + la modificación, y además vemos la modificación en un contexto.

Este ejemplo es un poco sencillo de más. Vamos a echarle un ojo a un parche real:

Parche para que la wlan prism2 pci
sea reseteada por soft cuando se vaya de paseo.
Envió el tip Todd C. Miller a misc@ y a mi me funciona.

=========================================================
--- sys/dev/ic/if_wi.c.orig     Tue Oct 28 12:21:29 2003
+++ sys/dev/ic/if_wi.c  Tue Oct 28 12:25:29 2003
@@ -951,9 +951,9 @@
         * Do a soft reset of the card; this is required for Symbol cards.
         * This shouldn't hurt other cards but there have been reports
         * of the COR reset messing up old Lucent firmware revisions so
-        * we only soft reset Symbol cards for now.
+        * we avoid reset Lucent cards for now.
         */
-       if (sc->sc_firmware_type == WI_SYMBOL) {
+       if (sc->sc_firmware_type != WI_LUCENT) {
                cor_value = bus_space_read_1(sc->wi_ltag, 
                    sc->wi_lhandle, sc->wi_cor_offset);
                bus_space_write_1(sc->wi_ltag, sc->wi_lhandle,

En azul he marcado el comentario. Los comentarios se pueden poner al principio del parche seguido por una linea de = que actua de delimitador. Es buena idea emplear comentarios. Debería poner qué hace el parche y cómo se aplica.

Luego sigue la información de diff que ya hemos visto. Puede que haya algo de información más si el parche se ha generado desde CVS, pero eso por ahora no nos importa demasiado.

Vemos que las diferencias comienzan en la linea 951 y que vamos a disponer de 9 líneas, y aquí sí queda claro que el diff unificado muestra un contexto para los cambios.

Es muy interesante entender qué hace un parche, porque así podemos aplicar los cambios a mano. Esto puede pasar cuando trabajamos con una versión de un software que ya no tiene soporte oficial. El parche para la versión N+1 puede que vaya en la versión N (me remito nuevamente al artículo de r0sk sobre como probar el parche sin aplicarlo), pero si no es así puede que aun podamos hacer un apaño a mano. Todo es cuestión de práctica.

Y creo que con estó ya tenemos una visión suficiente de cómo se haría un parche. No hay mucho más, aunque cuando se trabaja con CVS sí hay algunas cosas interesantes, pero eso ya es otro tema distinto.

Ahora haría un trackback a r0sk... :D.

Anotación por Juan J. Martínez.

Hay 1 comentario

Gravatar

...diff -bBurN por razones que sé que mirarás en el man! :P

por coder, en 2004-11-28 04:07:23

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.