Как работает сравнение текстов
Оба текста разбиваются на строки, и страница находит самую длинную последовательность строк, общую для обоих и идущую в том же порядке (наибольшая общая подпоследовательность). Всё остальное — изменения: строки только в оригинале удалены, строки только в изменённом тексте добавлены. Используется алгоритм Юджина Майерса — тот же, что лежит в основе GNU diff и git diff, поэтому находится наименьший набор изменений.
Если блок удалённых строк стоит вплотную к блоку добавленных, их сопоставляют по порядку и сравнивают ещё раз по словам. Различающиеся слова отмечаются, поэтому изменённый номер порта или путь заметен в длинной строке. Если у двух сопоставленных строк мало общего, вся строка показывается как изменённая.
«Игнорировать пробелы» считает последовательности пробелов и табуляций одним пробелом и пропускает их в концах строк, что помогает после смены отступов. «Игнорировать регистр» сравнивает буквы без учёта заглавных и строчных. Окончания строк (CRLF в Windows или LF в Unix) никогда не считаются различием. Длинные неизменённые участки сворачиваются, вокруг каждого изменения остаются три строки контекста.
Пример
В примере сайт nginx переведён с обычного HTTP на HTTPS. В оригинале 11 строк, в изменённой версии 12. Diff показывает: неизменённых строк — 7, удалённых — 4, добавленных — 5. В строке listen только «80» превратилось в «443 ssl», а в строке root только «html» стало «example», поэтому отмечены именно эти слова. В формате unified diff это выглядит так:
--- original.conf
+++ changed.conf
@@ -1,11 +1,12 @@
server {
- listen 80;
+ listen 443 ssl;
+ http2 on;
server_name example.com www.example.com;
- root /var/www/html;
+ root /var/www/example;
+ ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
+
location / {
try_files $uri $uri/ =404;
}
-
- access_log /var/log/nginx/access.log;
}
Строки, начинающиеся с минуса, удалены, с плюса — добавлены, с пробела — неизменённый контекст. Заголовок @@ -1,11 +1,12 @@ означает, что блок охватывает строки с 1 по 11 оригинала и с 1 по 12 изменённого текста. Команда patch может применить такой файл к оригиналу: patch original.conf changes.diff.
Вопросы
Как сравнить два текста и найти различия?
Вставьте старую версию в левое поле, а новую — в правое. Различия появятся сразу: удалённые строки красным, добавленные зелёным, а внутри них отмечены изменённые слова. Если вставили наоборот, нажмите «Поменять местами».
Загружается ли мой текст куда-нибудь?
Нет. Сравнение выполняется в вашем браузере с помощью JavaScript, и текст не покидает эту страницу. Поэтому можно безопасно вставлять конфиги, журналы и код, которые вы не стали бы отправлять на сайт, передающий текст на сервер. При закрытии вкладки текст исчезает.
Что делает «игнорировать пробелы» в diff?
Строки считаются равными, если они различаются только пробелами: несколько пробелов или табуляций считаются одним пробелом, а пробелы в начале и конце строки игнорируются. Это полезно после изменения отступов в файле или замены табуляций пробелами. Слова внутри изменённых строк сравниваются так же.
Как сравнить два файла в командной строке?
В Linux и macOS: diff -u old.conf new.conf или git diff --no-index old.conf new.conf — с цветами и отметками слов (добавьте --word-diff). В Windows: fc old.conf new.conf в cmd или Compare-Object (Get-Content old.conf) (Get-Content new.conf) в PowerShell. Добавьте -w к diff, чтобы игнорировать пробелы.
Что означает @@ -1,11 +1,12 @@ в diff?
Это заголовок блока (hunk) в unified diff. -1,11 значит, что блок начинается со строки 1 старого файла и охватывает 11 строк; +1,12 — что он начинается со строки 1 нового файла и охватывает 12. Ниже строки с - удалены, с + добавлены, а пробел означает неизменённый контекст.