Подтвердить что ты не робот

Как работают diff/patch и насколько они безопасны?

Относительно того, как они работают, мне было интересно работать на низком уровне:

  • Что вызовет конфликт слиянием?
  • Является ли контекст также использованными инструментами для применения патча?
  • Как они влияют на изменения, которые на самом деле не изменяют поведение исходного кода? Например, места определения функции обмена.

Что касается безопасности, правда, скажем, огромное хранилище ядро ​​Linux является свидетельством их безопасности. Но я задаюсь вопросом о следующих моментах:

  • Есть ли какие-либо оговорки/ограничения в отношении инструментов, о которых должен знать пользователь?
  • Было ли доказано, что алгоритмы не порождают неправильных результатов?
  • Если нет, существуют ли реализации/документы, предлагающие интеграционное тестирование, которые, по крайней мере, доказывают, что они ошибочно ошибочны? Что-то вроде содержания этих статей BrianKorver и JamesCoplien.
  • Опять же, репозиторий Linux должен быть достаточно относительно предыдущего пункта, но мне было интересно, что-то более общее. Исходный код, даже если он изменен, сильно не изменится (особенно из-за реализованного алгоритма и ограничений синтаксиса), но может ли безопасность быть обобщена на общие текстовые файлы?

Изменить

Хорошо, я редактирую, так как вопрос нечеткий, и ответы не касаются деталей.

Git/diff/patch детали

Унифицированный формат diff, который по умолчанию использует Git, в основном выводит три вещи: изменение, контекст, связанный с изменением, и номера строк, относящихся к контексту. Каждая из этих вещей может быть или не быть изменена одновременно, поэтому Git в основном имеет дело с 8 возможными случаями.

Например, если строки были добавлены или удалены до контекста, номера строк будут разными; но если контекст и изменения все те же, то diff может использовать сам контекст для выравнивания текстов и применения патча (я не знаю, действительно ли это происходит). Теперь, что будет с другими случаями? Я хотел бы узнать подробности о том, как Git решает применить изменения автоматически и когда он решит выпустить ошибку и разрешить пользователю разрешить конфликт.

Надежность

Я почти уверен, что Git полностью надежный, так как у него есть полная история коммитов и может проходить история. Я бы хотел, чтобы некоторые указатели на академические исследования и ссылки на это, если они существуют.

До сих пор, связанный с этой темой, мы знаем, что Git/diff обрабатывает файлы как общие текстовые файлы и работает в строках. Кроме того, алгоритм LCS, используемый diff, будет генерировать патч, пытающийся свести к минимуму количество изменений.

Итак, вот некоторые вещи, которые я хотел бы также знать:

  • Почему LCS используется вместо других строковых алгоритмов?
  • Если используется LCS, почему бы не использовать модифицированные версии метрики, которые учитывают грамматические аспекты базового языка?
  • Если такая метрика, которая учитывает грамматические аспекты, используется, может ли они обеспечить преимущества? Преимуществами в этом случае могут быть все, например, более чистый журнал ошибок.

Опять же, это могут быть огромные темы, и академические статьи приветствуются.

4b9b3361

Ответ 1

Что вызовет конфликт слияния?

Посмотрите на простейшую из git стратегии слияния, рекурсивную, во-первых: при слиянии двух ветвей, скажем a и b, которые имеют общий предок c, git создает патч для перехода от commit c к объявлению фиксации головы a и пытается применить этот патч к дереву во главе b. Если патч терпит неудачу, конфликт слияния.

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

Является ли контекст также использованными инструментами для применения патча?

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

Как они влияют на изменения, которые фактически не изменяют поведение исходного кода? Например, места для определения места обмена.

Патч

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

Существуют ли какие-либо оговорки/ограничения в отношении инструментов, о которых должен знать пользователь?

Что касается патча и diff: Нет. Оба алгоритма используют алгоритмы, которые существовали с начала 1970-х годов и достаточно надежны. Пока они не жалуются, вы можете быть уверены, что они сделали то, что вы намеревались.

Сказанное: git merge пытается самостоятельно разрешить конфликты слияния. В некоторых редких случаях все может пойти не так: эта страница имеет пример, близкий к его концу.

Было ли доказано, что алгоритмы не порождают неправильных результатов? Если нет, существуют ли реализации/документы, предлагающие интеграционное тестирование, которые, по крайней мере, доказывают, что они ошибочно ошибочны?

"неправильные результаты" - довольно неопределенный термин в этом контексте; Я бы сказал, что это невозможно доказать. Что эмпирически доказано, так это то, что применение патча, сгенерированного diff a b к файлу a, в любом случае приведет к созданию файла b.

Исходный код, даже если он изменен, сильно не изменится (особенно из-за реализованного алгоритма и ограничений синтаксиса), но может ли безопасность быть обобщена на общие текстовые файлы?

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

Я уверен, что git полностью надежный, так как у него есть полный история совершения и может пройти историю. Я бы хотел, чтобы некоторые указатели на академические исследования и ссылки на это, если они существуют.

Заключается в git - это моментальные снимки дерева с метаданными, а не различия с соседними версиями. Патч и diff вообще не участвуют в обходах пересмотра. (Но один уровень ниже поверхности, git затем организует капли в файлы пакетов, которые используют алгоритм дельта-сжатия. Ошибки здесь были бы легкими потому что git внутренне использует суммы sha1 для идентификации файлов, и сумма будет меняться, если произошла ошибка.)

Почему LCS используется вместо других строковых алгоритмов?

git по умолчанию использует алгоритм Майерса. Оригинальный документ объясняет, почему он работает так, как он делает. (Это не чисто LCS.)

Ответ 2

форматы diff/patch небезопасны. =) Потому что они ничего не знают о ваших источниках.

Вот описание формата, который я нарисовал (OMG) 2008. унифицированный формат diff

  • Слияние конфликтов запускается, когда строки в исходном блоке различаются или изменяются в фактическом исходном файле. Исходный кусок состоит из желтых линий, которые не начинаются с "+". Красный цвет выделяет номера строк, в которых программа патчей рассчитывает найти этот фрагмент источника перед исправлением. Если эти строки уже были изменены где-то в истории, вы получите конфликт слиянием.

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

  • Утилита патча ничего не знает о вашем поведении кода - она ​​просто вставляет и удаляет строки, давая вам предупреждения, когда ожидаемые строки не найдены (также могут выходить из строя или пытаться найти смещение) или когда они были изменены уже (слияние конфликта)

Надеюсь, это объяснение будет работать для вашего второго блока вопросов.

Что касается того, что можно было сделать, я когда-то придумал формат Extensible Changeset Format, так что формат diff мог нести дополнительные данные для более интеллектуальных инструментов исправления. я отправил идею в список рассылки subversion в 2011 году, но там было много энтузиазма в то время.

Я задокументировал идею Google Code, но он был закрыт, так что теперь он похоронен (без какой-либо истории) в GitHub здесь: https://github.com/techtonik/rainforce/blob/wiki/ExtensibleChangesetFormat.md

Ничего не получилось из-за отсутствия реальных проектов, которые могли бы выиграть от этого. На самом деле я создал расширенную версию (или, лучше сказать, альтернативу) формата патча, которая знает о файлах и каталогах. Он использовался для создания инкрементных обновлений для Wesnoth в 2008 году http://forums.wesnoth.org/viewtopic.php?f=5&t=20132, но я был слишком жадным, чтобы выпустить его с открытым исходным кодом (или боюсь, что я не сможет поддерживать инструмент должным образом, и он будет разветвлен какой-то коммерческой компанией, которая сделает много денег). Вот как выглядит расширенная/альтернативная версия формата пути:

[PatchPlan version 0.1]------------------------------------
* Description   : 
* Old Version   :
* New Version   :
* URL       :
* Patch made by : 
* Comments  :
* Used tools    :
-----------------------------------------------------------
[C ] ... "dir1/dir2/filename.ext" MD5
         N:"dir3/dir4/newfile.ext" MD5
[C ] ... "dir1/dir3/filename.ext" MD5
         P:"dir1/dir3/patchfile.ext.patch" TYPE MD5
[D ] ... "dir1/dir2/filename.ext" MD5
[A ] ... "dir1/dir2/filename.ext"
         N:"dir3/dir4/newfile.ext" MD5
[AD] ... "dir1/dir2/newdirname"
-----------------------------------------------------------

[C ] ... - Status field

         C  - Changed
         D  - Deleted
         A  - Added
         DE - Deleted empty directory
         DD - Deleted directory
         AD - Added directory
         ... - place reserved for flags like overwrite,
               force deletion etc. flags are separated by
               spaces from other fields




"dir1/dir2/filename.ext" - relative path of patched file


MD5    - 32 letters, i.e. cb5bc9f48388568178f24e6294ea782b


N:"dir3/dir4/newfile.ext" MD5
       - path for replacement file relative to directory
         with new files, i.e. temp directory where they
         were extracted, for example

P:"dir3/dir4/patchfile.ext.patch" TYPE MD5
       - path for patch file that should be applied
         TYPE is one of the supported 
         - VPATCH (DIFF, BSDIFF are planned)
       - .patch extensions is not a requirement, but
         merely a convention
       - MD5 in this case is MD5 of the new patched file
         and not of the patch itself


[D ] ... - MD5 of the file to be deleted

Учитывая, что каждый может извлечь инструмент самостоятельно для сравнения dirs и их исправления, создания двоичных патчей, текстовых патчей и т.д. До сих пор нет места для расширенной информации, но они могут быть добавлены по мере появления большего количества историй. Разумеется, мне было бы интересно участвовать в полной разработке такого инструмента (или, скорее, с открытым исходным кодом).

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

Ответ 3

  • Что вызовет конфликт слиянием?

Найдите исходную версию, с которой начались оба ветки. Запустите два diff против оригинала, от одной до левой версии ветки, а другой - вправо. В любом месте, где два показывают разные изменения в перекрывающихся смену изменения, конфликт git отказывается автосогласоваться. Что это.

  1. Является ли контекст также использованными инструментами для применения патча?

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

  1. Как они влияют на изменения, которые на самом деле не изменяют поведение исходного кода? Например, места для определения места обмена.

Они этого не делают. Подумайте о том, как научиться git применять семантику где. Если вы не мысленно кричите от ужаса, вы этого не делаете: -)

Вы можете предоставить свои собственные драйверы слияния. Это легко. Если у вас есть общие обычные случаи, которые вы хотите обрабатывать автоматически, просто сделайте это. Начните с простой оболочки script, которая вызывает встроенный драйвер, а затем sed или awk или что-то еще для конфликтов, которые вы можете обрабатывать правильно автоматически.


Я почти уверен, что git полностью надежный, так как у него есть полная история совершения и может проходить история. Я бы хотел, чтобы некоторые указатели на академические исследования и ссылки на это, если они существуют.

Git внутренняя структура невероятно проста. Я не шучу. Вы можете проверить надежность модели путем проверки. Сохраняйте структуру "даг-деревьев" и то, как работает слияние, попробуйте найти конкретную проблему или вопрос о ее надежности, я думаю, вы будете решать все так быстро, как они пытаются сформировать.

Если вы спрашиваете о надежности своих реализованных операций, правильно ли выполняете сжатие или передаете правильные объекты, чтобы удовлетворить push или fetch или еще что-то, что написано "у git есть ошибки?".