Программа 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) эффективно представляет перемещенные блоки текста без необходимости показывать их все содержимое?