Проверьте, был ли файл или папка уже пропатчен

22

Можно ли узнать, был ли файл уже исправлен, прежде чем применять исправление?

Мне нужно сделать это в сценарии, какие-нибудь мысли?

маргаритка
источник
1
Какую программу вы используете для их исправления? Какие патчи?
Всезнающий

Ответы:

20

Да, просто запустите patchс --dry-runпараметром, он либо потерпит неудачу, либо преуспеет, что можно узнать по состоянию выхода.

Но в более распространенном (и подверженном ошибкам) ​​способе вам, вероятно, придется запускать его с -Rопцией, которая означает «обратный», поскольку только в том случае, если он способен отменить весь патч, его можно рассматривать как «примененный». В противном случае (без '-R') он может потерпеть неудачу только из-за того, что некоторые части исходного файла были изменены. Ниже приведен простой пример:

if ! patch -R -p0 -s -f --dry-run <patchfile; then
  patch -p0 <patchfile
fi

(Более того, в приведенном выше фрагменте вы можете даже предпочесть patchполностью замолчать, перенаправив его stdout и stderr на /dev/null)

poige
источник
1
Это не работает для меня. Когда я запускаю эту команду, если патч не был применен, он спрашивает, «отменять ли» патч в интерактивном режиме, и, если я использую пакетный режим, он игнорирует обратную операцию и применяет патч, возвращая 0.
синак
1
Эй, попробуйте добавить -sfк patch(можно записать в виде patch -Rsfp0 --dry-run)
poige
1
@Synack все прошло хорошо?
Пой
16

На всякий случай, если кому-то это поможет, если вы используете bash-скрипт, пример, приведенный Omnifarious, не сработает. В bash статус выхода успешной команды равен 0

Таким образом, будет работать следующее:

patch -p0 -N --dry-run --silent < patchfile 2>/dev/null
#If the patch has not been applied then the $? which is the exit status 
#for last command would have a success status code = 0
if [ $? -eq 0 ];
then
    #apply the patch
    patch -p0 -N < patchfile
fi
DivKis01
источник
Проверка должна быть против 1вместо 0:if [ $? -eq 1 ]
Crisson
2
Нет, 0 верно. Патч будет выходить с ненулевым значением, если пробный прогон по какой-то причине не удался, и в этом случае патч не должен применяться.
Fls'Zen
Мой скрипт был правильным в bash. bash считает код выхода 0 trueдля целей if. Именно потому, что большинство команд используют код выхода 0, чтобы обозначить успех.
Всевышний
2

Вот предположение, предполагающее, что вы используете patchутилиту, и у каждого файла, который должен быть исправлен, есть собственный патч:

if patch <options> -N --dry-run --silent <patchfile 2>/dev/null; then
    echo The file has not had the patch applied,
    echo and the patch will apply cleanly.
else
    echo The file may not have had the patch applied.
    echo Or maybe the patch doesn't apply to the file.
fi
всевозможный
источник
Или, если вы исправили файлы ранее и хотите узнать, коснулся ли он какого-то определенного файла, вы можете запустить первый цикл исправлений с -Bпараметром, который приведет к созданию резервной копии. Затем вы проверяете наличие резервной копии.
Петер
8
Не могли бы вы немного рассказать, почему вы решили использовать nohupв этом ifслучае?
Зрайм
@zrajm - я не могу вспомнить, почему я это сделал. И к тому времени, когда я заметил (из-за запроса на редактирование), что это было там, это было так давно, что у меня никогда не было шансов найти причину. Мне кажется, что сейчас смотреть на это совершенно бессмысленно.
Всевышний
0

В моем случае я хотел сделать эту проверку, чтобы выполнение команды patch не заканчивалось интерактивным терминалом, спрашивающим, что делать (особенно для CI).

Оказывается, что если вам нужно только это, вы также можете использовать --forwardаргумент, и он пропустит патч, если он уже был применен!

maxime1992
источник
0

Это сработало для меня.

"scripts": {
    "symfony-scripts": [
        "patch -N --silent -p0 < patches/vendor/somefile.js.patch &2>/dev/null",
        "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
neisantos
источник