Программа diff
в своих различных воплощениях разумно хороша при вычислении разницы между двумя текстовыми файлами и выражении ее более компактно, чем отображение обоих файлов полностью. Он показывает разницу как последовательность вставленных и удаленных фрагментов строк (или в некоторых случаях измененных строк, но это эквивалентно удалению, за которым следует вставка). Эта же или очень похожая программа или алгоритм используется patch
и системами управления версиями для минимизации хранения, необходимого для представления различий между двумя версиями одного и того же файла. Обсуждается алгоритм здесь и здесь.
Но он падает, когда в файл перемещаются блоки текста.
Предположим, что у вас есть следующие два файла: a.txt
и b.txt
(представьте, что они представляют собой сотни строк длиной, а не только 6):
a.txt b.txt
----- -----
1 4
2 5
3 6
4 1
5 2
6 3
diff a.txt b.txt
показывает это:
$ diff a.txt b.txt
1,3d0
< 1
< 2
< 3
6a4,6
> 1
> 2
> 3
Изменение от a.txt
до b.txt
может быть выражено как "Возьмите первые три строки и переместите их в конец", но diff
показывает полное содержимое перемещенного фрагмента строк дважды, упуская возможность для краткого описания этого большого изменения.
Обратите внимание, что diff -e
показывает блок текста только один раз, но это потому, что он не отображает содержимое удаленных строк.
Существует ли вариант алгоритма diff
, который (a) сохраняет diff
способность представлять вставки и удаления и (b) эффективно представляет перемещенные блоки текста без необходимости показывать их все содержимое?