Si invertir un parche tiene éxito, ¿eso significa siempre que el parche se ha aplicado completamente?

9

Esto se aborda en dos preguntas, ' Verificar si un archivo o carpeta ya ha sido parcheado ' y ' Hacer patchregresar 0 al omitir un parche ya aplicado ', sin embargo, ninguno de los dos tuvo una respuesta satisfactoria.

Estoy escribiendo un script y quiero probar lo siguiente para un parche:

Totalmente aplicado: continuar

Parcialmente aplicado: salir

No aplicado: si puede aplicarse con éxito, hágalo y continúe, de lo contrario salga

El problema es manejar el caso parcialmente aplicado:

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

Entonces la barra existe pero foo no existe porque en algún momento fue eliminada. Ahora, si aplico el parche hacia adelante en una ejecución en seco, el código de salida es 1 ya que no se aplicó con éxito.

$ 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

Sin embargo, eso no me dice si el parche está completamente aplicado, solo que falló la ejecución en seco. No sé por qué está marcado como correcto como la respuesta de stackoverflow. Intenté revertir, pero como es un script no interactivo, solo funcionó con fuerza:

$ 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

Entonces, ¿siempre sostiene que si trato de revertir a la fuerza un parche en una ejecución en seco y tiene éxito que el parche se aplique completamente, y si falla, no se aplica completamente (o no se aplica)? Porque si es así, puedo hacer algo como

patch --dry-run --reverse --force -i foobar.patch ||
(patch --dry-run --forward --force -i foobar.patch &&
 patch --forward --force -i foobar.patch) ||
exit 1
Arrendajo
fuente
¿Está bajo su control el código fuente, es decir, puede garantizar que todos los parches siempre se apliquen exactamente una vez?
roaima
1
@roamia bueno, el parche y el script están bajo mi control. solo mi script estaría aplicando el parche.
Jay
Creo que es posible idear un punto de partida y un parche que tenga éxito en ambas direcciones, hacia adelante y hacia atrás.
Jasen

Respuestas:

3

Con esta diferencia:

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

esto pasa:

$ 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

Entonces la respuesta a tu pregunta es no.

aferber
fuente
Gracias por señalar eso. Descubrí que puedo solucionar ese caso usando, --posixya que establecerá un error cuando no haya ningún archivo para parchear. Sin embargo, el uso del modo POSIX no establecerá un error si un archivo a eliminar contiene contenido que difiere del parche. Por ejemplo, si ejecuto ese comando inverso con --posixy el archivo de la barra contiene algunos datos, en el modo POSIX el archivo no se eliminará y no se producirá ningún error. Por lo tanto, mi solución es ejecutarlo con y sin modo posix y si ambos están bien, supongo que el parche se aplicó con éxito. Actualizaré mi pregunta para reflejar esto.
Jay
Parece --posixque no es la cura, todo lo que pensé que era. Si un archivo es eliminado por un parche y lo ejecuto --posix --reverse, se produce un error de que el archivo no existe. Tendré que investigar esto más mañana.
Jay