Product SiteDocumentation Site

Глава 11. Модификация сторонних исходников

11.1. Отслеживание изменений
11.2. Patchutils
11.2.1. Combinediff
11.2.2. Interdiff
11.2.3. Rediff
11.3. Патчи при сборке пакетов
При работе со сторонними исходниками нередко необходимо вносить изменения в исходные тексты продукта для, например, его локализации, адаптации к системе или исправления зависимостей. В случае, когда разработчики не принимают изменения в основной код (или передача этих изменений должна быть ограничена некоторым кругом лиц и потому не может быть передана для добавления в основной код), можно локально изменить исходники, однако с обновлением основной версии необходимо будет переносить все изменения.
Для упрощения и отчасти автоматизации переноса изменений можно использовать патчи — сообщения специального формата, в которых описывается набор изменений объектов для их преобразования.
При создании первой версии изменений:
  • исходники непосредственно исправляются под нужды автора / сообщества;
  • исправления оформляются в виде патчей;
  • патч-сет сохраняется;
  • исправленная версия используется или выкладывается в открытый доступ в зависимости от нужд.
При обновлении исходников нужно:
  • применить патчи к новой версии (при этом часть может примениться сразу, а часть — отвалиться из-за изменений);
  • адаптировать оставшиеся патчи для их применимости;
  • сохранить новый патч-сет;
  • снова пользоваться надстройками.
С появлением распределённых систем контроля версий, таких как GIT, роль патч-сетов стали играть отдельные ветки разработки, и коммиты в них; однако diff / patch (или git diff / patch) —  всё ещё более гибкий инструмент, а явное хранение различий в .patch-файлах более наглядно.

11.1. Отслеживание изменений

Рассмотрим, как производится отслеживание изменений в файлах и описание патчей для их преобразования. С помощью потокового редактора sed сделаем три последовательных изменения файла. С помощью флага -i зададим постфикс для имени файла, в котором будет сохранена версия файла до изменения:
@user
[user@VM ~]$ mkdir calend-patches
[user@VM ~]$ cd calend-patches/

[user@VM calend-patches]$ cal -y > calend
[user@VM calend-patches]$ cat calend
                              2025

      Январь                 Февраль                 Март
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2                   1  2
6  7  8  9 10 11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
13 14 15 16 17 18 19   10 11 12 13 14 15 16   10 11 12 13 14 15 16
20 21 22 23 24 25 26   17 18 19 20 21 22 23   17 18 19 20 21 22 23
27 28 29 30 31         24 25 26 27 28         24 25 26 27 28 29 30
                                             31
      Апрель                   Май                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6             1  2  3  4                      1
7  8  9 10 11 12 13    5  6  7  8  9 10 11    2  3  4  5  6  7  8
14 15 16 17 18 19 20   12 13 14 15 16 17 18    9 10 11 12 13 14 15
21 22 23 24 25 26 27   19 20 21 22 23 24 25   16 17 18 19 20 21 22
28 29 30               26 27 28 29 30 31      23 24 25 26 27 28 29
                                             30
       Июль                  Август                Сентябрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6                1  2  3    1  2  3  4  5  6  7
7  8  9 10 11 12 13    4  5  6  7  8  9 10    8  9 10 11 12 13 14
14 15 16 17 18 19 20   11 12 13 14 15 16 17   15 16 17 18 19 20 21
21 22 23 24 25 26 27   18 19 20 21 22 23 24   22 23 24 25 26 27 28
28 29 30 31            25 26 27 28 29 30 31   29 30

      Октябрь                Ноябрь                 Декабрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2    1  2  3  4  5  6  7
6  7  8  9 10 11 12    3  4  5  6  7  8  9    8  9 10 11 12 13 14
13 14 15 16 17 18 19   10 11 12 13 14 15 16   15 16 17 18 19 20 21
20 21 22 23 24 25 26   17 18 19 20 21 22 23   22 23 24 25 26 27 28
27 28 29 30 31         24 25 26 27 28 29 30   29 30 31

[user@VM calend-patches]$ sed -i.old1 's/а/@/g' calend
[user@VM calend-patches]$ cat calend
                              2025

      Янв@рь                 Февр@ль                 М@рт
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2                   1  2
6  7  8  9 10 11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
13 14 15 16 17 18 19   10 11 12 13 14 15 16   10 11 12 13 14 15 16
20 21 22 23 24 25 26   17 18 19 20 21 22 23   17 18 19 20 21 22 23
27 28 29 30 31         24 25 26 27 28         24 25 26 27 28 29 30
                                             31
      Апрель                   М@й                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6             1  2  3  4                      1
7  8  9 10 11 12 13    5  6  7  8  9 10 11    2  3  4  5  6  7  8
14 15 16 17 18 19 20   12 13 14 15 16 17 18    9 10 11 12 13 14 15
21 22 23 24 25 26 27   19 20 21 22 23 24 25   16 17 18 19 20 21 22
28 29 30               26 27 28 29 30 31      23 24 25 26 27 28 29
                                             30
       Июль                  Август                Сентябрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6                1  2  3    1  2  3  4  5  6  7
7  8  9 10 11 12 13    4  5  6  7  8  9 10    8  9 10 11 12 13 14
14 15 16 17 18 19 20   11 12 13 14 15 16 17   15 16 17 18 19 20 21
21 22 23 24 25 26 27   18 19 20 21 22 23 24   22 23 24 25 26 27 28
28 29 30 31            25 26 27 28 29 30 31   29 30

      Октябрь                Ноябрь                 Дек@брь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2    1  2  3  4  5  6  7
6  7  8  9 10 11 12    3  4  5  6  7  8  9    8  9 10 11 12 13 14
13 14 15 16 17 18 19   10 11 12 13 14 15 16   15 16 17 18 19 20 21
20 21 22 23 24 25 26   17 18 19 20 21 22 23   22 23 24 25 26 27 28
27 28 29 30 31         24 25 26 27 28 29 30   29 30 31

[user@VM calend-patches]$ sed -i.old2 's/0/ /g' calend
[user@VM calend-patches]$ cat calend
                              2 25

      Янв@рь                 Февр@ль                 М@рт
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2                   1  2
6  7  8  9 1  11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
13 14 15 16 17 18 19   1  11 12 13 14 15 16   1  11 12 13 14 15 16
2  21 22 23 24 25 26   17 18 19 2  21 22 23   17 18 19 2  21 22 23
27 28 29 3  31         24 25 26 27 28         24 25 26 27 28 29 3
                                             31
      Апрель                   М@й                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6             1  2  3  4                      1
7  8  9 1  11 12 13    5  6  7  8  9 1  11    2  3  4  5  6  7  8
14 15 16 17 18 19 2    12 13 14 15 16 17 18    9 1  11 12 13 14 15
21 22 23 24 25 26 27   19 2  21 22 23 24 25   16 17 18 19 2  21 22
28 29 3                26 27 28 29 3  31      23 24 25 26 27 28 29
                                             3
       Июль                  Август                Сентябрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6                1  2  3    1  2  3  4  5  6  7
7  8  9 1  11 12 13    4  5  6  7  8  9 1     8  9 1  11 12 13 14
14 15 16 17 18 19 2    11 12 13 14 15 16 17   15 16 17 18 19 2  21
21 22 23 24 25 26 27   18 19 2  21 22 23 24   22 23 24 25 26 27 28
28 29 3  31            25 26 27 28 29 3  31   29 3

      Октябрь                Ноябрь                 Дек@брь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2    1  2  3  4  5  6  7
6  7  8  9 1  11 12    3  4  5  6  7  8  9    8  9 1  11 12 13 14
13 14 15 16 17 18 19   1  11 12 13 14 15 16   15 16 17 18 19 2  21
2  21 22 23 24 25 26   17 18 19 2  21 22 23   22 23 24 25 26 27 28
27 28 29 3  31         24 25 26 27 28 29 3    29 3  31

[user@VM calend-patches]$ sed -i.old3 's/@/ю/g' calend
[user@VM calend-patches]$ cat calend
                              2 25

      Янвюрь                 Феврюль                 Мюрт
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2                   1  2
6  7  8  9 1  11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
13 14 15 16 17 18 19   1  11 12 13 14 15 16   1  11 12 13 14 15 16
2  21 22 23 24 25 26   17 18 19 2  21 22 23   17 18 19 2  21 22 23
27 28 29 3  31         24 25 26 27 28         24 25 26 27 28 29 3
                                             31
      Апрель                   Мюй                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6             1  2  3  4                      1
7  8  9 1  11 12 13    5  6  7  8  9 1  11    2  3  4  5  6  7  8
14 15 16 17 18 19 2    12 13 14 15 16 17 18    9 1  11 12 13 14 15
21 22 23 24 25 26 27   19 2  21 22 23 24 25   16 17 18 19 2  21 22
28 29 3                26 27 28 29 3  31      23 24 25 26 27 28 29
                                             3
       Июль                  Август                Сентябрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6                1  2  3    1  2  3  4  5  6  7
7  8  9 1  11 12 13    4  5  6  7  8  9 1     8  9 1  11 12 13 14
14 15 16 17 18 19 2    11 12 13 14 15 16 17   15 16 17 18 19 2  21
21 22 23 24 25 26 27   18 19 2  21 22 23 24   22 23 24 25 26 27 28
28 29 3  31            25 26 27 28 29 3  31   29 3

      Октябрь                Ноябрь                 Декюбрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2    1  2  3  4  5  6  7
6  7  8  9 1  11 12    3  4  5  6  7  8  9    8  9 1  11 12 13 14
13 14 15 16 17 18 19   1  11 12 13 14 15 16   15 16 17 18 19 2  21
2  21 22 23 24 25 26   17 18 19 2  21 22 23   22 23 24 25 26 27 28
27 28 29 3  31         24 25 26 27 28 29 3    29 3  31

[user@VM calend-patches]$ ls
calend  calend.old1  calend.old2  calend.old3
[user@VM calend-patches]$
Глазами найти изменения довольно трудно, поэтому воспользуемся утилитой diff. При этом добавим флаг -u, который оформляет найденные различия в виде единого контекстного блока с указанными изменениями (т. н. «unified diff»). Именно такой формат в подавляющем большинстве случаев применяется для описания патчей:
@user
[user@VM calend-patches]$ diff -u calend.old1 calend.old2 > p0.patch
[user@VM calend-patches]$ diff -u calend.old2 calend.old3 > p1.patch
[user@VM calend-patches]$ diff -u calend.old3 calend > p2.patch

[user@VM calend-patches]$ cat p0.patch
--- calend.old1 2025-07-31 15:22:20.207687635 +0300
+++ calend.old2 2025-07-31 15:33:38.576477837 +0300
@@ -1,6 +1,6 @@
                               2025

-       Январь                 Февраль                 Март
+       Янв@рь                 Февр@ль                 М@рт
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
       1  2  3  4  5                   1  2                   1  2
 6  7  8  9 10 11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
@@ -8,7 +8,7 @@
20 21 22 23 24 25 26   17 18 19 20 21 22 23   17 18 19 20 21 22 23
27 28 29 30 31         24 25 26 27 28         24 25 26 27 28 29 30
                                              31
-       Апрель                   Май                   Июнь
+       Апрель                   М@й                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
    1  2  3  4  5  6             1  2  3  4                      1
 7  8  9 10 11 12 13    5  6  7  8  9 10 11    2  3  4  5  6  7  8
@@ -24,7 +24,7 @@
21 22 23 24 25 26 27   18 19 20 21 22 23 24   22 23 24 25 26 27 28
28 29 30 31            25 26 27 28 29 30 31   29 30

-       Октябрь                Ноябрь                 Декабрь
+       Октябрь                Ноябрь                 Дек@брь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
       1  2  3  4  5                   1  2    1  2  3  4  5  6  7
 6  7  8  9 10 11 12    3  4  5  6  7  8  9    8  9 10 11 12 13 14
[user@VM calend-patches]$
С помощью утилиты patch можно применять изменения к файлам для их преобразования:
@user
[user@VM calend-patches]$ cp calend.old1 work-copy
[user@VM calend-patches]$ patch work-copy < p0.patch
patching file work-copy
[user@VM calend-patches]$ diff -u work-copy calend.old2
[user@VM calend-patches]$
Так как патчи накладываются на обновляющуюся версию исходников, возможна ситуация, когда контекст наложения патча изменяется. В зависимости от того, как сильно обновление исходников изменило контекст, рассчитывается некоторый уровень применимости патча, с какого-то уровня патч не применяется:
@user
[user@VM calend-patches]$ cp calend.old2 work-copy

[user@VM calend-patches]$ patch --verbose work-copy < p2.patch
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- calend.old3        2025-07-31 15:34:51.901347072 +0300
|+++ calend     2025-07-31 15:35:51.631240548 +0300
--------------------------
patching file work-copy
Using Plan A...
Hunk #1 succeeded at 1 with fuzz 2.
Hunk #2 succeeded at 8 with fuzz 2.
Hunk #3 succeeded at 24 with fuzz 2.
done
[user@VM calend-patches]$ cat work-copy
                              2025

      Янвюрь                 Феврюль                 Мюрт
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2                   1  2
6  7  8  9 10 11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
13 14 15 16 17 18 19   10 11 12 13 14 15 16   10 11 12 13 14 15 16
20 21 22 23 24 25 26   17 18 19 20 21 22 23   17 18 19 20 21 22 23
27 28 29 30 31         24 25 26 27 28         24 25 26 27 28 29 30
                                             31
      Апрель                   Мюй                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6             1  2  3  4                      1
7  8  9 10 11 12 13    5  6  7  8  9 10 11    2  3  4  5  6  7  8
14 15 16 17 18 19 20   12 13 14 15 16 17 18    9 10 11 12 13 14 15
21 22 23 24 25 26 27   19 20 21 22 23 24 25   16 17 18 19 20 21 22
28 29 30               26 27 28 29 30 31      23 24 25 26 27 28 29
                                             30
       Июль                  Август                Сентябрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
   1  2  3  4  5  6                1  2  3    1  2  3  4  5  6  7
7  8  9 10 11 12 13    4  5  6  7  8  9 10    8  9 10 11 12 13 14
14 15 16 17 18 19 20   11 12 13 14 15 16 17   15 16 17 18 19 20 21
21 22 23 24 25 26 27   18 19 20 21 22 23 24   22 23 24 25 26 27 28
28 29 30 31            25 26 27 28 29 30 31   29 30

      Октябрь                Ноябрь                 Декюбрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
      1  2  3  4  5                   1  2    1  2  3  4  5  6  7
6  7  8  9 10 11 12    3  4  5  6  7  8  9    8  9 10 11 12 13 14
13 14 15 16 17 18 19   10 11 12 13 14 15 16   15 16 17 18 19 20 21
20 21 22 23 24 25 26   17 18 19 20 21 22 23   22 23 24 25 26 27 28
27 28 29 30 31         24 25 26 27 28 29 30   29 30 31

[user@VM calend-patches]$
@user
[user@VM calend-patches]$ cp calend.old2 work-copy
[user@VM calend-patches]$ sed -i "s/0/Q/g" work-copy

[user@VM calend-patches]$ patch --verbose work-copy < p1.patch
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- calend.old2        2025-07-31 15:33:38.576477837 +0300
|+++ calend.old3        2025-07-31 15:34:51.901347072 +0300
--------------------------
patching file work-copy
Using Plan A...
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file work-copy.rej
done
[user@VM calend-patches]$
В случае неприменимости каких-то изменений создаётся .rej-файл для описания неприменённых изменений; эти изменения необходимо вносить руками, после чего имеет смысл обновить исходный патч:
@user
[user@VM calend-patches]$ ls
calend  calend.old1  calend.old2  calend.old3  p0.patch  p1.patch  p2.patch  work-copy  work-copy.orig  work-copy.rej
[user@VM calend-patches]$ cat work-copy.rej
--- calend.old2 2025-07-31 15:33:38.576477837 +0300
+++ calend.old3 2025-07-31 15:34:51.901347072 +0300
@@ -1,34 +1,34 @@
-                               2025
+                               2 25

       Янв@рь                 Февр@ль                 М@рт
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
       1  2  3  4  5                   1  2                   1  2
- 6  7  8  9 10 11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
-13 14 15 16 17 18 19   10 11 12 13 14 15 16   10 11 12 13 14 15 16
-20 21 22 23 24 25 26   17 18 19 20 21 22 23   17 18 19 20 21 22 23
-27 28 29 30 31         24 25 26 27 28         24 25 26 27 28 29 30
+ 6  7  8  9 1  11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
+13 14 15 16 17 18 19   1  11 12 13 14 15 16   1  11 12 13 14 15 16
+2  21 22 23 24 25 26   17 18 19 2  21 22 23   17 18 19 2  21 22 23
+27 28 29 3  31         24 25 26 27 28         24 25 26 27 28 29 3
                                              31
       Апрель                   М@й                   Июнь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
    1  2  3  4  5  6             1  2  3  4                      1
- 7  8  9 10 11 12 13    5  6  7  8  9 10 11    2  3  4  5  6  7  8
-14 15 16 17 18 19 20   12 13 14 15 16 17 18    9 10 11 12 13 14 15
-21 22 23 24 25 26 27   19 20 21 22 23 24 25   16 17 18 19 20 21 22
-28 29 30               26 27 28 29 30 31      23 24 25 26 27 28 29
-                                              30
+ 7  8  9 1  11 12 13    5  6  7  8  9 1  11    2  3  4  5  6  7  8
+14 15 16 17 18 19 2    12 13 14 15 16 17 18    9 1  11 12 13 14 15
+21 22 23 24 25 26 27   19 2  21 22 23 24 25   16 17 18 19 2  21 22
+28 29 3                26 27 28 29 3  31      23 24 25 26 27 28 29
+                                              3
        Июль                  Август                Сентябрь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
    1  2  3  4  5  6                1  2  3    1  2  3  4  5  6  7
- 7  8  9 10 11 12 13    4  5  6  7  8  9 10    8  9 10 11 12 13 14
-14 15 16 17 18 19 20   11 12 13 14 15 16 17   15 16 17 18 19 20 21
-21 22 23 24 25 26 27   18 19 20 21 22 23 24   22 23 24 25 26 27 28
-28 29 30 31            25 26 27 28 29 30 31   29 30
+ 7  8  9 1  11 12 13    4  5  6  7  8  9 1     8  9 1  11 12 13 14
+14 15 16 17 18 19 2    11 12 13 14 15 16 17   15 16 17 18 19 2  21
+21 22 23 24 25 26 27   18 19 2  21 22 23 24   22 23 24 25 26 27 28
+28 29 3  31            25 26 27 28 29 3  31   29 3

       Октябрь                Ноябрь                 Дек@брь
Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс   Пн Вт Ср Чт Пт Сб Вс
       1  2  3  4  5                   1  2    1  2  3  4  5  6  7
- 6  7  8  9 10 11 12    3  4  5  6  7  8  9    8  9 10 11 12 13 14
-13 14 15 16 17 18 19   10 11 12 13 14 15 16   15 16 17 18 19 20 21
-20 21 22 23 24 25 26   17 18 19 20 21 22 23   22 23 24 25 26 27 28
-27 28 29 30 31         24 25 26 27 28 29 30   29 30 31
+ 6  7  8  9 1  11 12    3  4  5  6  7  8  9    8  9 1  11 12 13 14
+13 14 15 16 17 18 19   1  11 12 13 14 15 16   15 16 17 18 19 2  21
+2  21 22 23 24 25 26   17 18 19 2  21 22 23   22 23 24 25 26 27 28
+27 28 29 3  31         24 25 26 27 28 29 3    29 3  31

[user@VM calend-patches]$ diff work-copy.rej p1.patch
[user@VM calend-patches]$