Інструмент Linux patch дозволяє швидко та надійно переносити зміни між різними наборами файлів. Давайте розглянемо, як просто користуватися патчем.
Взаємодія команд patch і diff
Уявіть собі, що ви маєте текстовий документ на своєму комп’ютері. Вам надходить оновлена версія цього файлу від іншої особи. Яким чином можна оперативно перенести всі зміни з модифікованого документа до початкового? Саме тут у гру вступають patch і diff. Ці інструменти доступні в Linux та інших операційних системах, що базуються на Unix, таких як macOS.
Команда diff проводить аналіз двох різних редакцій документа та виявляє відмінності між ними. Виявлені різниці можна зберегти у файлі, відомому як файл виправлення (patch file).
Команда patch здатна обробляти файл виправлення, використовуючи його вміст як інструкції. Виконуючи ці інструкції, вона відтворює модифікації, внесені до зміненого файлу, в оригінальному документі.
А тепер уявіть собі, що аналогічний процес відбувається з цілою папкою текстових файлів – і все це за один прийом. Саме в цьому полягає потужність патча.
Іноді вам не надсилають оновлені файли, а тільки файл виправлення. Навіщо пересилати багато файлів, коли можна передати один файл або розмістити його для зручного скачування?
Як використовувати файл виправлення для оновлення ваших файлів? Це гарне питання, і ми розкриємо його у цій статті.
Хоча команда patch найчастіше застосовується розробниками програмного забезпечення, вона так само ефективна для будь-яких наборів текстових файлів, незалежно від їхнього призначення – чи то вихідний код, чи будь-що інше.
Наш практичний сценарій
У нашому прикладі ми знаходимося в директорії “work”, яка містить ще дві папки: “working” та “latest”. Папка “working” містить набір файлів вихідного коду, а “latest” – їхню найсвіжішу версію, де деякі файли були змінені.
Для безпеки, папка “working” є копією поточної версії текстових файлів, і це не єдина їхня копія.
Виявлення відмінностей між двома версіями файлу
Команда diff виявляє розбіжності між двома файлами, відображаючи змінені рядки в терміналі.
Один з файлів має назву “sleng.c”. Ми порівняємо його версію з папки “working” з версією з папки “latest”.
Опція “-u” (уніфікований) змушує diff виводити також кілька незмінених рядків до та після кожного зміненого блоку, так званих “контекстних рядків”. Вони допомагають команді patch точно визначити місця для внесення змін у вихідному файлі.
Ми вказуємо назви файлів, щоб diff розумів, які файли потрібно порівняти. Першим вказується початковий файл, потім – змінений. Ось команда, яку ми вводимо для diff:
diff -u working/slang.c latest/slang.c
diff створює звіт з відмінностями між файлами. Якщо файли ідентичні, звіт буде порожнім. Наявність звіту від diff підтверджує, що між двома версіями є різниця і вихідний файл потребує виправлення.
Створення файлу виправлення
Для збереження цих відмінностей у файлі виправлення, використайте наступну команду. Це та ж сама команда, що і раніше, тільки результат від diff перенаправляється у файл “slang.patch”.
diff -u working/slang.c latest/slang.c > slang.patch
Щоб patch застосував зміни з файлу виправлення до “work/slang.c”, використайте цю команду. Опція “-u” (уніфікований) повідомляє patch, що файл виправлення містить уніфіковані контекстні рядки. Іншими словами, ми використали “-u” з diff, тому використовуємо “-u” з patch.
patch -u working.slang.c -i slang.patch
У разі успіху ви побачите повідомлення про те, що файл був виправлений.
Створення резервної копії оригінального файлу
Ми можемо налаштувати patch на створення резервної копії виправлених файлів перед їх зміною за допомогою опції “-b” (резервне копіювання). Опція “-i” (вхід) вказує назву файлу виправлення.
patch -u -b working.slang.c -i slang.patch
Файл буде виправлено, як і раніше, без змін у результаті. Проте, якщо ви подивитеся в папку “working”, то побачите файл “slang.c.orig”, створений як резервна копія. Мітка часу показує, що “slang.c.orig” є оригіналом, а “slang.c” – новим файлом після виправлення.
Застосування diff до папок
Ми можемо скористатися diff для створення файлу виправлення, який містить усі відмінності між файлами у двох папках. Потім ми можемо використати цей файл з patch, щоб застосувати всі зміни до файлів у папці “working” однією командою.
Опції, які ми застосуємо з diff, це “-u” (уніфікований контекст), який ми використовували раніше, “-r” (рекурсивний), щоб diff сканував усі підпапки, та “-N” (новий файл).
Опція “-N” вказує diff, як обробляти файли в папці “latest”, яких немає в папці “working”. Це змушує diff вносити до файлу виправлення інструкції для patch, щоб він створював файли з “latest”, яких немає в “working”.
Ви можете об’єднати опції разом, використовуючи один дефіс “-“.
Зверніть увагу, що ми вказуємо лише назви папок, а не конкретні файли:
diff -ruN working/ latest/ > slang.patch
Огляд файлу виправлення
Подивимось на вміст файлу виправлення за допомогою less.
На початку файлу показані відмінності між двома версіями “slang.c”.
Прокручуючи файл далі, ми бачимо, що він описує зміни у іншому файлі “structs.h”. Це підтверджує, що файл виправлення дійсно містить відмінності між різними версіями кількох файлів.
Перевірка перед застосуванням
Виправлення великої кількості файлів може викликати занепокоєння, тому ми скористаємося опцією “–dry-run”, щоб переконатися, що все гаразд, перед тим, як застосовувати зміни.
Опція “–dry-run” змушує patch виконувати всі дії, крім фактичної зміни файлів. Patch проводить перевірку файлів, і у випадку проблем – повідомляє про них. У будь-якому разі, файли не змінюються.
Якщо проблем немає, ми можемо повторити команду без опції “–dry-run” та спокійно виправляти файли.
Опція “-d” (папка) вказує patch, з якою папкою працювати.
Зверніть увагу, що ми не використовуємо опцію “-i” (введення), щоб повідомити patch, який файл виправлення містить інструкції від diff. Натомість ми перенаправляємо файл виправлення в patch за допомогою “<“.
patch --dry-run -ruN -d working < slang.patch
З усієї папки diff знайшов два файли для виправлення. Інструкції щодо модифікацій цих файлів були перевірені patch, і жодних проблем не виявлено.
Попередня перевірка пройшла успішно, ми готові до дії.
Виправлення папки
Щоб реально застосувати виправлення до файлів, використаємо попередню команду, але без опції “–dry-run”.
patch -ruN -d working < slang.patch
Цього разу кожен рядок виводу починається не з “checking”, а з “patching”.
І жодних проблем не виявлено. Ми можемо скомпілювати наш вихідний код і отримати останню версію програмного забезпечення.
Згладжування відмінностей
Це найпростіший і безпечний спосіб використання patch. Скопіюйте цільові файли до папки і виправте її. Скопіюйте їх назад, коли переконаєтесь, що процес виправлення завершився без помилок.