Если изменение патча прошло успешно, значит ли это, что патч был полностью применен?

9

Этот вопрос затрагивается в двух вопросах: « Проверьте, был ли файл или папка уже исправлены » и « Сделать patchвозврат 0 при пропуске уже примененного исправления », однако ни один из них не дал удовлетворительного ответа.

Я пишу скрипт и хочу проверить следующее:

Полностью применено: продолжить

Частично применен: выход

Не применено: если оно может быть успешно применено, сделайте это и продолжите, иначе выйдите

Проблема заключается в обработке частично примененного случая:

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

Так что bar существует, но foo нет, потому что в какой-то момент он был удален. Теперь, если я применяю патч вперёд при пробном запуске, код выхода равен 1, так как он не был успешно применён.

$ 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

Это не говорит мне, был ли патч полностью применен, просто он провалил пробный запуск. Я не знаю, почему это помечено как ответ на стекопоток. Я попытался повернуть вспять, но так как это неинтерактивный скрипт, он работал только с силой:

$ 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

Так всегда ли считается, что, если я пытаюсь принудительно отменить патч в пробном режиме, и это успешно, что патч полностью применен, и если он терпит неудачу, он не применяется полностью (или применяется вообще)? Потому что если так, то я могу сделать что-то вроде

patch --dry-run --reverse --force -i foobar.patch ||
(patch --dry-run --forward --force -i foobar.patch &&
 patch --forward --force -i foobar.patch) ||
exit 1
сойка
источник
Является ли исходный код под вашим контролем, т.е. можете ли вы гарантировать, что все патчи будут всегда применяться ровно один раз?
Ройма
1
@roamia хорошо, патч и скрипт находятся под моим контролем. только мой сценарий будет применять патч.
Джей
Я думаю, что возможно создать начальную точку и патч, который будет полностью успешным как в прямом, так и в обратном направлении.
Jasen

Ответы:

3

С этим 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

Это случилось:

$ 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

Так что ответ на ваш вопрос - нет.

aferber
источник
Спасибо за указание на это. Я обнаружил, что могу исправить этот случай, используя, --posixтак как он установит ошибку, когда нет файла для исправления. Однако использование режима POSIX не приведет к ошибке, если удаляемый файл содержит содержимое, отличное от патча. Например, если я запускаю эту команду реверса с помощью, --posixа файл bar содержит некоторые данные, то в режиме POSIX файл не будет удален и ошибки не возникнет. Поэтому мое исправление - запустить его как в режиме posix, так и без него, и если оба в порядке, то я предполагаю, что исправление было успешно применено. Я обновлю свой вопрос, чтобы отразить это.
Джей
Похоже, --posixне может быть панацеей - все, что я думал, это было. Если файл удаляется патчем, и я запускаю --posix --reverseего, появляется ошибка, что файл не существует. Завтра я должен разобраться в этом подробнее.
Джей