Crear y aplicar parches (patches) en Linux

nullRecientemente he estado modificando un driver para la tarjeta GemPlus PC400 (acá GPR400) de modo que siga funcionando en Ubuntu Jaunty.

Como es de bien nacidos ser agradecidos, he querido enviar al autor de la versión original del driver los cambios necesarios para adaptarlo a la nueva versión del sistema operativo (la que tenía se quedaba en Ubuntu Hardy y han cambiado algunas cosas en el kernel que impedían que siguiese funcionando).

Para poder enviarle las modificaciones sobre el código fuente original he tenido que crear un patch y, a modo de recordatorio o chuleta, he optado por publicar el siguiente post (se que hay n-cientos artículos sobre el tema en Internet pero éste es el mio ;) )

Crear un patch en Linux

Para ello utilizaremos el comando diff del siguiente modo

diff -u viejo.txt nuevo.txt > cambios.patch

donde

  • viejo.txt y nuevo.txt son el fichero original (viejo.txt) y la versión que resulta de realizar los cambios que resulten oportunos (nuevo.txt)
  • cambios.patch gracias a la redirección (>) es el fichero donde se almacenarán los cambios que deben realizarse sobre viejo.txt para obtener nuevo.txt (si no se utiliza la redirección, los cambios aparecerán única y exclusivamente en pantalla)
  • -u permite generar “información de contexto” que facilite (a un humano) entender los cambios que se han realizado sobre viejo.txt (opcional pero muy recomendable utilizarlo)

Aplicar un “remiendo” o patch

Lo más sencillo es ejecutar un

patch < cambios.patch

¿Sobre qué fichero realizará el cambio?

Si abres con un simple editor de textos el fichero cambios.txt (si has utilizado el parámetro -u que comentamos anteriormente) descubrirás que en él se indica el fichero a utilizar
null

En concreto nos interesa la primera línea donde se indica (con los signos ---) que el fichero a modificar es viejo.txt.

¿Qué ocurre si la ubicación del fichero no coincide?

Es posible que el directorio en el que el autor tiene almacenado el fichero no coincida con el tuyo (o incluso el nombre podría ser distinto).

En dicho caso el comando preguntará la ruta del fichero a modificarnull

¿Cómo adaptar la ruta al fichero?

Si no quieres tener que escribir nada en la terminal siempre puedes editar el fichero cambios.patch para que apunte al fichero (y directorio) adecuados.

Como dicha solución resulta algo “cutre” los padres del comando patch han optado por incluir (entre otros) el parámetro -p que permite indicar el número de subdirectorios (de la ruta al fichero) que deseamos eliminar.

Así lanzando patch con -p0

patch -p0 < cambios.patch

al eliminar 0 directorios utilizará la ruta completa al fichero (es equivalente a no utilizar el -p); en el ejemplo dicha ruta sería

/tmp/blogcrearpatchsyaplicarlosenlinux/viejo.txt

Utilizando -p1

patch -p1 < cambios.patch

eliminará el primer directorio (/tmp) quedando la ruta

blogcrearpatchsyaplicarlosenlinux/viejo.txt

Utilizando -p2

patch -p2 < cambios.patch

eliminaría los dos primeros directorios (/tmp/blogcrearpatchsyaplicarlosenlinux/) quedando como ruta única y exclusivamente el nombre del fichero (porque no hay más directorios que si no seguirían apareciendo ;) )

viejo.txt

Conclusión

Una muy útil herramienta que permite generar un fichero con los cambios que se realizan sobre un archivo (sea binario o no).

Si alguien lo considera interesante que lo indique en los comentarios y publico un artículo explicando cómo interpretar el contenido del fichero cambios.patch.

Os puedo asegurar que una vez que se le coge el truco es realmente interesante el partido que se le puede llegar a sacar ;)


21 Respuestas a “Crear y aplicar parches (patches) en Linux”


  1. 1 Maanuel 24 agosto 2009 a las 8:06 pm

    Waaa genial, siempre quise aprender algo sobre este comando… lo único que hacía era aplicar lo que leía en las guías, pero ahora sé lo que hace ;)

    Bueno, sería estupendo si puedes hacer ese artículo que mencionas…. como para enterarse de que va hacer el dichoso parche antes de aplicarlo.

    Saludos!

  2. 2 shakaran 24 agosto 2009 a las 10:37 pm

    Muy buen manual/chuleta. Yo le he utilizado un par de veces para mandar parches de traducción para la página de Wine. También es muy util utilizando bajo sistemas de control de versiones como Git.

    Realmente aprendiendote 10 o 15 comandos puedes hacer muy buenas cosas con git y patch.

    Saludos

    • 3 jasvazquez 25 agosto 2009 a las 10:12 pm

      Eres una auténtica caja de sorpresas @Shak [me alegra saber que colaboras activamente con proyectos open-source aunque se trate de Wine :P ]

      Por cierto, hacia tiempo que no pasaba por tu blog y me ha sorprendido gratamente tanto la estética como el contenido (enhorabuena).

      Para que no vuelva a ocurrirme te incluyo en mi lector de RSS [ y si me envías una imagen "chula" de dimensiones similares a las de mi blogroll te meto en él ;) ]

      Un saludo compañero

  3. 5 zuargo 25 agosto 2009 a las 12:57 am

    Excelente, excelente entrada, yo suelo instalar versiones svn de los programas para tener lo último de lo último, y casi siempre aparecen parches para corregir algunos errores entes de que salga la nueva revisión del programa. Nunca supe acerca de ese comando “patch”. Siempre aplicaba los cambios (contenidos en el archivo .patch) de forma manual, es decir, copiar y pegar :P

    Una duda, si aplico un parche con el comando .patch a un archivo de una versión svn de un programa, al momento de hacer “svn up” ¿me dará algún error? lo que pasa es que cuando aplicaba los parches de forma manual siempre me decía que el fichero que había editado no era el mismo que estaba en los ¿repositorios svn? (¿se dice así o no?) y entonces me hacía unas preguntas el sistema que realmente no me di el tiempo de entender xD.

    Agradecería mucho que me pudieras responder.

    Gracias :)

    • 6 jasvazquez 25 agosto 2009 a las 10:33 pm

      Si he entendido bien andas buscando hacer un update con el repositorio SVN. ¿es así?

      En dicho caso, si has cambiado el contenido que tienes en local (aplicando un parche o editando su contenido) es normal que te indique que no coincide con la versión existente en el servidor. Está en tu mano seguir adelante (perdiendo lo que tienes en local) o sincronizar manualmente tu fichero (el local) con lo que hay en el servidor (para esto te sería muy útil entender el contenido de los ficheros patch que, como indicas, parece que controlas ;) )

  4. 7 zuargo 25 agosto 2009 a las 10:44 pm

    Gracias eso necesitaba saber :)

  5. 8 Wagner 28 agosto 2009 a las 8:58 pm

    Muy sencillo y entendible.

    Gracias por compartirlo.

  6. 9 kb 30 octubre 2009 a las 2:15 am

    Gracias por compartir!

  7. 10 Cristobal 11 abril 2010 a las 10:48 am

    Muchas gracias :-)
    ¿Sabes cómo hacer para añadir más de un fichero a la vez en el mismo parche? Se que se hace pero no lo consigo

    • 11 jasvazquez 11 abril 2010 a las 11:08 am

      Crea un fichero con las rutas a los ficheros que quieres “parchear” (imaginemos que se llama misParches.patch) y utiliza el parámetro -i del siguiente modo

      patch -p0 -i misParches.patch

      Espero te sea de utilidad, un saludo @Cristobal

  8. 12 Cristobal 11 abril 2010 a las 11:23 am

    Gracias por tan pronta respuesta, pero me refería a cómo usar diff para crear un .patch con más de un fichero parcheado a la vez
    Gracias

  9. 14 Cristobal 11 abril 2010 a las 1:21 pm

    Hola de nuevo, pues nada que no hay forma, he mirado ya muchos enlaces, la ayuda de diff pero no me sale. Es lo único que me queda por saber para aplicar parches cuando creo paquetes deb y rpm.
    Lo único que he conseguido es unir dos ficheros .patch en un uno con el comando merge pero me los une por columnas y no me sirve :-(

    Muchas gracias :-)

    • 15 jasvazquez 1 mayo 2010 a las 11:21 am

      ¿has probado a utilizar la misma técnica que se indica en el artículo (diff -u) pero indicando dos directorios en lugar de los ficheros a comparar?

      Ten en cuenta que en linux TODO son archivos (incluido los dispositivos como teclados, tarjetas de sonido, …) ;)

      Mantenme informado, últimamente no ando con demasiado tiempo y, aunque me interesa, el tema no he podido hacerte la prueba personalmente :(

      Perdona y un saludo

  10. 18 Cristobal 9 mayo 2010 a las 7:31 pm

    Hola, al fin un pajarito me dijo cómo hacerlo. Se hace con cat
    Ejemplo

    cat parche1.patch parche2.patch > parcheunion.patch

    Así de sencillo es ;-)


  1. 1 Bitacoras.com Trackback en 24 agosto 2009 a las 6:23 pm
  2. 2 Crear-y-aplicar-parches-patches-en-Linux : Sysmaya Trackback en 2 septiembre 2009 a las 1:52 am
  3. 3 Parchando paquetes con debdiff | Soy porque nosotros somos Trackback en 20 junio 2010 a las 11:19 pm

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s




Patrocinadores

blog de coches y motor blog de coches y motor Tu portal sobre tendencias web Cupones Descuento Genere ingresos con los infoproductos

¿Hablamos?

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevos mensajes por correo.

Únete a otros 1.171 seguidores

Participa

Histórico


Twitter


Seguir

Get every new post delivered to your Inbox.

Únete a otros 1.171 seguidores