Se l'inversione di una patch ha esito positivo, significa sempre che la patch è stata completamente applicata?


9

Questo è toccato a due domande, ' Controllare se un file o una cartella è stata già patchato ' e ' make patchritorno 0 quando saltare una patch già applicato ' tuttavia non ha avuto una risposta soddisfacente.

Sto scrivendo uno script e voglio testare quanto segue per una patch:

Completamente applicato: continua

Parzialmente applicato: uscita

Non applicato: se può essere applicato correttamente fallo e continua, altrimenti esci

Il problema sta gestendo il caso parzialmente applicato:

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

Quindi la barra esiste ma il foo no perché ad un certo punto è stata rimossa. Ora, se applico la patch in avanti a secco, il codice di uscita è 1 poiché non viene applicato correttamente.

$ 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

Ciò non mi dice se la patch sia stata completamente applicata, solo che non ha funzionato correttamente. Non so perché sia ​​contrassegnato come corretto come risposta allo stackoverflow. Ho provato a invertire ma poiché è uno script non interattivo ha funzionato solo con forza:

$ 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

Quindi sostiene sempre che se provo a invertire forzatamente una patch in un ciclo a secco e riesce che la patch sia completamente applicata, e se fallisce non è completamente applicata (o applicata)? Perché se è così allora posso fare qualcosa del genere

patch --dry-run --reverse --force -i foobar.patch ||
(patch --dry-run --forward --force -i foobar.patch &&
 patch --forward --force -i foobar.patch) ||
exit 1

Il codice sorgente è sotto il tuo controllo, ovvero puoi garantire che tutte le patch si applicheranno sempre esattamente una volta?
roaima,

1
@roamia bene la patch e lo script sono sotto il mio controllo. solo la mia sceneggiatura avrebbe applicato la patch.
Jay,

Penso che sia possibile escogitare un punto di partenza e una patch che riuscirebbero completamente in entrambe le direzioni avanti e indietro.
Jasen,

Risposte:


3

Con questo 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

questo succede:

$ 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

Quindi la risposta alla tua domanda è no.


Grazie per averlo sottolineato. Ho scoperto che posso risolvere il caso usando, --posixpoiché imposterà un errore quando non ci sono file da patchare. Tuttavia, l'utilizzo della modalità POSIX non imposterà un errore se un file da eliminare contiene contenuto diverso dalla patch. Ad esempio, se eseguo quel comando inverso con --posixe il file bar contiene alcuni dati, in modalità POSIX il file non verrà eliminato e non si verificherà alcun errore. Pertanto la mia correzione è eseguita sia con che senza la modalità posix e se entrambi sono ok, presumo che la patch sia stata applicata con successo. Aggiornerò la mia domanda per riflettere questo.
Jay,

Sembra che --posixpotrebbe non essere la cura-tutto ciò che pensavo fosse. Se un file viene eliminato da una patch ed eseguo, --posix --reverseallora si verifica un errore che il file non esiste. Dovrò approfondire questo domani.
Jay,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.