SCROLL
Среднее время на прочтение: 3 мин.

Как создать патч файл и применить патч к файлу в Linux. Использование команд diff и patch.

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

Что такое diff и patch?
  • diff: Утилита командной строки, которая сравнивает два файла построчно и выводит список различий.
  • patch: Утилита командной строки, которая применяет изменения (или исправления) к файлу на основе различий, выявленных с помощью diff.

Рассмотрим как использовать команды diff и patch. В качестве примера у меня будет два файла working/code.txt и latest/code.txt, где в первый продуктивный, а второй будет с изменениями.

Использование diff

Синтаксис использования.

diff [параметры] file1 file2

Сравнение

Обычное сравнение двух файлов.

diff working/code.txt latest/code.txt

2d1
< // The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.
7a7,14
>
> // ACCESS_ALLOWED_ACE structure (winnt.h)
> // The ACCESS_ALLOWED_ACE structure defines an access control entry (ACE) for the discretionary access control list (DACL) that controls access to an object.
> typedef struct _ACCESS_ALLOWED_ACE {
>   ACE_HEADER  Header;
>   ACCESS_MASK Mask;
>   DWORD       SidStart;
> } ACCESS_ALLOWED_ACE;

Создание контекстного различия сравниваемых файлов, которое предоставляет больше контекста для изменений. Используйте ключ -c в синтаксисе.

diff -c working/code.txt latest/code.txt

*** working/code.txt    2024-11-06 14:50:37.604862349 +0300
--- latest/code.txt     2024-11-06 14:50:49.472862255 +0300
***************
*** 1,7 ****
  // ACL_SIZE_INFORMATION structure (winnt.h)
- // The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.
  typedef struct _ACL_SIZE_INFORMATION {
    DWORD AceCount;
    DWORD AclBytesInUse;
    DWORD AclBytesFree;
  } ACL_SIZE_INFORMATION;
--- 1,14 ----
  // ACL_SIZE_INFORMATION structure (winnt.h)
  typedef struct _ACL_SIZE_INFORMATION {
    DWORD AceCount;
    DWORD AclBytesInUse;
    DWORD AclBytesFree;
  } ACL_SIZE_INFORMATION;
+
+ // ACCESS_ALLOWED_ACE structure (winnt.h)
+ // The ACCESS_ALLOWED_ACE structure defines an access control entry (ACE) for the discretionary access control list (DACL) that controls access to an object.
+ typedef struct _ACCESS_ALLOWED_ACE {
+   ACE_HEADER  Header;
+   ACCESS_MASK Mask;
+   DWORD       SidStart;
+ } ACCESS_ALLOWED_ACE;

Создание унифицированного diff, который будет более компактным и удобным для чтения. Используйте ключ -u в синтаксисе.

diff -u working/code.txt latest/code.txt

--- code.txt    2024-05-22 14:11:06.596389563 +0300
+++ code_modified.txt   2024-05-22 14:12:36.161050485 +0300
@@ -1,7 +1,14 @@
 // ACL_SIZE_INFORMATION structure (winnt.h)
-// The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.
 typedef struct _ACL_SIZE_INFORMATION {
   DWORD AceCount;
   DWORD AclBytesInUse;
   DWORD AclBytesFree;
 } ACL_SIZE_INFORMATION;
+
+// ACCESS_ALLOWED_ACE structure (winnt.h)
+// The ACCESS_ALLOWED_ACE structure defines an access control entry (ACE) for the discretionary access control list (DACL) that controls access to an object.
+typedef struct _ACCESS_ALLOWED_ACE {
+  ACE_HEADER  Header;
+  ACCESS_MASK Mask;
+  DWORD       SidStart;
+} ACCESS_ALLOWED_ACE;

Дополнительные полезные ключи:

  • -i : игнорирование различия в регистре при сравнении.
  • -w : игнорировать различия в пробелах при сравнении.
  • -r : рекурсивное сравнение каталогов.

Создание патч файла

Создание патч файла из сравниваемых файлов.

diff -u working/code.txt latest/code.txt > code.patch

Создание патча для всех файлов в сравниваемых каталогах.

diff -u working/ latest/ > patchfiles.patch
В обоих примерах patch файлы создаются в унифицированном формате diff.

Использование patch

Синтаксис использования.

patch [параметры] target_file < patch_file

Применение патча

Применение патч файла (контекстного или унифицированного diff). Оригинал файл и patch файл, должны находится в одном каталоге.

patch -i patchfile.patch -o updatedfile

Использование ключа -o указывает на то что нужно сохранить пропатченный файл в отдельный файл. вместо изменения целевого файла.

Применение патча к нескольким файлам

Применение патч файла (созданного по этому примеру) к нескольким файлам. Скопируйте оригинальную директорию и патч в какую либо отдельную папку и примените патч командой.

patch -p0 -i patchfiles.patch

Использование ключа -p0 указывает patch как обрабатывать пути к файлам в патче (то есть, какой уровень каталогов игнорировать при применении изменений).

  • -p0 — Означает, что структура каталогов в патче точно совпадает с текущей структурой, или если файлы патча находятся в директориях, где полный путь совпадает с указанным в патче.

Чтобы понять разницу использования других значений -p, рассмотрим на примере структуры каталога вида — working/src/code.txt:

  • -p1 — Пропускает один уровень каталога (например, working/) и ищет src/code.txt в текущей директории.
  • -p2 — Пропускает два уровня каталогов (например, working/src/), поэтому patch будет искать code.txt в текущей директории.

Отмена изменений патча

Применение исправлений в обратном порядке, т.е. отмена изменений. Используйте ключ -R в синтаксисе.

patch -R -i patchfile.patch

Создание резервной копии исходного файла

В процессе применения патча к файлу можно сделать его резервную копию перед изменением, используя параметр -b.

patch -u -b working/code.txt -i code.patch

После применения патча в рабочей папке можно увидеть, что появился файл с именем code.txt.orig.

ls -l working/

total 8
-rw-r--r-- 1 root root 495 May 23 16:09 code.txt
-rw-r--r-- 1 root root 265 May 23 16:00 code.txt.orig

Обсуждение

0 комментариев

Нет комментариев.