Робота з патчами
У світі Linux широко використовується пара програм diff і patch. diff створює файл, в який записуються відмінності між 2 файлами або 2 каталогами (т.зв. патч), а patch дозволяє "накласти" цей патч, тобто маючи патч і один з двох файлів (каталогів), отримати інший. Основне застосування цих програм - створення, поширення і застосування патчів до вихідних текстів програм. Наприклад, я знайшов помилку в якому-небудь програмі і після вивчення її вихідного коду зрозумів, що для виправлення цієї помилки треба додати 2 рядки, а ще в одній поміняти кілька символів. Я хочу повідомити розробнику про це, але яким чином вказати йому на необхідні зміни? Можна це зробити звичайною мовою, але набагато краще (і зручніше для нас обох) зробити патч і вислати його розробнику.
Або інший приклад. Ядро Linux, упаковане в .tar.bz2, важить більше 30 Мб незалежно від його версії. Але файл відмінностей між версіями 2.6.6 і 2.6.7, упакований в .bz2, важить всього 3 Мб, тому для отримання початкових кодів ядра 2.6.7 з початкових кодів ядра 2.6.6 досить завантажити лише 3 Мб, що не викачуючи всі 32 Мб заново.
Втім, часто потрібно просто подивитися відмінності 2 майже однакових файлів, і для цього теж зручно використовувати diff, виводячи результат його роботи не в файл, а прямо на екран.
А тепер подивимося роботу цих утиліт на практиці. Візьміть який-небудь текстовий файл і зробіть його копію, а потім відредагуйте цей копію - 1-2 рядки видаліть, що-небудь додайте, пару рядків просто поміняйте. Потім запустіть diff старий_файл новий_файл. Отримайте файл відмінностей в звичайному форматі. У ньому виводяться тільки змінені рядки, і зміни позначені символами <и> (Які дають зрозуміти, що відповідний рядок належить лівому або правому файлу в командному рядку). Цей формат придатний тільки для вивчення людиною невеликих відмінностей між 2 файлами. Для створення патчів використовуються інші формати виведення, що задаються додатковими опціями, при цьому результат роботи diff перенаправляється в файл патча стандартними засобами оболонки.
Додайте до рядка виклику diff ключ -u. Тепер висновок програми буде являти собою патч в уніфікованому форматі, який використовується в більшості випадків (є ще контекстний формат, що включається ключем -c, але він використовується набагато рідше). У такій патч включаються і кілька сусідніх незмінених рядків (т.зв. контекст), що допомагають програмі patch знайти місце в файлі, де відбулася зміна. Додані в 2-му файлі рядки позначаються плюсами, віддалені - мінусами. Якщо рядок змінилася, вона виводиться 2 рази - старий варіант з мінусом і новий з плюсом. Крім того, на початку додається заголовок, в якому вказуються імена і дати зміни обох файлів.
diff дозволяє отримати відмінності між двома каталогами. Це використовується, як правило, щоб отримати загальний патч до всього дереву початкових кодів програми, якщо було змінено декілька файлів. Для цього використовуються ключі -urN, а замість 2 файлів вказуються імена 2 каталогів (старого і зміненого). При цьому коректно обробляються ситуації з створеними / віддаленими файлами (файл, відсутній в одному з каталогів, вважається існуючим і порожнім).
Щоб накласти патч, треба перейти в каталог, де знаходиться старий файл / каталог, і виконати команду
При використанні патчів до каталогів зазвичай роблять так: патч створюється, як описано вище (тоді в заголовках патчів до окремих файлів шлях до них буде починатися з імені нового каталогу), а прикладається він всередині змінюваного каталогу. Тоді команда буде виглядати так:
patch -p1 <файл_патча
Тут -p1 означає, що з заголовків патча треба прибрати початковий каталог. Поясню все це на прикладі. У нас є дерево початкових кодів ядра 2.6.0. Це каталог linux-2.6.0, в якому містяться каталоги drivers, arch і т.д. І у нас є патч до версії 2.6.1, в якому містяться такі заголовки:
Бачимо, що при створенні патча старий і новий каталоги називалися a і b відповідно. У нас же каталог називається по-іншому, і patch нічого зробити не зможе. Тому заходимо в каталог linux-2.6.0 і виконуємо вказану вище команду. Тепер заголовки будуть інтерпретуватися як
і патч додасться нормально.