Use parche para parchear el código, rápido y eficiente, la diferencia entre parche -p1 y p0

  • Generar parche:
git diff > file.patch
  • Golpear parche:
patch -p1 < file.patch
git apply file.patch
说到patch命令,就不得不提到diff命令,也就是制作patch的必要工具。diff命令,在制作patch文件的时候,基本上只需要使用到diff -Nau 这个参数,如果比较的是文件夹,还要加上-r参数,所以一般直接使用Naur参数。

实验的基本步骤。我打算是建立一个级联目录./x/xx/xxx/,在xxx目录下建立两个不同的文件xxx1,xxx2。然后在xxx目录下用diff命令,建立一个补丁文件xxx.patch,在xx目录下建立一个补丁文件xx.patch,在x目录下建立一个补丁文件x.patch。然后在这三个目录下实验。

Iniciar experimento : crear directorio de experimentos
[King @ Fedora ~] $ mkdir -pv x / xx / xxx
mkdir: directorio creado “x”
mkdir: directorio creado “x / xx”
mkdir: directorio creado “x / xx / xxx"

Ingrese al directorio xxx para crear xxx1, xxx2

[King@Fedora ~]$ cd x/xx/xxx
[King@Fedora xxx]$ cat >> xxx1 << EOF
> 111111
> 111111
> EOF
[King@Fedora xxx]$ cat >> xxx2 << EOF
> 111111
> 222222
> EOF

Vea estos dos archivos:

[King@Fedora xxx]$ diff -y xxx1 xxx2
111111                                111111
111111                           |    222222

Debe prestar atención : el directorio donde se encuentra el parche

在xxx目录下创建补丁文件xxx.patch,并查看。
[King@Fedora xxx]$ diff -Naru xxx1 xxx2 > xxx.patch
[King@Fedora xxx]$ cat xxx.patch 
- - - xxx1    2009-12-19 22:28:26.582959182 +0800
+++ xxx2    2009-12-19 22:28:42.798928591 +0800
@@ -1,2 +1,2 @@
  111111
- 111111
+222222

Cree el archivo de parche xx.patch en el directorio xx y vea:

[King@Fedora xxx]$ cd ..
[King@Fedora xx]$ diff -Naru xxx/xxx1 xxx/xxx2 > xx.patch
[King@Fedora xx]$ cat xx.patch 
--- xxx/xxx1    2009-12-19 22:28:26.582959182 +0800
+++ xxx/xxx2    2009-12-19 22:28:42.798928591 +0800
@@ -1,2 +1,2 @@
111111
-111111
+222222

Cree un archivo de parche x.patch en el directorio x y vea

[King@Fedora xx]$ cd ..
[King@Fedora x]$ diff -Nu xx/xxx/xxx1 xx/xxx/xxx2 > x.patch
[King@Fedora x]$ cat x.patch 
--- xx/xxx/xxx1    2009-12-19 22:28:26.582959182 +0800
+++ xx/xxx/xxx2    2009-12-19 22:28:42.798928591 +0800
@@ -1,2 +1,2 @@
111111
-111111
+222222

Ahora copie todos los archivos de parche en el directorio xxx.

[King@Fedora x]$ cp x.patch xx/xxx/
[King@Fedora x]$ cp xx/xx.patch xx/xxx/

Ingrese al directorio xxx para comenzar el experimento

[King@Fedora x]$ cd xx/xxx
[King@Fedora xxx]$ ls
x.patch  xx.patch  xxx1  xxx2  xxx.patch
[King@Fedora xxx]$ patch-p0< xxx.patch  #用第二个的 补丁 修改 第一个文件
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
222222
[King@Fedora xxx]$ patch -RE < xxx.patch #用第一个的 补丁 修改 第一个文件
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
111111
[King@Fedora xxx]$ patch -p1 < xx.patch
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
222222
[King@Fedora xxx]$ patch -RE < xxx.patch
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
111111
[King@Fedora xxx]$ patch -p2 < x.patch
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
222222
[King@Fedora xxx]$ patch -RE < x.patch
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
111111
[King@Fedora xx]$ patch-p0 < xx.patch  # 用第二个的 补丁 修改 第一个文件
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
222222
[King@Fedora xxx]$ patch -RE < xxx.patch #用第一个的 补丁 修改 第一个文件
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
111111

[King@Fedora xxx]$ patch -p1 < x.patch
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
222222
[King@Fedora xxx]$ patch -RE < xxx.patch
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
111111
[King@Fedora x]$ patch-p0< x.patch  # 用第二个的 补丁 修改 第一个文件
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
222222
[King@Fedora xxx]$ patch -RE < xxx.patch #用第一个的 补丁 修改 第一个文件
patching file xxx1
[King@Fedora xxx]$ cat xxx1
111111
111111

Lo único que debe explicarse aquí es el significado de p0, porque la información de la ruta en el archivo de parche x.patch es así:

--- xx/xxx/xxx1   

** p significa omitir varios niveles de directorios. ** Debido a que es el comando de parche que se usa en el directorio x, el directorio xx está debajo del directorio x, por lo que no es necesario omitir ningún directorio, sino la ruta completa xx / Se debe usar xxx / xxx1, por lo tanto, se usa p0 en este momento.

Nota: No se permiten números negativos después del parche -p. Cuando no se usa el parámetro p, el comando patch ignora cualquier directorio y usa el archivo directamente.

[King @ Fedora x] $ parche x / xx / xxx / xxx1 <x.patch # Utilice el parche x.patch para modificar directamente el archivo xxx1, debido a que no se usa el parámetro p, se ignorarán todos los directorios del archivo del parche.

Como programador, es muy necesario comprender el comando diff & patch. Por ejemplo, si encontramos que un proyecto tiene un código de error y no tenemos el permiso para enviarlo, la solución más apropiada en este momento es usar el comando diff para hacer un parche y enviarlo a los miembros del proyecto. Los miembros del proyecto pueden conocer inmediatamente sus intenciones a través del comando patch. Algunas personas dirán que es más fácil cargar un archivo nuevo directamente. No olvide que un archivo de parche es más pequeño y más rápido de transferir, y puede ver claramente qué cambios se han realizado.

El ejemplo asegura que el directorio actual es el directorio de demostración:

mkdir demo
cd demo

Primero simule un directorio de proyecto antiguo:

mkdir -p old/a/b
vi old/a/b/foo.txt
old_line_1
old_line_2

Supongamos que encontramos que el proyecto anterior tiene un código de error, primero copiemos un nuevo directorio nuevo y modifiquemos el código de error aquí:

cp -r old new
vi new/a/b/foo.txt
new_line_1
new_line_2

Asegúrese de que tanto el directorio antiguo como el nuevo estén en el directorio actual. El comando diff se puede usar a continuación. No use rutas absolutas, pero use rutas relativas. En cuanto a la razón, será claro al final del artículo:

LC_ALL=C TZ=UTC0 diff -Naur old new > foo.patch

Si no le importa el juego de caracteres, la diferencia horaria, etc., también puede omitir la variable de entorno LC_ALL = C TZ = UTC0:

diff -Naur old new > foo.patch

El contenido es de Linuxren.net.
El parámetro -Naur es un uso fijo. La mayoría de las veces, puede usar este parámetro con el comando diff.

Examine aproximadamente el archivo de parche:

cat foo.patch
diff -Naur old/a/b/foo.txt new/a/b/foo.txt
--- old/a/b/foo.txt     2009-12-07 20:40:07.000000000 +0800
+++ new/a/b/foo.txt     2009-12-07 20:41:51.000000000 +0800
@@ -1,2 +1,2 @@
-old_line_1
-old_line_2
+new_line_1
+new_line_2

El contenido después del signo más y menos es contenido útil, y el otro contenido es el contenido de información relevante para su conveniencia. El parche está completo.
La estructura del directorio de archivos en este momento es aproximadamente la siguiente:

#tree
demo
|-- old
|   `-- a
|       `-- b
|           `-- foo.txt
|-- new
|   `-- a
|       `-- b
|           `-- foo.txt 
-- foo.patch

Echemos un vistazo a cómo usar el parche para aplicar parches. Tenga en cuenta que el directorio actual es una demostración. Pruebe el siguiente comando:

 patch -p0 < foo.patch
patching file old/a/b/foo.txt

Lo único que debe explicarse aquí es el significado de p0, porque la información de la ruta en el archivo de parche foo.patch es así:

--- old/a/b/foo.txt

p significa omitir varios niveles de directorios. Debido a que es el comando de parche utilizado en el directorio de demostración, el directorio anterior está debajo del directorio de demostración, por lo que no es necesario omitir ningún directorio, sino la ruta completa de / a / b anterior Se debe usar /foo.txt, por lo que en este momento, se usa p0.

Verifique el archivo de destino, encontrará que el contenido se ha modificado a uno nuevo:

# cat old/a/b/foo.txt
new_line_1
new_line_2

En este punto, si usa el comando patch nuevamente, el sistema le preguntará si desea restaurar, ingrese y para restaurar:

# patch -p0 < foo.patch
patching file old/a/b/foo.txt
Reversed (or previously applied) patch detected!  Assume -R? [n] y

Verifique el archivo de destino, encontrará que el contenido se ha restaurado al anterior:

# cat old/a/b/foo.txt
old_line_1
old_line_2

Si desea especificar estrictamente que se aplicará el parche, puede usar el siguiente comando (es decir, aumentar el parámetro N):

# patch -Np0 < foo.patch

Si desea especificar estrictamente restaurar el parche, puede usar el siguiente comando (es decir, aumentar el parámetro R):

# patch -Rp0 < foo.patch

Nota: En este ejemplo, después de aplicar cada parche, restaure el parche usted mismo para que pueda continuar probándolo más tarde. No diré más.

Vea aquí si no está seguro acerca del parámetro p del parche, luego mire hacia abajo, cambiemos la ruta actual:

# cd old

En este momento, debería ser p1, no p0, y la ruta para hacer referencia al archivo foo.patch también debería cambiarse relativamente, porque el directorio actual ya es antiguo: Linuxren.net

# patch -p1 < ../foo.patch
patching file a/b/foo.txt

Porque en este momento estamos usando el comando patch en old, que está al nivel del subdirectorio a, y la declaración de ruta en el archivo de parche foo.patch es:

--- old/a/b/foo.txt

Es decir, la parte antigua / a la izquierda de la primera barra es inútil. ¡Este es el significado de p1!
Continúe cambiando la ruta a la profundidad y pruebe y use los parámetros p2, p3 a su vez:

# cd a
# patch -p2 < ../../foo.patch
patching file b/foo.txt
# cd b
# patch -p3 < ../../../foo.patch
patching file foo.txt

En este ejemplo, p3 ya es el directorio más profundo y el parámetro p se puede omitir en este momento:

# patch < ../../../foo.patch
patching file foo.txt

En otras palabras, cuando no se usa el parámetro p, el comando patch ignorará cualquier directorio y usará el archivo directamente.

Siguiendo el artículo mencionado anteriormente, ¿por qué es mejor no usar una ruta absoluta cuando se usa el comando diff, sino usar una ruta relativa?

Respuesta: Si usa una ruta absoluta cuando usa diff, la información de la ruta del archivo en el archivo de parche será similar a la siguiente:

--- /a/b/c/d/e/f/g/bar.txt
	如此一来,当别人想应用你的补丁时,因为目录结构肯定有差异,所以就不得不费力判断到底使用p几。这样一来就很容易出错,相反,如果使用相对路径的话,大多数时候,p0或者p1就足够了,不易出错。

Algunas explicaciones de uso obtenidas por la Enciclopedia Baidu: El
comando diff de Linux se usa para comparar las diferencias de archivos:
diff compara las similitudes y diferencias de archivos de texto línea por línea. Si especifica comparar directorios, diff comparará archivos con el mismo nombre de archivo en el directorio, pero no comparará subdirectorios.

Sintaxis
diff [-abBcdefHilnNpPqrstTuvwy] [- <número de líneas>] [- C <número de líneas>] [- D <nombre de macro>] [- I <carácter o cadena>] [- S <archivo>] [- W <ancho>] [- x <archivo o directorio>] [- X <archivo>] [- ayuda] [- columna-izquierda] [- suprimir-línea-común] [archivo o directorio 1] [archivo o directorio 2]
parámetro:

- <Número de líneas> Especifique cuántas líneas de texto se mostrarán. Este parámetro debe utilizarse junto con el parámetro -co -u. El ajuste preestablecido -a o -text diff solo comparará archivos de texto línea por línea. -b o -ignore-space-change no comprueba las diferencias en los caracteres de espacio.

-B o -ignore-blank-lines no comprueba si hay líneas en blanco.
-c muestra todo el texto y marca las diferencias.
-C <número de líneas> o -context <número de líneas> es lo mismo que ejecutar el comando "-c- <número de líneas>".
-do -minimal usa un algoritmo diferente y compara en unidades más pequeñas.
-D <nombre de macro> o ifdef <nombre de macro> El formato de salida de este parámetro se puede utilizar para macros de preprocesador.
-e o -ed El formato de salida de este parámetro se puede utilizar para archivos de script ed.
El formato de salida de -fo -forward-ed es similar al archivo de script de ed, pero la diferencia se muestra en el orden del archivo original.
-H o -speed-large-files pueden aumentar la velocidad al comparar archivos grandes.
-l <carácter o cadena> o --ignore-matching-lines <carácter o cadena> Si dos archivos son diferentes en ciertas líneas, y todas estas líneas contienen el carácter o cadena especificada en la opción, la diferencia entre estos dos archivos es no se muestra.
-yo -ignore-case no comprueba la diferencia entre mayúsculas y minúsculas.
-l o -paginate pasarán los resultados al programa pr para la paginación.
-no -rcs mostrará el resultado de la comparación en formato RCS.
-N o –nuevo-archivo Al comparar directorios, si el archivo A solo aparece en un directorio determinado, se mostrará el valor predeterminado:
Solo en el directorio: si el archivo A usa el parámetro -N, diff comparará el archivo A con una comparación de archivos en blanco.
-p Si el archivo comparado es un archivo de código de programa en lenguaje C, muestra el nombre de la función de la diferencia.
-P o -unidirectional-new-file es similar a -N, pero solo cuando el segundo directorio contiene un archivo que el primer directorio no tiene, este archivo se comparará con un archivo en blanco.
-q o -brief solo muestra si hay diferencias y no muestra información detallada.
-ro -recursivo Compara archivos en subdirectorios.
-s o -report-idénticos-archivos Si no se encuentran diferencias, la información aún se muestra.
-S <archivo> o --starting-file <archivo> Al comparar directorios, inicie la comparación desde el archivo especificado.
-to -expand-tabs expanden los caracteres de tabulación durante la salida.
-T o -initial-tab Añada caracteres de tabulación delante de cada línea para la alineación.
-u, -U <número de columnas> o -unified = <número de columnas> para mostrar las diferencias en el contenido del archivo de forma combinada.
-v o -version muestra información sobre la versión.
-w o -ignore-all-space Ignora todos los caracteres de espacio.
-W <width> o -width <width> Cuando utilice el parámetro -y, especifique el ancho de la columna.
-x <nombre de archivo o directorio> o -exclude <nombre de archivo o directorio> No compare los archivos o directorios especificados en la opción.
-X <archivo> o –excluir-de <archivo> Puede guardar el tipo de archivo o directorio como un archivo de texto y luego ingresar = <archivo> Especifique este archivo de texto en formato.
-y o -side-by-side muestra las similitudes y diferencias de los archivos en paralelo.
-Ayuda Mostrar ayuda.
--Left-column Cuando se usa el parámetro -y, si el contenido de una línea de dos archivos es el mismo, solo el contenido de esa línea se mostrará en la columna de la izquierda.
--Suppress-common-lines Cuando se usa el parámetro -y, solo se muestran las diferencias.

El comando de parche de Linux se usa para parchear archivos.
El comando de parche permite a los usuarios modificar y actualizar el archivo original configurando el archivo de parche. Si modifica solo un archivo a la vez, puede emitir instrucciones directamente en la línea de comando para ejecutarlas en secuencia. Si coopera con el método de parchear archivos, puede parchear una gran cantidad de archivos a la vez, que también es uno de los métodos de actualización principales del sistema Linux.


Parche de sintaxis [-bceEflnNRstTuvZ] [- B <cadena de prefijo de respaldo>] [- d <directorio de trabajo>] [- D <símbolo de etiqueta>] [- F <número de columnas de monitoreo>] [- g <valor de control>] [ -i <archivo de corrección>] [- o <archivo de salida>] [- p <nivel de eliminación>] [- r <archivo de rechazo>] [- V <método de respaldo>] [- Y <cadena de prefijo de respaldo>] [- z <cadena de sufijo de respaldo>] [- respaldo-si-no coincide] [- binario] [- ayuda] [- no respaldo-si-no coincide] [- detallado] [archivo original <archivo parcheado>] o ruta [-p <eliminación nivel>] <[archivo de parche]
parámetros:

-b o -backup Realiza una copia de seguridad de cada archivo original.
-B <cadena de prefijo de copia de seguridad> o –prefix = <cadena de prefijo de copia de seguridad> Al configurar la copia de seguridad del archivo, la cadena de prefijo se agrega delante del nombre del archivo. Esta cadena puede ser un nombre de ruta.
-co -context interpreta los datos parcheados como diferencias de relevancia.
-d <directorio de trabajo> o –directory = <directorio de trabajo> Establece el directorio de trabajo.
-D <símbolo de etiqueta> o -ifdef = <símbolo de etiqueta> Marque el lugar cambiado con el símbolo especificado.
-e o -ed Interpreta los datos parcheados en un archivo narrativo que puede ser utilizado por el comando ed.
-E o -remove-empty-files Si el contenido del archivo de salida está en blanco después de la revisión, elimine el archivo.
-fo -force El efecto de este parámetro es similar a especificar el parámetro "-t", pero asumirá que la versión de los datos parcheados es una nueva versión.
-F <número de columnas de supervisión> o -fuzz <número de columnas de supervisión> Establece el número máximo de columnas de supervisión.
-g <valor de control> o –get = <valor de control> Configure RSC o SCCS para controlar la operación de reparación.
-i <archivo de parche> o -input = <archivo de parche> Lea el parche especificado y le preguntará.
-l o -ignore-whitespace Ignora las tabulaciones y los espacios entre los datos parcheados y los datos de entrada.
-no -normal interpretan los datos reparados como diferencias generales.
-N o -forward Ignora los datos parcheados que son más antiguos que la versión del archivo original, o los datos parcheados de esta versión ya se han utilizado.
-o <archivo de salida> o --output = <archivo de salida> Establezca el nombre del archivo de salida y el archivo reparado se almacenará con este nombre.
-p <nivel de eliminación> o --strip = <nivel de eliminación> Establece los nombres de ruta de varias capas que se eliminarán.
-f <archivo de rechazo> o - archivo de rechazo = <archivo de rechazo> Establezca el nombre del archivo que guarda la información sobre el parche de rechazo. El nombre de archivo predeterminado es .rej.
-R o -reverse asume que los datos de reparación se generan intercambiando la ubicación de los archivos nuevos y antiguos.
-s o -quiet o -silent no muestran el proceso de ejecución del comando a menos que ocurra un error.
-t o -batch omite automáticamente los errores y no hace ninguna pregunta.
-T o -set-time El efecto de este parámetro es similar al de especificar el parámetro "-Z", pero se basa en la hora local.
-u o -unified Interpreta los datos parcheados en diferencias uniformes.
-v o -version muestra información sobre la versión.
-V <método de copia de seguridad> o –version-control = <método de copia de seguridad> Después de realizar la copia de seguridad del archivo de destino con el parámetro "-b", se agregará una cadena de copia de seguridad al sufijo del archivo de copia de seguridad. Esta cadena no se puede utilizar solo con cambios de parámetro "-z", cuando se usa el parámetro "-V" para especificar diferentes métodos de respaldo, también se generarán cadenas de respaldo con diferentes sufijos.
-Y <cadena de prefijo de copia de seguridad> o –basename-prefix = - <cadena de prefijo de copia de seguridad> Al configurar la copia de seguridad del archivo, la cadena de prefijo se agrega al principio del nombre base del archivo.
-z <cadena de sufijo de respaldo> o –suffix = <cadena de sufijo de respaldo> El efecto de este parámetro es similar al parámetro "-B" especificado, la diferencia es que la ruta y el nombre de archivo usados ​​por el trabajo de parche son src / linux / fs /super.c, después de agregar la cadena "backup /", el archivo super. c se respaldará en el directorio / src / linux / fs / backup.
-Z o -set-utc Cambie el archivo parcheado y establezca la hora de acceso a UTC.
- Copia de seguridad si no coincide Se realiza una copia de seguridad del archivo cuando los datos reparados no coinciden por completo y no se especifica que se realice una copia de seguridad deliberadamente.
-Binary Lee y escribe datos en modo binario sin pasar por el dispositivo de salida estándar.
--Ayuda Ayuda en línea.
--Nobackup-if-discretch No realice una copia de seguridad de los archivos cuando los datos reparados no coincidan completamente y los archivos de los que se va a realizar la copia de seguridad no se especifiquen deliberadamente.
--Verbose muestra el proceso de ejecución de la instrucción en detalle

Supongo que te gusta

Origin blog.csdn.net/yangdashi888/article/details/103736873
Recomendado
Clasificación