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]$