Как работают алгоритмы diff
Каждый вид diff на этой странице создаётся алгоритмом Myers — техника 1986 года Юджина У. Майерса, которая находит кратчайший скрипт правок между двумя последовательностями токенов за O((N+M)D) операций, где D — расстояние редактирования. Алгоритм построен вокруг задачи наибольшей общей подпоследовательности, и движок работает полностью в вашем браузере с помощью открытой библиотеки jsdiff.
- Токенизация входных данных — Перед сравнением алгоритм разбивает каждый ввод на последовательность токенов. Гранулярность по строкам разбивает по символам новой строки; по словам — по границам пробелов и пунктуации; по символам — каждая кодовая точка Unicode является отдельным токеном.
- Построение графа правок — Алгоритм Myers моделирует сравнение как путь по двумерной сетке, где движение вправо означает «удалить из оригинала», вниз — «вставить из изменённого», по диагонали — «токен совпадает в обоих». Алгоритм находит кратчайший путь с максимальным числом диагональных ходов.
- Извлечение НОП — Диагональные ходы в кратчайшем пути отслеживают наибольшую общую подпоследовательность — токены, встречающиеся в обоих вводах в одном относительном порядке. Каждый токен в НОП — «без изменений»; всё остальное — либо добавление, либо удаление.
- Применение параметров предобработки — При включённой опции «Игнорировать регистр» оба ввода переводятся в нижний регистр перед расчётом НОП, чтобы «ПРИВЕТ» и «привет» считались одинаковыми. «Игнорировать пробелы» сжимает несколько пробелов в один. «Обрезать каждую строку» убирает ведущие и завершающие пробелы в каждой строке перед сравнением.
- Отображение выбранного вида — Результат — один и тот же расчёт НОП, представленный тремя способами: «Бок о бок» показывает оригинал слева и изменённый справа в двухколоночной сетке с красными и зелёными выделениями строк. «Унифицированный» показывает один столбец со строками с префиксами − и +, как вывод
git diff. «Встроенный» отображает удаления красным зачёркиванием и добавления зелёным подчёркиванием в едином потоке текста. - Вычисление итоговой полосы — После отображения инструмент подсчитывает количество добавленных, удалённых и неизменённых токенов, затем вычисляет схожесть как отношение неизменённых токенов к большему из двух входных объёмов. Схожесть 100% означает, что вводы идентичны после предобработки.
Зачем использовать diff checker
- Код-ревью без Git-клиента — Вставьте две версии конфигурационного файла, SQL-миграции или shell-скрипта и посмотрите, что изменилось, не клонируя репозиторий, не переключая ветки и не дожидаясь CI-пайплайна. Инструмент удобен для быстрых ревью при парном программировании, при передаче работ подрядчиком без общей истории Git и для устаревших кодовых баз без контроля версий. Унифицированный вид создаёт вывод, который можно скопировать прямо в чат или тикет.
- Сравнение контрактов и правок документов — Поуровневый diff показывает, какие термины изменились между черновиками контракта, быстрее, чем панель «Отслеживание изменений» в Word. Вставьте пункт A из первого черновика и пункт B из подписанной копии — замена выделится красным и зелёным на точной фразе, которая изменилась. Юристы и команды закупок используют это для проверки правок в последнюю минуту перед подписанием контракта.
- Правки эссе и черновиков — Авторы, сравнивающие первый черновик с отредактированной версией, могут переключиться на гранулярность по словам, чтобы увидеть каждую замену, вставку и вырезку, не перечитывая оба текста. Тот же рабочий процесс подходит для переводчиков, проверяющих изменения относительно исходного текста, для редакторов, убеждающихся, что правка сохранила голос автора, и для журналистских команд, сверяющих опубликованную статью с поданным черновиком.
- Сравнение журналов и конфигураций — Системные администраторы, сравнивающие два снимка конфигурации сервера, два расписания cron или два вывода
ps aux, могут использовать гранулярность по строкам для поиска единственного изменённого параметра в 200-строчном файле за секунды. Используйте совместно с опцией «Игнорировать пробелы» — и шумный diff из-за выравнивания сведётся к реально изменившимся параметрам.
Типичные сценарии использования
Текстовый diff возникает в конце каждого цикла правок в писательской, разработческой и операционной работе.
- Ревью pull request: вставьте две реализации функции бок о бок, чтобы понять логическое изменение перед одобрением, без накладных расходов на checkout ветки.
- QA локализации: сравните английскую исходную строку с переведённым эквивалентом на уровне слов для выявления вставок, пропусков или подмены терминологии, которые мог допустить переводчик.
- Анализ инцидентов: сравните два снимка манифеста Kubernetes или два вывода «docker inspect» на уровне строк для выявления изменения конфигурации, предшествовавшего сбою.
Практический пример
Возьмём конфигурацию сервера из пяти строк. Оригинал: host=localhost, port=5432, dbname=app_db, user=app, password=secret. Изменённый: host=db.prod.example.com, port=5432, dbname=app_db, user=app_prod, password=secret. При гранулярности по строкам и виде «Бок о бок» строка 1 покажет красный слева (host=localhost) и зелёный справа (host=db.prod.example.com), строка 4 — красный (user=app) и зелёный (user=app_prod), а строки 2, 3 и 5 останутся без изменений с обеих сторон. Итоговая полоса сообщит: 2 добавлено, 2 удалено, 3 без изменений, схожесть 60% — три из пяти строк сохранены. Переключитесь на гранулярность по словам — diff сузится ещё: только значения справа от = в строках 1 и 4 выделятся, ключи останутся неизменными, а схожесть вырастет до ~85%, так как НОП теперь считает host, user и окружающую пунктуацию сохранёнными.
Это работает в моём браузере?
Да. Весь расчёт diff выполняется на стороне клиента с помощью открытой библиотеки jsdiff, загружаемой вместе со страницей. Всё, что вы вводите, вставляете или сравниваете, не отправляется ни на какой сервер. Убедитесь сами: откройте DevTools браузера, перейдите на вкладку Network, очистите журнал, нажмите «Сравнить» и убедитесь, что для шага сравнения не выполнено ни одного сетевого запроса.
Что означает процент схожести?
Схожесть вычисляется как неизменённые токены / max(общее количество токенов в оригинале, общее количество токенов в изменённом). 100% означает, что два ввода идентичны после применения параметров предобработки (сведение регистра, сжатие пробелов, обрезка строк). 0% означает, что ни один токен не является общим. Метрика — грубое приближение расстояния редактирования, полезное как быстрый ориентир, но не как оценка заимствований или оригинальности.
Можно ли сравнивать JSON / YAML / XML семантически?
Не в этом инструменте. Это текстовый diff, поэтому переформатирование JSON или XML только с изменением пробелов всё равно показывает много изменений, даже если данные логически идентичны. Изменение порядка ключей в объекте JSON тоже показывается как изменения, хотя большинство парсеров считает порядок ключей незначимым. Для истинного семантического diff, сравнивающего разобранные деревья объектов и игнорирующего порядок ключей и форматирование, планируется отдельный инструмент JSON Diff. Пока что нормализуйте оба ввода к одному отступу и порядку ключей перед вставкой сюда.
Чем отличаются унифицированный и «бок о бок» виды?
«Бок о бок» выводит два столбца: оригинал слева и изменённый справа; удалённые строки выделяются красным слева, добавленные — зелёным справа. Неизменённые строки отображаются в обоих столбцах выровненными в одну строку. «Унифицированный» выводит один столбец с префиксом − и красным фоном для удалённых строк и префиксом + и зелёным фоном для добавленных — тот же формат, что выводит git diff в терминале. Используйте унифицированный, когда хотите скопировать результат как файл патча или вставить в ветку код-ревью. Используйте «бок о бок», когда важнее видеть визуальное выравнивание того, что что заменило.
Вставьте оригинал слева, изменённую версию справа, выберите вид и гранулярность — сравнение появится в миллисекунды. Включите режим реального времени — и diff пересчитывается при каждом нажатии клавиши при редактировании любой из сторон. Скачайте результат как стандартный унифицированный файл .patch, который git apply применяет напрямую. Без загрузки, без аккаунта, без API-ключа поставщика, без квот.