Si trabajas con GNU/Linux y desarrollas o mantienes software, tarde o temprano vas a toparte con los parches de código. Puede que quieras enviar una corrección al autor de un proyecto, compartir cambios con un compañero sin usar un repositorio remoto o adaptar un driver antiguo a un kernel moderno. En todos esos casos, crear y aplicar parches con las utilidades diff y patch es una solución sencilla, potente y muy usada en el mundo Unix.
En este artículo vamos a ver, con calma y mucho detalle, cómo generar parches y cómo aplicarlos usando tanto las herramientas clásicas de GNU/Linux (diff y patch) como su integración en flujos de trabajo con Git. Además, comentaremos otros escenarios donde se hablan de “parches” (como sistemas empresariales tipo Sage X3 o actualizaciones de software) para que tengas una visión completa de qué es un parche informático y cómo funciona en distintos contextos.
¿Qué es un parche de código en informática?
En un contexto de desarrollo de software, cuando hablamos de un parche informático nos referimos a un conjunto de cambios que se aplican sobre uno o varios archivos ya existentes. Esos cambios pueden estar orientados a corregir errores, añadir nuevas funcionalidades, actualizar el comportamiento de un programa o incluso eliminar partes antiguas del código que ya no tienen sentido.
Un parche no es más que un fichero de texto plano que describe con precisión qué líneas hay que añadir, eliminar o modificar en determinados archivos. A partir de un archivo original y ese fichero de parche, la herramienta adecuada (como patch o los comandos de Git) es capaz de reconstruir la versión modificada sin necesidad de enviar todo el archivo nuevo completo.
Este mecanismo es especialmente útil en proyectos de software libre, en los que colaboradores externos pueden enviar correcciones o mejoras sin acceso directo al repositorio. Simplemente crean un parche con sus cambios y se lo mandan al mantenedor para que lo revise y lo aplique si lo considera oportuno.
Ejemplo práctico: modificar un script en GNU/Linux
Imagina que tienes un pequeño script Bash llamado actualizar.sh que usas para automatizar una tarea. Te das cuenta de que podrías mejorarlo o que contiene errores tipográficos en los mensajes que muestra por pantalla. No quieres machacar el original sin más, así que sigues un enfoque ordenado:
- Haces una copia del archivo original, por ejemplo, actualizar.sh.nuevo.
- Editas esa copia y aplicas las modificaciones que creas oportunas: añadir funciones, corregir textos, eliminar partes redundantes…
- Una vez estás satisfecho con el resultado, generas un parche que recoja exactamente las diferencias entre el archivo original y el modificado.
El resultado será un fichero con extensión .patch que podrás enviar a otra persona (por correo, mensajería, adjunto en un issue, etc.) para que integre esos cambios en su propio código original de forma automática.
Creación de un parche con el comando diff
La utilidad diff compara dos archivos o directorios y muestra las diferencias entre ellos. Es la base para generar parches en GNU/Linux. En el caso más sencillo, puedes crear un parche con un comando de este estilo:
diff -u viejo.txt nuevo.txt > cambios.patch
En este ejemplo, viejo.txt es el archivo original y nuevo.txt es la versión modificada que contiene los cambios que quieres compartir. Mediante la redirección con >, todo el resultado de diff se guarda en cambios.patch, que es el fichero de parche que luego aplicarás sobre la versión original.
La opción -u genera un parche unificado con contexto: incluye varias líneas antes y después de cada cambio. Esto facilita tanto la lectura humana como el trabajo de la herramienta patch, que puede localizar mejor dónde aplicar las modificaciones incluso si el archivo no coincide al 100 % con el original.
En muchos entornos se recomienda usar un conjunto más amplio de opciones, como -Naur:
- -N: trata los archivos que faltan como vacíos (útil cuando se crean o eliminan archivos).
- -a: fuerza el tratamiento como texto incluso si diff sospecha que pueda ser binario.
- -u: genera el diff en formato unificado, que es el estándar de facto para parches.
- -r: recorre directorios de forma recursiva, comparando subcarpetas.
Un ejemplo típico para generar un parche de todo un proyecto podría ser:
diff -Naur proyecto_original/ proyecto_modificado/ > proyecto.patch
Con este comando obtienes un único fichero de parche que describe todas las diferencias entre ambas copias del proyecto, incluyendo archivos nuevos, archivos borrados y cambios en el contenido.
Cómo interpretar el contenido de un archivo .patch

Si abres un fichero de parche con tu editor de texto favorito, verás que sigue una estructura bastante clara. Por ejemplo, algo similar a esto:
$ diff -Naur cello.c.orig cello.c
--- cello.c.orig 2016-05-26 17:21:30.478523360 -0500
+++ cello.c 2016-05-27 14:53:20.668588245 -0500
@@ -1,6 +1,6 @@
#include<stdio.h>
int main(void){
- printf("Hello World!\n");
+ printf("Hello World from my very first patch!\n");
return 0;
}
\ No newline at end of file
En este fragmento puedes observar varios elementos clave en el formato unificado:
- Las líneas que empiezan por — y +++ indican, respectivamente, el archivo original y el archivo modificado.
- Los bloques que comienzan con @@ señalan el rango de líneas afectado en el archivo original y en el nuevo.
- Las líneas con – al inicio son líneas que se eliminan del archivo original.
- Las líneas con + al inicio representan las líneas que se añaden en el archivo resultante.
- Las líneas sin signo inicial (o con espacio) son contexto: por ellas, la herramienta entiende dónde encajan los cambios.
Aunque pueda parecer un formato algo crudo, una vez te acostumbras resulta muy intuitivo y te permite revisar de un vistazo qué se ha cambiado y dónde y, si hace falta, probar cambios en un entorno aislado sin tener que abrir los archivos originales y los modificados por separado.
Aplicar un parche con el comando patch
La herramienta complementaria a diff es patch, que se encarga de leer un archivo .patch y realizar las modificaciones necesarias sobre uno o varios ficheros existentes. El uso básico es muy directo:
patch < cambios.patch
En este caso, patch lee el contenido desde la entrada estándar y, gracias a la información incluida en el parche (las líneas — y +++ con los nombres de archivo), sabe exactamente sobre qué fichero debe aplicar los cambios. Si el archivo no está donde se espera, patch puede preguntarte por la ruta correcta o fallar con un mensaje de error; es buena práctica en estrategias de actualización preparar el entorno antes de aplicar parches.
También puedes especificar los archivos de forma explícita, por ejemplo para un caso muy sencillo de un solo fichero:
patch viejo.txt < cambios.patch
En este modo, le indicas a patch cuál es el archivo base y el parche se aplica sobre él. Si todo va bien, al final tendrás un viejo.txt modificado que coincide con la versión nuevo.txt con la que creaste el parche.
Gestionar rutas con la opción -p de patch
Cuando los parches se generan entre directorios completos, el nombre del archivo dentro del .patch suele incluir la ruta relativa al fichero, algo como:
--- /tmp/blogcrearpatchsyaplicarlosenlinux/viejo.txt
+++ /tmp/blogcrearpatchsyaplicarlosenlinux/viejo.txt
Si en tu máquina los archivos no están en esa ruta exacta, no es práctico ir editando el parche a mano para ajustar las rutas. Para eso existe el parámetro -p de patch, que permite “recortar” directorios del principio de la ruta hasta que encaje con tu estructura de carpetas.
Por ejemplo:
- patch -p0 < cambios.patch mantiene la ruta completa /tmp/blogcrearpatchsyaplicarlosenlinux/viejo.txt.
- patch -p1 < cambios.patch elimina el primer componente (/tmp) y se queda con blogcrearpatchsyaplicarlosenlinux/viejo.txt.
- patch -p2 < cambios.patch elimina los dos primeros directorios (/tmp y blogcrearpatchsyaplicarlosenlinux/), quedando solo viejo.txt como ruta.
Gracias a esta opción, puedes aplicar parches generados en otros entornos o con diferentes jerarquías de directorios sin tocar el contenido del fichero .patch. Es una solución mucho más limpia que editar las rutas a mano y evita errores tontos.
Uso de parches con Git: git diff, git apply y git format-patch
Aunque diff y patch son la base histórica, en el día a día muchos desarrolladores trabajan con Git, que incorpora sus propios comandos para crear y aplicar parches de forma integrada con el repositorio.
Dentro de un repositorio Git, un parche sigue siendo un fichero de texto plano con diferencias en formato unificado. La ventaja es que Git sabe en todo momento qué ha cambiado, quién lo ha modificado y en qué commits, así que puede generar parches de distintas formas según lo que necesites compartir.
Crear un parche con cambios sin commitear
Si has tocado varios archivos en tu copia local, pero aún no has hecho commit, puedes guardar esos cambios en un archivo de parche para compartirlos con alguien o conservarlos sin necesidad de subirlos a un remoto:
git diff > cambios.patch
Este comando captura todas las diferencias entre tu working directory y el último commit, y las vuelca a un fichero .patch que luego otra persona podrá aplicar sobre la misma versión del repositorio.
Crear un parche a partir de un commit existente
Cuando ya has realizado un commit y quieres compartir únicamente ese conjunto de cambios, es más cómodo recurrir a git format-patch:
git format-patch -1 HEAD
Con esta orden se genera un archivo .patch (o .patch/.mbox) que contiene toda la información del último commit: diffs, metadatos, autor, mensaje de commit, etc. Es el formato clásico que se usa para enviar parches por correo en muchos proyectos de código abierto.
También puedes indicar un rango de commits para generar una serie de parches, uno por commit, si necesitas que el receptor los aplique de forma secuencial respetando la historia de cambios.
Aplicar un parche en Git
Si lo que recibes es un simple archivo de diff (creado con git diff o diff clásico), en un repositorio Git normalmente usarás:
git apply cambios.patch
Este comando intentará aplicar los cambios sobre tu árbol de trabajo actual, sin crear ningún commit automáticamente. Para mantener un sistema estable, después podrás revisar y hacer commit de las modificaciones como prefieras.
Antes de lanzarte, es muy recomendable verificar si el parche encaja bien en tu árbol actual usando la opción –check:
git apply --check cambios.patch
Si no aparecen errores, significa que el parche se puede aplicar sin conflictos. Si hay problemas de compatibilidad (archivos que han cambiado demasiado, contexto que no coincide, etc.), Git te lo indicará y podrás decidir si actualizas tu rama, pides al autor que rehaga el parche sobre tu versión o resuelves conflictos manualmente.
Aplicar parches tipo “serie de commits” con git am
Cuando el parche procede de git format-patch o de algunos sistemas como GitHub (por ejemplo, parches descargados de una pull request), lo habitual es usar git am, que aplica el parche y genera directamente los commits correspondientes:
git am --signoff < patchName.patch
El parámetro –signoff añade una línea “Signed-off-by” en el mensaje de commit, algo que ciertas comunidades exigen por motivos de trazabilidad legal o de autoría. Durante este proceso pueden aparecer advertencias, pero mientras no haya errores bloqueantes, el parche se incorporará a la rama actual como uno o varios commits nuevos.
Si en algún momento tienes que revertir un parche aplicado con git apply, puedes usar la opción -R para intentar deshacerlo:
git apply -R patchName.patch
Este comando intenta aplicar el parche en sentido inverso, eliminando las líneas añadidas y restaurando las que fueron borradas, siempre que el contexto no haya cambiado en exceso.
Verificar compatibilidad y conflictos de parches
Uno de los riesgos al trabajar con parches es que no encajen bien con el estado actual del código: quizá el archivo ha cambiado mucho desde que se generó el parche, o estás intentando combinar varios parches que tocan las mismas zonas del código de forma incompatible.
En flujos de trabajo con Git, ya hemos visto que puedes ejecutar git apply –check para comprobar si un parche se podría aplicar sin errores antes de modificar nada. En otros entornos, como proyectos específicos (por ejemplo, motores de juego como Intersect o plataformas empresariales), suele haber una función de “probar parches” que analiza su impacto y genera un informe de compatibilidad; además, es habitual crear snapshots siguiendo buenas prácticas de snapshots antes de integrarlos de manera definitiva.
Conviene que solo instales parches procedentes de fuentes de confianza, ya que cualquier modificación del código fuente puede introducir bugs, problemas de rendimiento o incluso vulnerabilidades de seguridad si el parche no está bien escrito.
Parches en sistemas empresariales: ejemplo de Sage X3
Más allá del mundo del desarrollo puro, muchas aplicaciones empresariales complejas, como las que usan la tecnología SAFE X3 (por ejemplo, Sage X3), incorporan mecanismos propios para distribuir correcciones y evoluciones funcionales en forma de ficheros de parche.
En este tipo de sistemas, un parche puede incluir objetos muy variados: pantallas, definiciones de tablas, códigos de actividades, tipos de datos, menús, capítulos de mensajes, procesos automatizados, peticiones de ejecución, datos adicionales, etc. La lógica es parecida a la de los parches de código, pero aplicada a elementos de configuración y estructura interna del ERP.
Los archivos de parche suelen seguir convenciones de nombre estrictas, como por ejemplo:
- Correcciones estándar con nombres del tipo P_nnnn_vvv.dat, donde nnnn es un número secuencial y vvv indica la versión mínima del producto sobre la que se puede aplicar.
- Parches de documentación con nombres tipo Dy_nnnnn_vvv_ppp.dat, donde y abrevia el producto, nnnnn es un número cronológico, vvv es la versión y ppp el código de legislación.
La propia aplicación se encarga de verificar la secuencialidad, la versión mínima requerida, la integridad del fichero y si el módulo funcional afectado está implantado en el “dossier” (entorno) donde quieres integrarlo. Si faltan parches intermedios, si el archivo está corrupto o si la versión del producto es demasiado antigua, se registran errores en un fichero de traza.
En muchos casos, la integración de un parche no solo toca el código, sino también el diccionario de datos y la base de datos. Por ejemplo, si el parche incluye una tabla nueva o modifica una existente, el sistema puede necesitar validar la tabla, recrearla, actualizar índices y estadísticas, etc. Dependiendo del tipo de cambio (añadir campos al final o entre campos ya existentes), las estadísticas de la base se mantienen o se pierden y se reconstruyen.
La gestión de estos parches suele realizarse desde una función específica dentro del ERP (como PATCHT en Sage X3), que permite lanzar la integración en modo interactivo o en modo batch para varios dossieres a la vez (normalmente hasta un máximo configurado). Al finalizar, se genera un fichero de traza que conviene revisar para identificar cualquier incidencia.
En el caso de los parches de documentación, su integración actualiza el diccionario de documentación, pero no los documentos finales publicados. Para que estos se reflejen en el servidor de documentación, hay que lanzar procesos de generación de documentación, a menudo diferenciando tipos de datos (APM, AML, ATB, ATY) y respetando un orden concreto.
Cómo se relacionan los parches con las actualizaciones de software
Cuando en el día a día actualizas un programa en tu sistema operativo, es normal preguntarse si lo que hace el gestor de paquetes es desinstalar todo y reinstalar, o si en realidad está aplicando algo parecido a un parche. La respuesta depende mucho de la tecnología de distribución que se utilice.
En los sistemas de paquetes tradicionales (como deb en Debian/Ubuntu o rpm en Red Hat/Fedora), muchas actualizaciones consisten en instalar un paquete completo nuevo que contiene todos los archivos de la versión actualizada. Técnicamente no es un parche al estilo de diff/patch, sino un reemplazo de archivos. El gestor se encarga de quitar los archivos antiguos (o marcarlos como obsoletos) y colocar los nuevos, respetando en lo posible las configuraciones del usuario.
Sin embargo, en otros contextos —sobre todo en entornos empresariales, juegos, sistemas embebidos o algunas plataformas móviles— se usan mecanismos de actualizaciones incrementales, donde se distribuyen solo los cambios respecto a la versión instalada. Esto se parece mucho más al concepto de parche: se entrega un archivo que contiene deltas (diferencias) y un programa actualizador que se ocupa de aplicarlos al binario o a los datos existentes para producir la nueva versión.
En sistemas operativos modernos también existen métodos sofisticados como instantáneas (snapshots), capas de solo lectura y deltas binarios, que permiten reducir el tamaño de las descargas y aumentar la fiabilidad de las actualizaciones. Aunque por debajo se use un formato distinto, la idea conceptual es muy similar a la de los parches que ves con diff y patch: partir de un estado A, aplicar un conjunto de transformaciones bien definidas y obtener un estado B sin tener que reconstruirlo todo desde cero.
En definitiva, entender cómo funcionan los parches de código con herramientas como diff, patch y los comandos de Git te da un control enorme sobre cómo compartes y aplicas cambios, desde el pequeño script que ajustes en tu máquina hasta entornos empresariales donde se distribuyen evoluciones completas en forma de ficheros de parche; dominar estas técnicas te permite colaborar de manera más eficiente, diagnosticar mejor los problemas de compatibilidad y moverte con soltura por cualquier escenario donde haya que transformar un código o sistema ya existente sin reinstalarlo por completo.
