Inverser définitivement un fichier patch

Parfois, pour une raison quelconque, je dois produire des fichiers de correctifs (sous Linux) qui sont dans la mauvaise direction. Je sais que je peux gérer cela en utilisant le commutateur -R lors de l'application via patch, mais ce serait bien s'il y avait un moyen d'Inverser définitivement le fichier patch. Existe-t-il un utilitaire qui peut le faire, ou par exemple une expression rationnelle qui serait garantie de fonctionner?

Mise à jour

Lie Ryan a suggéré une façon soignée de le faire . Cependant, elle nécessite accès au(X) Fichier (S) source (s) d'origine. Donc, je suppose que je devrais mettre à jour ma question pour indiquer que je suis plus après un moyen d'y parvenir étant donné seulement le fichier patch lui-même.

33
demandé sur Community 2010-10-11 02:00:43

3 réponses

, Vous pouvez utiliser l'outil interdiff(1) à partir de patchutils. En particulier, la page de manuel de interdiff dit:

Pour inverser un patch, utilisez / dev / null pour diff2.

Donc,

$ interdiff file.patch /dev/null > reversed.patch
47
répondu camh 2010-10-10 23:54:13

Essayez:

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

Modifier:

Pour inverser un diff unifié, vous devez changer trois choses:

  • l'en-tête du patch
  • l'en-tête du bloc
  • le + à-et - à +

Voici donc comment un en-tête de patch pour un ressemble:

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

Vous devez l'Inverser pour qu'il ressemble à ceci:

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

Fondamentalement changer l'ordre, et passer + + + à - - - et vice versa.

Ensuite, le morceau en-tête:

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

Vous devez inverser les nombres, donc cela ressemble à ceci:

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

Fondamentalement, changez les paires de nombres

Et enfin, commutez chaque ligne commençant par + et chaque ligne commençant par -.

Modifier:

Pour changer l'en-tête de bloc, vous pouvez faire:

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

Pour passer + et de +, vous pouvez faire:

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

ENFIN:

Pour inverser l'en-tête du patch, procédez comme suit:

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

Donc, enfin, notre (rapide et sale) script ressemble à:

#!/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

Je l'ai testé, et il semble fonctionner.

Cependant, pour rendre les choses plus maintenables et plus propres:

#!/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
14
répondu Lie Ryan 2010-10-10 23:39:13

J'avais appliqué un patch patch -N -p0 < path/file.patch mais j'ai commencé à faire face à des problèmes de compilation en raison d'un code incomplet tout ce que j'ai fait était d'exécuter cette commande patch -p0 -R < path/file.patch . Référencé ce lien

0
répondu tinker_fairy 2015-07-06 10:23:55