Si l'inversion d'un patch réussit, cela signifie-t-il toujours que le patch a été entièrement appliqué?

9

Ceci est abordé dans deux questions, `` Vérifier si un fichier ou un dossier a déjà été corrigé '' et `` Faire patchrevenir 0 en sautant un correctif déjà appliqué '', mais aucune n'a eu de réponse satisfaisante.

J'écris un script et je veux tester ce qui suit pour un correctif:

Entièrement appliqué: continuer

Partiellement appliqué: sortie

Non appliqué: s'il peut être appliqué avec succès, continuez, sinon quittez

Le problème est de gérer le cas partiellement appliqué:

mkdir test && cd test

cat << EOF > foobar.patch
--- /dev/null
+++ foo
@@ -0,0 +1 @@
+foo
--- /dev/null
+++ bar
@@ -0,0 +1 @@
+bar
EOF

patch --forward -i foobar.patch
rm foo

Donc, la barre existe mais foo n'existe pas car à un moment donné, elle a été supprimée. Maintenant, si j'applique le correctif vers l'avant dans un essai à sec, le code de sortie est 1 car il n'est pas appliqué avec succès.

$ patch --dry-run --forward --force -i foobar.patch
checking file foo
The next patch would create the file bar,
which already exists!  Skipping patch.
1 out of 1 hunk ignored
$ echo $?
1

Cela ne me dit pas si le correctif est entièrement appliqué, mais juste qu'il a échoué le test à sec. Je ne sais pas pourquoi cela est indiqué comme la réponse stackoverflow. J'ai essayé d'inverser mais comme il s'agit d'un script non interactif, il ne fonctionnait qu'avec force:

$ patch --dry-run --reverse --force -i foobar.patch
The next patch, when reversed, would delete the file foo,
which does not exist!  Applying it anyway.
checking file foo
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED
checking file bar
$ echo $?
1

Donc, est-ce que je considère toujours que si j'essaie d'inverser de force un patch lors d'un essai à blanc et qu'il réussit à ce que le patch soit entièrement appliqué, et s'il échoue, il n'est pas entièrement appliqué (ou appliqué du tout)? Parce que si c'est le cas, je peux faire quelque chose comme

patch --dry-run --reverse --force -i foobar.patch ||
(patch --dry-run --forward --force -i foobar.patch &&
 patch --forward --force -i foobar.patch) ||
exit 1
Geai
la source
Le code source est-il sous votre contrôle, c'est-à-dire pouvez-vous garantir que tous les correctifs s'appliqueront toujours exactement une fois?
roaima
1
@roamia bien le patch et le script sont sous mon contrôle. seul mon script appliquerait le patch.
Jay
Je pense qu'il est possible de créer un point de départ et un patch qui réussiraient pleinement dans les directions avant et arrière.
Jasen

Réponses:

3

Avec ce diff:

diff --git a/bar b/bar
new file mode 100644
index 0000000..e69de29
diff --git a/foo b/foo
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo

ça arrive:

$ cd /tmp/test
$ patch --forward -i foobar.patch
patching file bar
patching file foo
$ echo $?
0
$ rm bar
$ patch --dry-run --reverse --force -i foobar.patch
The next patch, when reversed, would delete the file bar,
which does not exist!  Applying it anyway.
checking file bar
checking file foo
$ echo $?
0

La réponse à votre question est donc non.

aferber
la source
Merci d'avoir fait remarquer cela. J'ai trouvé que je peux résoudre ce cas en utilisant --posixcar cela définira une erreur lorsqu'il n'y a pas de fichier à corriger. Cependant, l'utilisation du mode POSIX ne générera pas d'erreur si un fichier à supprimer contient un contenu différent du correctif. Par exemple, si j'exécute cette commande inverse avec --posixet que le fichier à barres contient des données, alors en mode POSIX, le fichier ne sera pas supprimé et aucune erreur ne se produit. Par conséquent, mon correctif est exécuté à la fois avec et sans mode posix et si les deux sont corrects, je suppose que le correctif a été appliqué avec succès. Je mettrai à jour ma question pour refléter cela.
Jay
Il semble --posixque ce ne soit pas le remède que je pensais. Si un fichier est supprimé par un correctif et que je lance, --posix --reversecela signifie que le fichier n'existe pas. Je vais devoir approfondir cela demain.
Jay