Сравнение и объединение файлов diff, diff3, sdiff, cmp, patch : Объединение с помощью 'patch'

Вперед Назад Содержание

10. Объединение с помощью 'patch'

'patch' применяет результаты сравнения произведенные 'diff' к копии оригинального файла, для производства измененной версии. С помощью 'patch', можно распространять только изменения внесенные в набор файлов, а не весь этот набор; Ваши корреспонденты могут применить 'patch' для приведения в соответствие своих копий с Вашими изменениями. 'patch' автоматически определяет формат, в котором находятся изменения, пропускает начальные и встроенные заголовки, определяя по ним какой файл изменять. Это позволяет Вашим корреспондентам загружать список различий непосредственно в 'patch'.

'patch' обнаруживает и сообщает об общих проблемах, таких как опережающие изменения. Он сохраняет исходную версию обрабатываемых файлов, а также все списки различий, которые не удалось применить. Он также может создавать файл 'patchlevel.h' для обеспечения применения списков различий в правильном порядке.

Программе 'patch' для обработки может быть задана серия списков различий в их стандартной форме, обычно разделенных заголовками, указывающими какой файл следует изменять. Он применяет ханки 'diff' (см. "Ханки") последовательно, один за другим. Если ханк не совсем подходит к оригинальному файлу, 'patch' использует эвристический метод, пытаясь изменить файл так, как сможет. Если не найдено даже приблизительного соответствия, 'patch' отвергает ханк и переходит к следующему. Обычно 'patch' заменяет каждый файл F на его новую версию, сохраняя оригинальный файл в 'F.orig' и помещая отвергнутые ханки (если такие есть) в 'F.rej'.

10.1 Задание входного формата для 'patch'

Обычно 'patch' определяет в каком 'diff'-формате находятся списки различий, анализируя их содержание. Для списков различий, содержащих особенно запутанные заголовки, может оказаться необходимым использовать одну из следующих опций, заставляющих 'patch' воспринимать файлы списков различий как созданные в определенном формате 'diff'. Только перечисленные здесь форматы вывода 'diff' воспринимаются 'patch'.

`-c' или `--context'

контекстный формат.

`-e' или `--ed'

скрипт для редактора 'ed'.

`-n' или `--normal'

нормальный формат.

`-u'или `--unified'

унифицированный формат.

10.2 Применение несовершенных списков различий

'patch' пытается пропускать любой заголовок в списке различий, принимая его, также как и любой вводный текст. Таким образом, можно загружать непосредственно в 'patch' даже сообщение пришедшее по электронной почте, и тем не менее он будет работать. Если весь список различий имеет отступ на некоторое одинаковое число символов пробела или табуляции 'patch' автоматически игнорирует этот отступ.

Однако, могут существовать другие виды несовершенства ввода, требующие вмешательства пользователя.

Применение списков различий с изменениями в "пропусках"

Иногда программы обработки почты, редакторы или другие программы заменяют пробелы на табуляцию и наоборот. Если это произойдет с файлом, содержащим список различий или со входным файлом, файлы могут выглядеть так же, но 'patch' не сможет работать с ними правильно. При возникновении этой проблемы используйте опцию '-l' или '--ignore-white-space', заставляющая 'patch' не замечать различий в "пропусках", так что любая последовательность "пропусков" в файле списков различий будет соответствовать любой последовательности "пропусков" во входном файле. Остальные символы должны при этом точно соответствовать. Каждая строка строка контекста должна соответствовать строке во входном файле.

Применение реверсивных списков различий

Иногда люди запускают 'diff' с новым файлом на первом месте вместо второго. Это создает "реверсивный" список различий. Чтобы применить такой список различий, необходимо задать опцию '-R' или '--reverse'. В этом случае 'patch' пытается перевернуть каждый ханк перед тем как его использовать. Отказы производятся в перевернутом формате. Опция '-R' не работает со скриптами 'ed', потому что в них содержится слишком мало информации для реконструкции обратной операции.

Часто 'patch' может самостоятельно определить, что список различий реверсивный. Если первый ханк списка не работает, 'patch' переворачивает ханк, проверяя нельзя ли применить его таким образом. Если да, 'patch' спрашивает нужно ли установить опцию '-R'; если нет, 'patch' продолжает применять список различий как обычно. Этот метод не позволяет определить реверсивный список различий, если он находится в нормальном формате и первая команда, которую необходимо применить (имеется в виду команда удаления), такова, что ее применение всегда возможно, так как отсутствующий контекст всегда совпадает. Но большинство списков различий скорее добавляют или изменяют строки, а не удаляют их, так что большинство реверсивных списков различий в нормальном формате начинается с удаления, которое не удается применить, что замечает 'patch'.

Если применить список различий, который уже применялся, 'patch' посчитает, что это реверсивный список и запрашивает о его реверсивном применении. Это можно рассматривать как дополнительную возможность. Если вы сделали это по ошибке и не хотите применять список различий реверсивно, ответьте 'n' на этот запрос и на последующий "apply anyway" ("Все равно применить") или наберите 'C-c' для прерывания процесса 'patch'.

Помощь 'patch' в поиске неточных соответствий

Для контекстного формата, и для маленьких списков различий в нормальном формате, 'patch' может определить неправильность указанных в списке различий номеров строк, и попытаться найти правильное место для применения каждого ханка списка. Сначала он пытается работать с номерами строк, указанными в ханке, со смещением, используемым в предыдущем ханке. Если это не срабатывает, 'patch' проверяет текст вперед и назад, ища набор строк соответствующих контексту, указанному в ханке.

Сначала 'patch' пытается найти место полного совпадения строк контекста. Если такого места не найдено, обрабытвается контекстный или унифицированный формат, а показатель максимальной неточности установлен в 1 или более, 'patch' совершает еще один поиск, игнорируя первую и последнюю строки контекста. Если это не помогает, а показатель максимальной неточности установлен на 2 или более, он совершает еще один поиск, игнорируя первые две и последние две строки контекста. Процесс будет продолжаться подобным образом, если показатель максимальной неточности будет иметь еще большее значение.

Опция '-F LINES' или '--fuzz=LINES' устанавливает показатель максимальной неточности равным LINES. Эта опция применима только в контекстном или унифицированном формате; она игнорирует до LINES строк в процессе поиска места для применения ханка. Заметьте, что большее значение показателя неточности увеличивает вероятность неправильного применения списка различий. По умолчанию показатель неточности равен 2; он не может быть больше числа строк контекста в списке различий, обычно равного 3.

Если 'patch' не может найти места для применения ханка из 'patch', он записывает его в reject-файл (см. подробнее о названиях reject-файлов: "Отвергнутые ханки".). Запись производится в контекстном формате вне зависимости от того в каком формате они были в списке различий. Если входной список был в нормальном или 'ed' формате, большинство контекста пусто. Номера строк в ханке из reject-файла могут отличаться от номеров в файле списка различий: они показывают примерное место, где, как предполагает 'patch' несработавшие ханки находились скорее в новом файле, чем в старом.

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

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

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

10.3 Удаление пустых файлов

Иногда при сравнении двух каталогов, первый каталог содержит файл, которого нет во втором. Если в 'diff' была задана опция '-N' или '--new-file', будет произведен список различий, в котором не будет содержимого такого файла. По умолчанию, 'patch' сохраняет пустой файл, после применения такого списка различий. Опция 'patch' '-E' или '--remove-empty-files' удаляет пустые выходные файлы после применения списка различий.

10.4 Несколько списков различий в одном файле

Если файл списка различий содержит более одного списка различий, 'patch' пытается применить каждый из них, как если бы они содержались в разных файлах. Т.е. он определяет имена файлов, подлежащих обработке в каждом списке различий, и проверяет заголовок каждого списка различий на имена файлов и требуемый номер изменения. (см. подробнее "Создание списков различий".).

Для второго и последующих списков различий в одном файле, можно задать опции и другое имя оригинального файла, разделяя список их аргументов знаком '+'. Однако, список аргументов для второго и последующего файлов не может задавать новый файл, содержащий списки различий, так как это бессмысленно.

Например, для того, чтобы 'patch' отбросил первые три косые черты из имени первого списка различий в файле, и не делал этого ни для одного из последующих списков, а также использавал файл 'code.c' как входной для первого списка, используйте:

      patch -p3 code.c + -p0 < patchfile   
Опция '-S' или '--skip' игнорирует текущий список различий из файла, но продолжает искать следующий список в файле. Так, чтобы игнорировать первый и третий списки различий в файле, используйте:

      patch -S + + -S + < patch file   

10.5 Сообщения и запросы 'patch'

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

Сообщение 'Hmm...' означает, что 'patch' считывает текст из файла списка различий, пытаясь определить находится ли список различий в этом файле, и если да, то какого вида.

Можно блокировать все сообщения 'patch', которые не являются сообщениями об ошибке, с помощью опции '-s', '--quiet' или '--silent'.

Существует два способа не давать 'patch' запрашивать информацию. Опция '-f' или '--force' предполаает, что Вы знаете, что делаете. Без запросов совершаются следующие действия:

  • не рассматриваются списки различий, несодержащие имен файлов в своих заголовках;
  • файлы списков различий обрабатываются, даже если они имеют неправильную версию для строки 'Prereq:' в списке различий;
  • считается, что списки различий не реверсивны, даже если они так выглядят.
Опция '-t' или '--batch' подобна опции '-f', она не дает запрашивать информацию, но делает немного другие допущения:
  • не рассматриваются списки различий не содержащие имен файлов в своих заголовках (как и для '-f');
  • не рассматриваются файлы списков различий имеющие неправильную версию для строки 'Prereq:' в списке различий;
  • считается, что списки различий реверсивны, если они так выглядят.
'patch' завершает работу с ненулевым кодом завершения, в случае создания любых reject-файлов. При применении набора списков различий по очереди, следует проверять выходной статус, чтобы не применить более поздний список различий к файлу, обработанному неполностью.


Вперед Назад Содержание