Si revertir un parche tiene éxito, ¿eso siempre significa que el parche se ha aplicado por completo?

Esto se aborda en dos preguntas, ' Comprobar si un file o carpeta ya se ha parcheado ' y ' Hacer patch retorno 0 al omitir un parche ya aplicado ', pero ninguno tuvo una respuesta satisfactoria.

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

Totalmente aplicado: continuar

Parcialmente aplicado: salida

No aplicado: si se puede aplicar 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 barra existe pero foo no porque en algún punto fue eliminada. Ahora si aplico el parche 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 ignonetworking $ echo $? 1 

Sin embargo, eso no me dice si el parche está completamente aplicado, solo que falló el funcionamiento en seco. No sé por qué se marcó correctamente como la respuesta de stackoverflow. Traté de invertir, pero como es un guión no interactivo, solo funcionaba 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 mantiene que si trato de invertir un parche a la fuerza en una ejecución en seco y se logra que el parche se aplique por completo, y si falla, no se aplica por completo (o se aplica en absoluto)? Porque si es así, entonces 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 

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.