patch (Unix)

Эта статья находится на начальном уровне проработки, в одной из её версий выборочно используется текст из источника, распространяемого под свободной лицензией
Материал из энциклопедии Руниверсалис

patch
Разработчик Andreas Gruenbacher, Jim Meyering
Операционная система Кроссплатформенное программное обеспечение
Лицензия GPL
Сайт savannah.gnu.org/project…

patch — программная утилита Unix, предназначенная для переноса правок (изменений) между разными версиями текстовых файлов. Информация о правке обычно содержится в отдельном файле, называемом «заплаткой», «правкой» или «файлом правки» («патч-файле» — англ. patch file). Подобный файл, как правило, создается с помощью другой утилиты Unix — diff, позволяющей автоматически извлечь информацию о различиях в тексте файлов.

История

Оригинальная версия программы patch была написана будущим автором Perl Larry Wall (posted to mod.sources) . Сегодня программа patch является частью GNU-проекта и поддерживается FSF.

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

В то время как исходным предназначением программы был перенос различий между версиями файлов программ (так, что программист, внесший в свою программу полезные изменения, мог поделиться этими изменениями с другими программистами, использующими предыдущие версии кода), patch может использоваться для переноса различий между любыми двумя текстовыми файлами, включая, но не ограничиваясь, программную документацию, html-файлы и так далее.

«Файлы правок», или «патчи», или, неформально, «заплатки», используемые утилитой patch («patch files», «patches»), являются текстовыми файлами специального формата. В отличие от них, существуют также бинарные файлы сходного назначения, однако последние, как правило, не имеют ничего общего с утилитой patch и связаны с задачами внесения изменений в бинарные (нетекстовые) файлы, в том числе — исполняемые файлы программ.

Содержимое файлов-патчей

Файлы являющиеся результатом работы diff имеют определенный формат, удобный, в том числе, для чтения и внесения правок «вручную» самим пользователем.

Пример содержимого такого файла:

--- a/path/to/file	2021-01-26 22:55:55.288371691 +0300
+++ b/path/to/file	2021-01-26 22:58:31.790414616 +0300
@@ -1,5 +1,8 @@
+#include <stdio.h>
+
 int
-main(void)
+main(int argc, char** argv)
 {
+	printf("%s: Example `diff` usage;\n", __FILE__);
 	return 0;
 }

На строке начинающейся с тройного знака «минус» (в простейшем случае первая строка) указан относительный путь к оригинальному файлу и время последних изменений. Затем на следующей строке после тройного знака «плюс» указан относительный путь и время последних изменений финальной версии файла, используемой для создания патча.

Далее, на строке начинающейся и заканчивающейся двойным символом «@» после знака «минус» указан номер строки начала приведенного участка текста и количество строк, которое этот участок занимал в старой версии файла, а после знака «плюс» аналогичные характеристики участка в новом файле. Ниже приводится сам участок, где вначале каждой строки добавлен пробел, если строка не менялась, «минус» если она отсутствует в новом файле, и, соответственно, «плюс» если эта строка была добавлена. В приведенном выше примере файла присутствует только один такой сегмент, однако их может быть любое количество. Кроме того, патч может содержать сведения об изменениях внесенных в другие файлы, если команда diff применялась к директории.

Очень часто создание патчей происходит в контексте использования какой-либо системы контроля версий. Если файл изменений создавался средствами одной из них, например git, то формат принципиально отличаться не будет, в нем просто может оказаться дополнительная, избыточная для утилиты patch, информация.

Пример использования

Для создания патча, или файла правки, с помощью утилиты diff, выполните в командной строке:

  $ diff -u старый_файл новый_файл > разница.diff
  # ключ -u указывает программе diff выдавать разницу в так называемом "стандартном" ("унифицированном") формате

Чтобы применить полученный патч, выполните следующую команду:

 $ patch < разница.diff

Выполнение последней команды перенесёт разницу из нового файла в старый, обновив старый файл. (Если старый файл не будет найден по заданному пути, программа выдаст ошибку.)

Патч можно «откатить», то есть отменить, передав программе patch ключ -R:

 $ patch -R < разница.diff

Как правило, утилита patch способна правильно обновить файл и в том случае, когда он несколько изменился (например, был отредактирован в области, не перекрывающейся с областью применения текущей «заплатки»).

Для этого утилита patch использует «контекст» — несколько строчек, соседних с областью применения патча, хранящихся в файле правки наряду с другой информацией о замене.

Однако в случае существенного расхождения файла, к которому применяется («накладывается») патч, и исходного файла, использовавшегося при создании патча, корректность применения патча, вообще говоря, не гарантируется.

Портирование (перенос на другие платформы)

Созданная для применения на Unix-системах, утилита patch была впоследствии перенесена на платформу Windows и некоторые другие. Версии patch для Windows можно найти в пакетах GnuWin32 и UnxUtils[англ.], а также в среде Cygwin.

См. также

  • quilt
  • rsync
  • IEBUPDTE — аналог программы patch, созданный примерно на 20 лет раньше (предположительно в 1964 году для мейнфреймов System 360).

Примечания

Ссылки

  • patch(1): применение файла различий (diff) к оригиналу — страница справки man по пользовательским командам GNU/Linux  (англ.)
  • Patchutils — Дополнительные программы для работы с патчами
  • GNU tools for Win32 — Win32-порт утилит GNU, включая diff и patch
  • diffstat — выдача статистики на основе вывода утилиты diff