2010-10-10 13 views
29

A veces, por cualquier razón, tengo que producir archivos de parche (en Linux) que están en la dirección incorrecta. Sé que puedo manejar esto usando el interruptor -R al aplicarlo a través del patch, pero sería bueno si hubiera una manera de invertir de forma permanente el archivo de parche. ¿Hay alguna utilidad que pueda hacer esto, o p. una expresión regular que se garantizaría que funcionara?Inversión permanente de un archivo de parche

ACTUALIZACIÓN

Lie Ryan tiene suggested a neat way of doing this. Sin embargo, requiere acceso a los archivos fuente originales. Así que supongo que debería actualizar mi pregunta para indicar que estoy más allá de una forma de lograr esto, dado solo el archivo de parche en sí.

Respuesta

44

Usted puede utilizar la herramienta de interdiff(1)patchutils. En particular, la página del manual de interdiff dice:

Para invertir un parche, utilice/dev/null para dif2.

Así,

$ interdiff file.patch /dev/null > reversed.patch 
+0

no funciona. Intenté aplicar el parche invertido al archivo parcheado con el parche directo, y falla. Por lo tanto, esto no produce un parche invertido correcto, al menos no para todos los parches. No sé si interdiff está roto o este método es simplemente incorrecto. – matteo

+0

Veo, se supone que * esto funciona de acuerdo con la página man de interdiff, por lo que es un error en interdiff – matteo

14

Probar:

patch -R file.txt file.patch 
diff file.txt.orig file.txt > file.patch.rev 
// you can then `rm file.txt.orig file.patch` 

EDIT:

Para invertir un diff unificado, tiene que cambiar tres cosas:

  • el parche cabecera cabecera
  • el trozo
  • + a - y - a +

Así que aquí es como un encabezado parche para una apariencia como:

--- b.asm 2010-09-24 12:03:43.000000000 +1000  
+++ a.asm 2010-09-24 23:28:43.000000000 +1000 

que necesita para invertir para que se vea así:

--- a.asm 2010-09-24 23:28:43.000000000 +1000 
+++ b.asm 2010-09-24 12:03:43.000000000 +1000  

cambiar básicamente el orden, y el interruptor + ++ a --- y viceversa.

A continuación, el encabezado de la porción:

@@ -29,5 +27,7 @@ 

Es necesario revertir los números, por lo que se vea como esto:

@@ -27,7 +29,5 @@ 

básicamente, cambiar los pares de números

y por último, cambie cada línea que comience con + y cada línea que comience con -.

EDIT:

para cambiar la cabecera trozo, puede hacerlo:

sed -e "s/@@ -\([0-9]\+,[0-9]\+\) +\([0-9]\+,[0-9]\+\) @@/@@ -\2 +\1 @@/" 

para cambiar + a - y - a +, que puede hacer:

sed -e "s/^+/P/" -e "s/^-/+/" -e "s/^P/-/" 

FINALMENTE:

para revertir la cabecera parche, hacer:

head -2 orig.diff | tac | sed -e "s/+++/PPP/" -e "s/---/+++/" -e "s/PPP/---/" > head 
tail orig.diff -n+3 > tail 
cat head tail > headtail 
rm head tail 

Así que, finalmente, nuestro script (rápido y sucio) se parece a:

#!/usr/bin/env sh 
F="$1" 
head -2 $F | tac | sed -e "s/+++/PPP/" -e "s/---/+++/" -e "s/PPP/---/" > $F.head 
tail $F -n+3 | sed -e "s/@@ -\([0-9]\+,[0-9]\+\) +\([0-9]\+,[0-9]\+\) @@/@@ -\2 +\1 @@/" -e "s/^+/P/" -e "s/^-/+/" -e "s/^P/-/" > $F.tail 
cat $F.head $F.tail 
rm $F.head $F.tail 

lo probé, y parece que funciona.

embargo, para hacer las cosas más fácil de mantener, y más limpia:

#!/usr/bin/env sh 
swap() { 
    sed -e "s/^$1/PPP/" -e "s/^$2/$1/" -e "s/^PPP/$2/" 
} 
file_header() { 
    head -2 $1 | tac | swap +++ --- 
} 
fix_chunk_header() { 
    sed -e "s/@@ -\([0-9]\+,[0-9]\+\) +\([0-9]\+,[0-9]\+\) @@/@@ -\2 +\1 @@/" 
} 
fix_lines() { 
    swap + - 
} 
file="$1" 
file_header $file 
tail $file -n+3 | fix_chunk_header | fix_lines 
+0

+1: No había pensado en esto. Pero por interés, ¿hay alguna forma de hacerlo sin acceso a los archivos originales? –

+0

@Oli Charlesworth: el archivo file.txt.orig es una copia de seguridad automática generada por parche cuando lo llama en la primera línea. Simplemente uso esa copia de seguridad para regenerar el parche invertido. –

+0

@Lie Ryan: Lo que quise decir fue, ¿cómo podría hacer esto si solo * tengo el archivo parche? –

0

había aplicado un parche patch -N -p0 < path/file.patch pero empecé enfrentan a problemas de compilación debido al código incompleto todo lo que hice fue correr este comando patch -p0 -R < path/file.patch. Referido esto link