Блог/Работа с patch файлами

Работа с patch файлами в веб-разработке

Автор: Кудашев Сергей

Давно собирался написать про использование patch файлов, да как-то не доходили руки. Продвинутым разработчикам это не так интересно, так как большинство знает, как пользоваться этим инструментом, ну или пользуется другими аналогичными инструментами. Для остальных, возможно, это не так интересно, однако думаю пришло время заполнить этот пробел.

Данный метод работы с кодом пришел из моего далекого прошлого, когда я начинал работать админом *nic систем, где патчинье используется довольно широко. Оно используется для быстрого распространения и накладывания заплаток на различные программы. Благодаря тому, что я постоянно использую данный метод, на сайте уже выложено достаточное количество мелких патчей, которыми я пользуюсь на регулярной основе. Коллекция данных патчей будет пополняться и, возможно, будет создала отдельная страница с ними.

Кто-то может спросить, а зачем вообще использовать патчи, когда можно предложить изменения автору/авторам и, если изменение хорошее, то они его примут. Так вот нет, к сожалению, как показала, моя практика, это не всегда возможно. Некоторые пакеты уже давно заброшены, а внесение изменений в репозиторий может занимать года (на вскидку, чей-то пулл реквест с добавлением отображения вывода примерного потребления памяти в MODx Revolution я вижу не закрытым уже полгода, не меньше). В общем, убедившись, что этим методом пользоваться буду, решил поделиться его использованием со своими читателями.

Патч файл это файл "заплатка", который формируется на основе различий кода между файлами A и B и содержит данные различия в определенном формате. Эти различия можно применить к файлу C, расположенному на другом компьютере, т.е. пропатчить сторонний файл, внеся в него нужные нам изменения без передачи всего файла целиком.

Я пользуюсь классическим набором *nix программ, которые позволяют патчить файлы. На самом деле, получать и накладывать patch файлы можно огромным количеством инструментов, например WinMerge, тот же git, который имеет встроенную diff команду. Поэтому patch файлы это довольно универсальный инструмент. И перед тем, как показать полную цепочку работы, хотел бы остановиться на еще одном моменте.

Благодаря специальных форматам patch файлы можно применять к файлам, даже если они существенно отличаются от исходных. Например, я сделал какие-то изменения в pdoTools, который обновляется с завидной регулярностью. С 99% процентной вероятностью я смогу пропатчить pdoTools своим решением и через год, и через два, так как формат patch файла не привязан строго к строкам изменения кода и допускает их изменение. Таким образом, если файлы компонента не будут переписаны координальным образом или если не будет переписаны строки кода, которые подлежат замене, файлы будут успешно патчиться. Но это рождает и обратную проблему, так как при существенном изменении кода патч файлы могут нарушать работу программы, хотя и успешно применяться. Поэтому после каждого применения патча надо проверять сайт на корректную работу и делать бэкап перед использованием данного инструмента.

Рассмотрим простой пример доработки TinyMCE под работу с адаптивными изображениями. Устанавливаем TinyMCE, переходим в папку указанную в посте: /assets/components/tinymce/jscripts/tiny_mce/plugins/advimage/js/ и туда же закачиваем patch файл. Для того, чтобы применить патч достаточно выполнить команду patch < file.patch. Это самый просто вариант, но на всякий случай проверим, может ли данный файл быть применен без ошибок и только после этого его применим. Более сложный пример я допишу позже, когда такой мне попадется.

patch --verbose --dry-run < adaptiveImage.patch

, в ответ мы получаем, что изменения могут быть применены без проблем, и что Hunk (блок измененного нами кода) за это время даже не менял расположения. Если же у нас рядом с любым Hunk появится FAILED значит надо разбираться в чем проблема.

checking file image.js
Using Plan A...
Hunk #1 succeeded at 20.
done

Все, можем спокойно патчить, после чего мы получим тот функционал, который и ожидали.

patch -N --verbose image.js < adaptiveImage.patch

, и если что-то пошло не так, то в любой момент мы можем отменить наложенный патч:

patch -R --verbose image.js < adaptiveImage.patch

Как только попадется хороший пример, я дополню этот пост устранением конфликтов и получением собственных patch файлов.

Комментарии (0)