Jeśli odwrócenie poprawki się powiedzie, czy to zawsze oznacza, że ​​łatka została w pełni zastosowana?

9

Zostało to poruszone w dwóch pytaniach: „ Sprawdź, czy plik lub folder został już załatany ” i „ Zwróć patch0, pomijając już zastosowaną łatkę ”, jednak żadne nie miało satysfakcjonującej odpowiedzi.

Piszę skrypt i chcę przetestować następujące poprawki:

W pełni zastosowane: kontynuuj

Częściowo zastosowane: wyjście

Nie zastosowano: jeśli można go pomyślnie zastosować, zrób to i kontynuuj, w przeciwnym razie zakończ

Problemem jest obsługa częściowo zastosowanego przypadku:

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

Więc pasek istnieje, ale foo nie, ponieważ w pewnym momencie został usunięty. Teraz, jeśli zastosuję łatkę do przodu w suchym biegu, kod wyjścia to 1, ponieważ nie został pomyślnie zastosowany.

$ 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

Nie mówi mi to jednak, czy łatka została w pełni zastosowana, tylko to, że nie powiodła się sucha próba. Nie wiem, dlaczego oznaczono to poprawnie jako odpowiedź na przepełnienie stosu. Próbowałem cofnąć, ale ponieważ jest to skrypt nieinteraktywny, działał tylko z siłą:

$ 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

Czy zatem zawsze utrzymuje się, że jeśli spróbuję siłą odwrócić łatkę w trybie próbnym i uda się, że łatka zostanie w pełni zastosowana, a jeśli zawiedzie, to nie zostanie w pełni zastosowana (lub w ogóle zastosowana)? Bo jeśli tak, to mogę zrobić coś takiego

patch --dry-run --reverse --force -i foobar.patch ||
(patch --dry-run --forward --force -i foobar.patch &&
 patch --forward --force -i foobar.patch) ||
exit 1
Sójka
źródło
Czy kod źródłowy jest pod twoją kontrolą, tzn. Czy możesz zagwarantować, że wszystkie łatki będą zawsze stosowane dokładnie raz?
roaima,
1
@roamia dobrze, łatka i skrypt są pod moją kontrolą. tylko mój skrypt zastosowałby łatkę.
Jay
Myślę, że można stworzyć punkt początkowy i łatkę, która odniosłaby pełny sukces zarówno w kierunku do przodu, jak i do tyłu.
Jasen,

Odpowiedzi:

3

Z tą różnicą:

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

to się stało:

$ 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

Odpowiedź na twoje pytanie brzmi: nie.

Aferber
źródło
Dziękuję za zwrócenie na to uwagi. Zauważyłem, że mogę naprawić ten przypadek, --posixponieważ spowoduje to błąd, gdy nie będzie pliku do załatania. Jednak użycie trybu POSIX nie spowoduje błędu, jeśli plik do usunięcia zawiera treść inną niż łatka. Na przykład, jeśli uruchomię to polecenie odwrotne za pomocą, --posixa plik słupka zawiera pewne dane, wówczas w trybie POSIX plik nie zostanie usunięty i nie wystąpi błąd. Dlatego moja poprawka jest uruchamiana zarówno w trybie posix, jak i bez niego, a jeśli oba są w porządku, zakładam, że łatka została pomyślnie zastosowana. Zaktualizuję moje pytanie, aby to odzwierciedlić.
Jay
Wydaje się, że --posixto nie może być lekarstwo - wszystko, o czym myślałem. Jeśli plik zostanie usunięty przez łatkę, a ja uruchomię, oznacza --posix --reverseto, że plik nie istnieje. Będę musiał przyjrzeć się temu jutro.
Jay