patch: aplicar un archivo diff a un original
SINOPSIS
patch [opciones] [archivo_original [archivo_patch]]
pero normalmente simplemente
patch -pnum <archivo_patch
DESCRIPCIÓN
patch toma un archivo de parche `archivo_patch` que contiene una lista de diferencias generada por el programa `diff` y aplica esas diferencias a uno o más archivos originales, produciendo versiones parcheadas. Normalmente, las versiones parcheadas se colocan en lugar de los archivos originales. Se pueden crear copias de seguridad; consulte la opción `-b` o `--backup`. Los nombres de los archivos que se van a parchear se suelen obtener del archivo de parche, pero si solo hay un archivo que parchear, se puede especificar en la línea de comandos como `archivo_original`.
Al inicio, patch intenta determinar el tipo de lista de diferencias, a menos que se anule con las opciones -c (--context), -e (--ed), -n (--normal) o -u (--unified). Los parches de contexto (estilo antiguo, nuevo y unificado) y los parches normales se aplican mediante el propio programa patch, mientras que los parches ed se envían simplemente al editor ed(1) a través de una tubería.
patch intenta omitir cualquier basura inicial, aplicar la diferencia y, luego, omitir cualquier basura final. Por lo tanto, podría alimentar un mensaje de correo electrónico que contenga una lista de diferencias a patch, y debería funcionar. Si toda la diferencia está sangrada por una cantidad constante, si las líneas terminan en CRLF, o si una diferencia está encapsulada una o más veces prefijando "- " a las líneas que comienzan con "-", como se especifica en Internet RFC 934, esto se tiene en cuenta. Después de eliminar la sangría o la encapsulación, se ignoran las líneas que comienzan con #, ya que se consideran comentarios.
Con los parches de contexto, y en menor medida con los parches normales, patch puede detectar cuándo los números de línea mencionados en el parche son incorrectos e intenta encontrar el lugar correcto para aplicar cada fragmento del parche. Como primera aproximación, toma el número de línea mencionado para el fragmento, más o menos cualquier desplazamiento utilizado en la aplicación del fragmento anterior. Si ese no es el lugar correcto, patch escanea tanto hacia adelante como hacia atrás para encontrar un conjunto de líneas que coincidan con el contexto dado en el fragmento. Primero, patch busca un lugar donde todas las líneas del contexto coincidan. Si no se encuentra ningún lugar así, y es un parche de contexto, y el factor de tolerancia máximo está establecido en 1 o más, entonces se realiza otro escaneo ignorando la primera y la última línea del contexto. Si eso falla, y el factor de tolerancia máximo está establecido en 2 o más, se ignoran las dos primeras y las dos últimas líneas del contexto, y se realiza otro escaneo. (El factor de tolerancia máximo predeterminado es 2).
Los fragmentos con menos contexto de prefijo que contexto de sufijo (después de aplicar la tolerancia) deben aplicarse al principio del archivo si su primera línea es 1. Los fragmentos con más contexto de prefijo que contexto de sufijo (después de aplicar la tolerancia) deben aplicarse al final del archivo.
Si un parche no puede encontrar un lugar para instalar un fragmento del parche, coloca ese fragmento en un archivo de rechazo, que normalmente tiene el nombre del archivo de salida más un sufijo .rej, o # si .rej generara un nombre de archivo demasiado largo (si incluso agregar el carácter # hace que el nombre del archivo sea demasiado largo, entonces # reemplaza el último carácter del nombre del archivo).
El fragmento rechazado se muestra en formato de diff unificado o de contexto. Si la entrada fue un diff normal, muchos de los contextos son simplemente nulos. Los números de línea de los fragmentos en el archivo de rechazo pueden ser diferentes de los del archivo de parche: reflejan la ubicación aproximada en el archivo nuevo donde el parche cree que deben colocarse los fragmentos fallidos, en lugar del archivo antiguo.
A medida que se completa cada fragmento, se le informa si el fragmento falló y, de ser así, qué línea (en el archivo nuevo) el parche pensó que debía contener el fragmento. Si el fragmento se instala en una línea diferente a la especificada en el diff, se le informa del desplazamiento. Un desplazamiento grande puede indicar que un fragmento se instaló en el lugar incorrecto. También se le informa si se utilizó un factor de ajuste para realizar la coincidencia, en cuyo caso también debe sospechar ligeramente. Si se da la opción --verbose, también se le informa sobre los fragmentos que coinciden exactamente.
Si no se especifica un archivo original origfile en la línea de comandos, patch intenta determinar a partir de la información inicial cuál es el nombre del archivo que se va a editar, utilizando las siguientes reglas.
Primero, patch toma una lista ordenada de nombres de archivo candidatos de la siguiente manera:
Si el encabezado es el de un diff de contexto, patch toma los nombres de archivo antiguos y nuevos en el encabezado. Se ignora un nombre si no tiene suficientes barras diagonales para satisfacer la opción -pnum o --strip=num. El nombre /dev/null también se ignora.
Si hay una línea Index: en la información inicial y si tanto los nombres antiguos como los nuevos están ausentes, o si patch se ajusta a POSIX, patch toma el nombre en la línea Index:.
Para los siguientes propósitos, los nombres de archivo candidatos se consideran en el orden (antiguo, nuevo, índice), independientemente del orden en que aparezcan en el encabezado.
Luego, patch selecciona un nombre de archivo de la lista de candidatos de la siguiente manera:
Si algunos de los archivos nombrados existen, patch selecciona el primer nombre si se ajusta a POSIX, y el mejor nombre en caso contrario.
Si patch no está ignorando RCS, ClearCase, Perforce y SCCS (vea la opción -g num o --get=num), y ningún archivo nombrado existe, pero se encuentra un maestro de RCS, ClearCase, Perforce o SCCS, patch selecciona el primer nombre de archivo con un maestro de RCS, ClearCase, Perforce o SCCS.
Si no existen archivos nombrados, no se encontró ningún maestro de RCS, ClearCase, Perforce o SCCS, se proporcionan algunos nombres, patch no se ajusta a POSIX y el parche parece crear un archivo, patch selecciona el mejor nombre que requiere la creación del menor número de directorios.
Si no se obtiene ningún nombre de archivo a partir de las heurísticas anteriores, se le pide el nombre del archivo que se va a aplicar el parche y patch selecciona ese nombre.
Para determinar el mejor de una lista no vacía de nombres de archivo, patch primero toma todos los nombres con la menor cantidad de componentes de ruta; de esos, luego toma todos los nombres con el nombre base más corto; de esos, luego toma todos los nombres más cortos; finalmente, toma el primer nombre restante.
Además, si el encabezado contiene una línea Prereq:, patch toma la primera palabra de la línea de requisitos previos (normalmente un número de versión) y verifica el archivo original para ver si esa palabra se puede encontrar. Si no es así, patch solicita confirmación antes de continuar.
La conclusión de todo esto es que debería poder ejecutar algo como el siguiente comando de shell:
patch -d /usr/src/local/blurfl
y aplicar un parche a un archivo en el directorio `blurfl` directamente desde un parche que se lee desde la entrada estándar.
Si el archivo de parche contiene más de un parche, patch intenta aplicar cada uno de ellos como si provinieran de archivos de parche separados. Esto significa, entre otras cosas, que se asume que el nombre del archivo que se va a aplicar el parche debe determinarse para cada listado de diferencias, y que el encabezado antes de cada listado de diferencias contiene cosas interesantes como nombres de archivo y nivel de revisión, como se mencionó anteriormente.
OPCIONES
-b o --backup
Crea archivos de copia de seguridad. Es decir, cuando se aplica un parche a un archivo, se cambia el nombre o se copia el archivo original en lugar de eliminarlo. Consulte la opción `-V` o `--version-control` para obtener más detalles sobre cómo se determinan los nombres de los archivos de copia de seguridad.
--backup-if-mismatch
Crea una copia de seguridad de un archivo si el parche no coincide exactamente con el archivo y si no se solicitan copias de seguridad. Este es el valor predeterminado a menos que `patch` cumpla con POSIX.
--no-backup-if-mismatch
No cree una copia de seguridad de un archivo si el parche no coincide exactamente con el archivo y si no se solicitan copias de seguridad. Este es el valor predeterminado si `patch` cumple con POSIX.
-B pref o --prefix=pref
Utilice el método simple para determinar los nombres de los archivos de copia de seguridad (consulte el método `-V` o el método `--version-control`) y agregue `pref` a un nombre de archivo al generar su nombre de archivo de copia de seguridad. Por ejemplo, con `-B /junk/` el nombre de archivo de copia de seguridad simple para `src/patch/util.c` es `/junk/src/patch/util.c`.
--binary
Escriba todos los archivos en modo binario, excepto la salida estándar y `/dev/tty`. Cuando se lee, deshabilite la heurística para transformar los finales de línea CRLF en finales de línea LF. Esta opción es necesaria en los sistemas POSIX al aplicar parches generados en sistemas no POSIX a archivos no POSIX. (En los sistemas POSIX, las lecturas y escrituras de archivos nunca transforman los finales de línea. En Windows, las lecturas y escrituras transforman los finales de línea de forma predeterminada, y los parches deben generarse mediante `diff --binary` cuando los finales de línea son significativos).
-c o --context
Interprete el archivo de parche como una diferencia de contexto normal.
-d dir o --directory=dir
Cambie al directorio `dir` inmediatamente, antes de hacer cualquier otra cosa.
-D define o --ifdef=define
Usar la construcción #ifdef ... #endif para marcar cambios, con define como símbolo diferenciador.
--dry-run
Mostrar los resultados de aplicar los parches sin modificar realmente ningún archivo.
-e o --ed
Interpretar el archivo de parche como un script ed.
-E o --remove-empty-files
Eliminar los archivos de salida que queden vacíos después de aplicar los parches. Normalmente esta opción es innecesaria, ya que patch puede examinar las marcas de tiempo en la cabecera para determinar si un archivo debería existir después del parcheado. Sin embargo, si la entrada no es un diff de contexto o si patch cumple con POSIX, patch no elimina los archivos parcheados vacíos a menos que se proporcione esta opción. Cuando patch elimina un archivo, también intenta eliminar cualquier directorio ancestro vacío.
-f o --force
Asumir que el usuario sabe exactamente lo que está haciendo y no hacer preguntas. Saltar los parches cuyas cabeceras no digan qué archivo debe ser parcheado; parchear archivos aunque tengan la versión incorrecta para la línea Prereq: en el parche; y asumir que los parches no están invertidos incluso si parecen estarlo. Esta opción no suprime los comentarios; use -s para eso.
-F num o --fuzz=num
Establecer el factor de imprecisión máximo. Esta opción solo se aplica a diffs que tienen contexto y hace que patch ignore hasta ese número de líneas de contexto al buscar lugares para instalar un fragmento. Tenga en cuenta que un factor de imprecisión mayor aumenta las probabilidades de un parche defectuoso. El factor de imprecisión predeterminado es 2. Un factor de imprecisión mayor o igual al número de líneas de contexto en el diff de contexto, normalmente 3, ignora todo el contexto.
-g num o --get=num
Esta opción controla las acciones de patch cuando un archivo está bajo control de RCS o SCCS, y no existe o es de solo lectura y coincide con la versión predeterminada, o cuando un archivo está bajo control de ClearCase o Perforce y no existe. Si num es positivo, patch obtiene (o hace checkout) el archivo del sistema de control de revisiones; si es cero, patch ignora RCS, ClearCase, Perforce y SCCS y no obtiene el archivo; y si es negativo, patch pregunta al usuario si desea obtener el archivo. El valor predeterminado de esta opción viene dado por el valor de la variable de entorno PATCH_GET si está configurada; si no, el valor predeterminado es cero.
--help
Mostrar un resumen de las opciones y salir.
-i archivo_parche o --input=archivo_parche
Leer el parche de archivo_parche. Si archivo_parche es -, leer de la entrada estándar, el valor predeterminado.
-l o --ignore-whitespace
Coincidir patrones de forma flexible, en caso de que los tabuladores o espacios se hayan alterado en sus archivos. Cualquier secuencia de uno o más espacios en el archivo de parche coincide con cualquier secuencia en el archivo original, y las secuencias de espacios al final de las líneas se ignoran. Los caracteres normales deben seguir coincidiendo exactamente. Cada línea del contexto debe seguir coincidiendo con una línea en el archivo original.
--merge o --merge=merge o --merge=diff3
Fusionar un archivo de parche en los archivos originales de manera similar a diff3(1) o merge(1). Si se encuentra un conflicto, patch emite una advertencia y delimita el conflicto con líneas <<<<<<< y >>>>>>>. Un conflicto típico se verá así:
<<<<<<<
líneas del archivo original
|||||||
líneas originales del parche
=======
nuevas líneas del parche
>>>>>>>
El argumento opcional de --merge determina el formato de salida para los conflictos: el formato diff3 muestra la sección ||||||| con las líneas originales del parche; en el formato merge, esta sección falta. El formato merge es el predeterminado.
Esta opción implica --forward y no tiene en cuenta la opción --fuzz=num.
-n o --normal
Interpreta el archivo de parche como un diff normal.
-N o --forward
Cuando un parche no se aplica, patch normalmente comprueba si el parche parece que ya se ha aplicado intentando aplicar el primer bloque en sentido inverso. La opción --forward evita esto. Consulte también -R.
-o outfile o --output=outfile
Envía la salida a outfile en lugar de aplicar los parches a los archivos in situ. No utilice esta opción si outfile es uno de los archivos que se van a aplicar. Cuando outfile es -, envía la salida a la salida estándar y envía cualquier mensaje que normalmente se enviaría a la salida estándar a la salida de error estándar.
-pnum o --strip=num
Elimina el prefijo más pequeño que contiene num barras diagonales iniciales de cada nombre de archivo que se encuentra en el archivo de parche. Una secuencia de una o más barras diagonales adyacentes se cuenta como una sola barra diagonal. Esto controla cómo se tratan los nombres de archivo que se encuentran en el archivo de parche, en caso de que guarde sus archivos en un directorio diferente al de la persona que envió el parche. Por ejemplo, suponiendo que el nombre de archivo en el archivo de parche es
/u/howard/src/blurfl/blurfl.c
establecer -p0 proporciona el nombre de archivo completo sin modificar, -p1 proporciona
u/howard/src/blurfl/blurfl.c
sin la barra diagonal inicial, -p4 proporciona
blurfl/blurfl.c
y no especificar -p proporciona simplemente blurfl.c. Lo que se obtenga se buscará ya sea en el directorio actual o en el directorio especificado por la opción -d.
--posix
Se ajusta más estrictamente al estándar POSIX, de la siguiente manera.
Toma el primer archivo existente de la lista (antiguo, nuevo, índice) al intuir los nombres de archivo de los encabezados diff.
No elimina los archivos que están vacíos después de aplicar el parche.
No pregunta si se deben obtener los archivos de RCS, ClearCase, Perforce o SCCS.
Requiere que todas las opciones precedan a los archivos en la línea de comandos.
No realiza copias de seguridad de los archivos cuando hay una discrepancia.
--quoting-style=word
Utiliza el estilo word para citar los nombres de salida. La palabra debe ser una de las siguientes:
literal
Muestra los nombres tal cual.
shell Cita los nombres para el shell si contienen metacaracteres del shell o provocarían una salida ambigua.
shell-always
Cita los nombres para el shell, incluso si normalmente no requieren ser citados.
c Cita los nombres como para una cadena de lenguaje C.
escape Cita como con c, excepto que omite los caracteres de comillas dobles circundantes.
Puede especificar el valor predeterminado de la opción --quoting-style con la variable de entorno QUOTING_STYLE. Si esa variable de entorno no está definida, el valor predeterminado es shell.
-r rejectfile o --reject-file=rejectfile
Coloca los archivos rechazados en rejectfile en lugar del archivo .rej predeterminado. Cuando rejectfile es -, descarta los archivos rechazados.
-R o --reverse
Asume que este parche fue creado con los archivos antiguo y nuevo intercambiados. (Sí, me temo que eso ocurre ocasionalmente, siendo la naturaleza humana como es). patch intenta intercambiar cada bloque antes de aplicarlo. Los archivos rechazados se generan en el formato intercambiado. La opción -R no funciona con scripts diff de ed porque hay muy poca información para reconstruir la operación inversa.
Si el primer bloque de un parche falla, patch invierte el bloque para ver si se puede aplicar de esa manera. Si se puede, se le pregunta si desea establecer la opción -R. Si no se puede, el parche continúa aplicándose normalmente. (Nota: este método no puede detectar un parche invertido si es un diff normal y si el primer comando es un añadido (es decir, debería haber sido una eliminación) ya que los añadidos siempre tienen éxito, debido al hecho de que un contexto nulo coincide en cualquier lugar. Afortunadamente, la mayoría de los parches añaden o cambian líneas en lugar de eliminarlas, por lo que la mayoría de los diffs normales invertidos comienzan con una eliminación, lo que falla, lo que activa la heurística).
--read-only=behavior
Comportarse según lo solicitado al intentar modificar un archivo de solo lectura: ignorar el posible problema, advertir al respecto (el valor predeterminado) o fallar.
--reject-format=format
Genera archivos rechazados en el formato especificado (ya sea contexto o unificado). Sin esta opción, los bloques rechazados se generan en formato diff unificado si el parche de entrada estaba en ese formato, de lo contrario, en formato diff de contexto ordinario.
-s o --silent o --quiet
Trabaja en silencio, a menos que ocurra un error.
--follow-symlinks
Al buscar archivos de entrada, sigue los enlaces simbólicos. Reemplaza los enlaces simbólicos, en lugar de modificar los archivos a los que apuntan los enlaces simbólicos. Los parches de estilo Git a los enlaces simbólicos ya no se aplicarán. Esta opción existe para la compatibilidad con versiones anteriores de patch; su uso no se recomienda.
-t o --batch
Suprime preguntas como -f, pero hace algunas suposiciones diferentes: omite los parches cuyos encabezados no contienen nombres de archivo (igual que -f); omite los parches para los que el archivo tiene la versión incorrecta para la línea Prereq: en el parche; y asume que los parches están invertidos si parece que lo están.
-T o --set-time
Establece las horas de modificación y acceso de los archivos parcheados a partir de las marcas de tiempo dadas en los encabezados diff de contexto. A menos que se especifique en las marcas de tiempo, asume que los encabezados diff de contexto utilizan la hora local.
El uso de esta opción con marcas de tiempo que no incluyen zonas horarias no se recomienda, porque los parches que utilizan la hora local no se pueden utilizar fácilmente por personas en otras zonas horarias, y porque las marcas de tiempo locales son ambiguas cuando los relojes locales se retrasan durante los ajustes del horario de verano. Asegúrese de que las marcas de tiempo incluyan zonas horarias, o genere parches con UTC y utilice la opción -Z o --set-utc en su lugar.
-u o --unified
Interpreta el archivo de parche como un diff de contexto unificado.
-v o --version
Imprime el encabezado de revisión y el nivel de parche, y sale.
-V method o --version-control=method
Utiliza method para determinar los nombres de los archivos de respaldo. El valor de method también puede ser dado por la variable de entorno PATCH_VERSION_CONTROL (o, si no está establecida, la variable de entorno VERSION_CONTROL), que es sobreescrita por esta opción. El valor de method no afecta si se crean o no archivos de respaldo; afecta solo los nombres de los archivos de respaldo que se creen.
El valor de method es similar a la variable version-control de GNU Emacs; patch también reconoce sinónimos que son más descriptivos. Los valores válidos para method son (se aceptan abreviaturas únicas):
existing o nil
Crea respaldos numerados de los archivos que ya los tienen, de lo contrario, crea respaldos simples. Este es el valor predeterminado.
numbered o t
Crea respaldos numerados. El nombre del archivo de respaldo numerado para F es F.~N~, donde N es el número de versión.
simple o never
Crea respaldos simples. Las opciones -B o --prefix, -Y o --basename-prefix, y -z o --suffix especifican el nombre del archivo de respaldo simple. Si no se proporciona ninguna de estas opciones, se utiliza un sufijo de respaldo simple; es el valor de la variable de entorno SIMPLE_BACKUP_SUFFIX si está establecida, y es .orig de lo contrario.
Con respaldos numerados o simples, si el nombre del archivo de respaldo es demasiado largo, se utiliza el sufijo de respaldo ~ en su lugar; si incluso agregar ~ haría que el nombre fuera demasiado largo, entonces ~ reemplaza el último carácter del nombre del archivo.
--verbose
Muestra información adicional sobre el trabajo que se está realizando.
-x num o --debug=num
Establece banderas de depuración internas de interés solo para los programadores de patch.
-Y pref o --basename-prefix=pref
Utiliza el método simple para determinar los nombres de los archivos de respaldo (vea la opción -V method o --version-control method), y agrega el prefijo pref al nombre base de un archivo cuando se genera su nombre de archivo de respaldo. Por ejemplo, con -Y .del/ el nombre del archivo de respaldo simple para src/patch/util.c es src/patch/.del/util.c.
-z suffix o --suffix=suffix
Utiliza el método simple para determinar los nombres de los archivos de respaldo (vea la opción -V method o --version-control method), y utiliza suffix como el sufijo. Por ejemplo, con -z - el nombre del archivo de respaldo para src/patch/util.c es src/patch/util.c-.
-Z o --set-utc
Establece las horas de modificación y acceso de los archivos parcheados a partir de las marcas de tiempo dadas en los encabezados del diff de contexto. A menos que se especifique en las marcas de tiempo, asume que los encabezados del diff de contexto utilizan el Tiempo Universal Coordinado (UTC, a menudo conocido como GMT). También vea la opción -T o --set-time.
Las opciones -Z o --set-utc y -T o --set-time normalmente se abstienen de establecer la hora de un archivo si la hora original del archivo no coincide con la hora dada en el encabezado del parche, o si su contenido no coincide exactamente con el parche. Sin embargo, si se proporciona la opción -f o --force, la hora del archivo se establece independientemente.
Debido a las limitaciones del formato de salida de diff, estas opciones no pueden actualizar las horas de los archivos cuyos contenidos no han cambiado. Además, si utiliza estas opciones, debe eliminar (por ejemplo, con make clean) todos los archivos que dependen de los archivos modificados, para que las invocaciones posteriores de make no se confundan con las horas de los archivos modificados.
ENTORNO
`PATCH_GET`
Esto especifica si `patch` obtiene los archivos faltantes o de solo lectura desde RCS, ClearCase, Perforce o SCCS de forma predeterminada; consulte la opción `-g` o `--get`.
`POSIXLY_CORRECT`
Si se establece, `patch` se ajusta más estrictamente al estándar POSIX de forma predeterminada; consulte la opción `--posix`.
`QUOTING_STYLE`
Valor predeterminado de la opción `--quoting-style`.
`SIMPLE_BACKUP_SUFFIX`
Extensión que se utilizará para los nombres de los archivos de copia de seguridad simples en lugar de `.orig`.
`TMPDIR`, `TMP`, `TEMP`
Directorio donde se colocan los archivos temporales; `patch` utiliza la primera variable de entorno de esta lista que se establece. Si no se establece ninguna, el valor predeterminado depende del sistema; normalmente es `/tmp` en los hosts Unix.
`VERSION_CONTROL` o `PATCH_VERSION_CONTROL`
Selecciona el estilo de control de versiones; consulte la opción `-v` o `--version-control`.
ARCHIVOS
`$TMPDIR/p*`
archivos temporales
`/dev/tty`
terminal de control; se utiliza para obtener respuestas a las preguntas que se le hacen al usuario
VÉASE TAMBIÉN
[diff]({filename}../../diff)(1), `ed(1)`, `merge(1)`.
Marshall T. Rose y Einar A. Stefferud, Proposed Standard for Message Encapsulation, Internet RFC 934 [https://datatracker.ietf.org/doc/html/rfc934] (1985-01).
NOTAS PARA LOS REMITENTES DE PARCHES
Hay varias cosas que debe tener en cuenta si va a enviar parches.
Cree su parche de forma sistemática. Cuando utilice un sistema de control de versiones, esto debería ser fácil; por ejemplo, con Git puede utilizar git diff. De lo contrario, un buen método es el comando diff -Naur old new, donde old y new identifican los directorios antiguos y nuevos. Los nombres old y new no deben contener barras.
Si el parche debe comunicar las marcas de tiempo de los archivos, así como el contenido de los archivos, los encabezados de los comandos diff deben tener fechas y horas en tiempo universal utilizando el formato Unix tradicional, para que los destinatarios del parche puedan utilizar la opción -Z o --set-utc. Aquí hay un ejemplo de comando para generar tales encabezados, utilizando la sintaxis de Bourne shell:
LC_ALL=C TZ=UTC0 diff -Naur myprog-2.7 myprog-2.8
Indique a sus destinatarios cómo aplicar el parche indicándoles a qué directorio deben dirigirse y qué opciones de parche deben utilizar. La cadena de opciones -Np1 es recomendable. Pruebe su procedimiento pretendiendo ser un destinatario y aplicando su parche a una copia de los archivos originales.
Puede ahorrar a las personas muchos problemas manteniendo un archivo patchlevel.h que se modifica para incrementar el nivel de parche como el primer diff en el archivo de parche que envía. Si coloca una línea Prereq: con el parche, no les permitirá aplicar los parches fuera de orden sin una advertencia.
Puedes crear un archivo enviando un diff que compare /dev/null o un archivo vacío con fecha del
Época (1970-01-01 00:00:00 UTC) con el archivo que deseas crear. Esto solo funciona si el archivo
que deseas crear no existe ya en el directorio de destino. Inversamente, puedes eliminar un archivo
enviando un diff de contexto que compare el archivo que se va a eliminar con un archivo vacío con fecha del
Época. El archivo se eliminará a menos que patch cumpla con POSIX y no se proporcione la opción -E o --remove-empty-files. Una forma sencilla de generar parches que creen y eliminen
archivos es usar la opción -N o --new-file de GNU diff.
Si se espera que el destinatario use la opción -pN, no envíes una salida que se vea así:
diff -Naur v2.0.29/prog/README prog/README
--- v2.0.29/prog/README Mon Mar 10 15:13:12 2024
+++ prog/README Mon Mar 17 14:58:22 2024
porque los dos nombres de archivo tienen un número diferente de barras diagonales y diferentes versiones de patch interpretan los
nombres de archivo de manera diferente. Para evitar confusiones, envía en su lugar una salida que se vea así:
diff -Naur v2.0.29/prog/README v2.0.30/prog/README
--- v2.0.29/prog/README Mon Mar 10 15:13:12 2024
+++ v2.0.30/prog/README Mon Mar 17 14:58:22 2024
Evita enviar parches que comparen nombres de archivos de respaldo como README.orig, ya que esto podría confundir
a patch y hacer que aplique el parche a un archivo de respaldo en lugar del archivo real. En su lugar, envía parches que comparen
los mismos nombres de archivos base en diferentes directorios, por ejemplo, old/README y new/README.
Ten cuidado de no enviar parches invertidos, ya que esto hace que la gente se pregunte si ya aplicaron el parche.
Intenta no tener parches que modifiquen archivos derivados (por ejemplo, el archivo configure donde hay una línea
^ onfigure: configure.ac en tu archivo Makefile), ya que el destinatario debería poder regenerar los
archivos derivados de todos modos. Si debes enviar diffs de archivos derivados, genera los
diffs usando UTC, haz que los destinatarios apliquen el parche con la opción -Z o --set-utc, y haz que eliminen cualquier archivo no parcheado que dependa de archivos parcheados (por ejemplo, con make clean).
Si bien es posible que puedas salir adelante colocando 582 listados de diff en un solo archivo, podría ser más prudente agrupar los parches relacionados en archivos separados en caso de que algo salga mal.
DIAGNÓSTICOS
Los diagnósticos generalmente indican que patch no pudo analizar tu archivo de parche.
Si se da la opción --verbose, el mensaje Hmm... indica que hay texto no procesado en
el archivo de parche y que patch está intentando deducir si hay un parche en ese texto y,
en caso afirmativo, qué tipo de parche es.
El estado de salida de patch es 0 si todos los fragmentos se aplican correctamente, 1 si algunos fragmentos no se pueden aplicar
o hubo conflictos de fusión y 2 si hay problemas más graves. Al aplicar un conjunto de
parches en un bucle, debes verificar este estado de salida para no aplicar un parche posterior a un
archivo parcialmente parcheado.
PRECAUCIONES
Los diffs de contexto no pueden representar de manera confiable la creación o eliminación de archivos vacíos, directorios vacíos o archivos especiales como enlaces simbólicos. Tampoco pueden representar cambios en los metadatos de los archivos como la propiedad, los permisos o si un archivo es un enlace físico a otro. Si también se requieren cambios como estos, instrucciones separadas (por ejemplo, un script de shell) para lograrlos deben acompañar al parche.
patch no puede determinar si los números de línea son incorrectos en un script ed, y solo puede detectar números de línea incorrectos en un diff normal cuando encuentra un cambio o una eliminación. Un diff de contexto que use un factor de tolerancia de 3 puede tener el mismo problema. En estos casos, probablemente deberías hacer un diff de contexto para ver si los cambios tienen sentido. Por supuesto, compilar sin errores es una buena indicación de que el parche funcionó, pero no siempre.
patch normalmente produce los resultados correctos, incluso cuando tiene que hacer muchas suposiciones. Sin embargo, los resultados solo están garantizados si el parche se aplica exactamente a la misma versión del archivo del que se generó el parche.
PROBLEMAS DE COMPATIBILIDAD
El estándar POSIX especifica un comportamiento diferente al de GNU patch.
En POSIX patch, cuando no se usa -b, no se crean copias de seguridad, incluso cuando hay una discrepancia. En GNU patch, este comportamiento se habilita con la opción --no-backup-if-mismatch, o cumpliendo con POSIX con la opción --posix o estableciendo la variable de entorno POSIXLY_CORRECT.
Cuando patch infiere el nombre del archivo que se va a aplicar desde la cabecera del parche, utiliza un método complicado que es opcionalmente compatible con POSIX. El método es equivalente a POSIX si los nombres de archivo en la cabecera del diff de contexto y la línea Index: son todos idénticos después de eliminar los prefijos. Tu parche normalmente es compatible si cada nombre de archivo en la cabecera contiene el mismo número de barras.
Limítate a las siguientes opciones al enviar instrucciones que deban ser ejecutadas por cualquier persona que utilice GNU patch o un patch que cumpla con POSIX. Los espacios son opcionales en la siguiente lista.
-b
-c
-d dir
-D define
-e
-i patchfile
-l
-n
-N
-o outfile
-p num
-R
-r rejectfile
-u
ERRORES
Por favor, informa sobre los errores por correo electrónico a <_>.
Si el código ha sido duplicado (por ejemplo, con #ifdef OLDCODE ... #else ... #endif), patch es incapaz de aplicar el parche a ambas versiones, y, si lo hace, probablemente aplicará el parche a la versión incorrecta y te dirá que tuvo éxito.
Si aplicas un parche que ya has aplicado, patch piensa que es un parche invertido y te ofrece la posibilidad de deshacer la aplicación del parche. Esto podría considerarse una característica.
Calcular cómo combinar un fragmento es significativamente más difícil que usar el algoritmo de tolerancia estándar. Los fragmentos más grandes, más contexto, un mayor desplazamiento desde la ubicación original y una peor coincidencia, todos hacen que el algoritmo sea más lento.
COPYRIGHT
Copyright © 1989–2025 Free Software Foundation, Inc. Copyright © 1984–1986, 1988 Larry Wall.
Se concede permiso para realizar y distribuir copias literales de este manual, siempre que el aviso de copyright y este aviso de permiso se conserven en todas las copias.
Se concede permiso para copiar y distribuir versiones modificadas de este manual bajo las condiciones para la copia textual, siempre que toda la obra derivada resultante se distribuya bajo los términos de un aviso de permiso idéntico a este.
Se concede permiso para copiar y distribuir traducciones de este manual a otro idioma, bajo las condiciones anteriores para las versiones modificadas, excepto que este aviso de permiso puede incluirse en las traducciones aprobadas por los titulares de los derechos de autor en lugar de en el inglés original.
AUTORES
Larry Wall escribió la versión original de patch. Paul Eggert eliminó los límites arbitrarios de patch; agregó soporte para archivos binarios, la configuración de las horas de los archivos y la eliminación de archivos; y lo hizo más conforme con POSIX. Otros colaboradores incluyen a Wayne Davison, quien agregó soporte para unidiff, y a David MacKenzie, quien agregó soporte para la configuración y las copias de seguridad. Andreas Gruenbacher agregó soporte para la fusión.