🔍
Инструменты разработчика
March 19, 20266 min readBy BrowseryTools Team

Сравнение текста и алгоритмы diff: полное руководство

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

diffсравнение текстаgitверсионированиеразработка

Каждый разработчик сталкивался с этой ситуацией: две версии файла, которые должны быть идентичны, но что-то изменилось. Может быть, конфигурационный файл, отредактированный вручную на сервере. Может быть, договор, вернувшийся от юриста с нераскрытыми правками. Может быть, файл перевода, возвращённый поставщиком, — и нужно убедиться, что ничего случайно не удалено. Во всех этих случаях ответ один: запустить diff.

Вы можете мгновенно сравнить любые два блока текста с помощью инструмента сравнения текста BrowseryTools — бесплатно, без регистрации, всё остаётся в браузере.

Почему важно сравнение текста

Diff — не только инструмент разработчика. Любая ситуация, где существуют две версии документа и нужно выявить различия, является задачей сравнения:

  • Ревью кода — понимание того, что изменилось между двумя версиями исходного кода перед одобрением слияния
  • Сравнение договоров и юридических документов — точное определение того, какие пункты были добавлены, удалены или изменены между черновиками
  • Управление конфигурацией — подтверждение того, что развёрнутый конфигурационный файл соответствует версии в системе контроля версий
  • Верификация переведённого контента — проверка того, охватывает ли переведённый документ все те же разделы, что и оригинал
  • Валидация данных — сравнение CSV-экспортов из двух систем для обнаружения расхождений
  • Корректура — выявление непреднамеренных изменений между черновиком документа и его опубликованной версией

Как работают алгоритмы diff

Базовая задача, решаемая алгоритмом diff: по двум последовательностям A и B найти минимальный набор правок (вставок и удалений), необходимый для преобразования A в B. Формально это задача нахождения наибольшей общей подпоследовательности (LCS). Diff затем сообщает, что не вошло в LCS — строки, уникальные для A (удаления) и строки, уникальные для B (вставки).

В практических реализациях доминируют два алгоритма:

  • Алгоритм Майерса (1986) — алгоритм, лежащий в основе оригинальной Unix-команды diff и Git. Юджин Майерс разработал его для поиска кратчайшего сценария правок (diff с минимальным числом вставок и удалений) за время O(ND), где N — суммарный размер обоих входов, а D — число различий. Он быстрый и создаёт минимальные diff-ы, но может давать неинтуитивный вывод при перемещении больших блоков кода.
  • Patience diff — разработан Брэмом Коэном (создателем BitTorrent) и используется в Bazaar, впоследствии популяризирован Kaleidoscope. Вместо побайтовой работы patience diff сначала сопоставляет уникальные строки, встречающиеся ровно по одному разу в обоих файлах. Это даёт вывод, гораздо лучше сохраняющий границы функций и блоков для исходного кода. Git поддерживает его через git diff --patience.

Чтение унифицированного вывода diff

Унифицированный формат diff — стандартный вывод git diff и большинства diff-инструментов. После понимания нотации он становится мгновенно читаемым.

--- a/config.yml       (исходный файл)
+++ b/config.yml       (изменённый файл)
@@ -10,7 +10,8 @@     (заголовок фрагмента)
 server:
   host: localhost
-  port: 3000
+  port: 8080
+  timeout: 30
   debug: false

Ключевые элементы для чтения:

  • Строки, начинающиеся с - — присутствовали в оригинале, удалены в новой версии (выделены красным)
  • Строки, начинающиеся с + — отсутствовали в оригинале, добавлены в новой версии (выделены зелёным)
  • Строки без префикса (пробел) — неизменённые контекстные строки, показанные для ориентации
  • Заголовок фрагмента @@ — читается как «начиная со строки 10, показывая 7 строк из оригинала; начиная со строки 10, показывая 8 строк новой версии». Формат: @@ -начало,количество +начало,количество @@.

Посимвольный, пословный и построчный diff

Гранулярность diff определяет его полезность для конкретной задачи.

  • Построчный diff — стандарт для исходного кода. Каждая строка обрабатывается как атомарная единица. Быстрый и подходящий для кода, где строки короткие и значимые. Если одно слово меняется в длинном абзаце, вся строка показывается как изменённая.
  • Пословный diff — подходит для прозы и документации. Изменённые слова в строке подсвечиваются по отдельности, давая значительно более чёткий сигнал в документах с большим количеством текста. Большинство инструментов сравнения документов (Microsoft Word — отслеживание изменений, история версий Google Docs) работают на уровне слов.
  • Посимвольный diff — выделяет отдельные изменения символов внутри слов. Наиболее полезен для обнаружения опечаток, изменений пробелов, невидимых символов (пробелы нулевой ширины, неразрывные пробелы) или различий в кодировке. Необходим для сравнения данных, визуально выглядящих идентично, но различающихся на уровне байтов.

Инструмент сравнения текста BrowseryTools выделяет различия встроенно, что позволяет мгновенно замечать изменения без ручного чтения унифицированного формата diff.

Как работает git diff под капотом

При запуске git diff Git вычисляет алгоритм Майерса между версиями объектов, хранимыми в его базе объектов. Несколько полезных флагов изменяют поведение:

git diff                      # неиндексированные изменения vs последний коммит
git diff --staged             # индексированные изменения vs последний коммит
git diff HEAD~3               # текущее состояние vs 3 коммита назад
git diff main...feature       # что ветка feature добавила к main
git diff --word-diff          # подсветка на уровне слов
git diff --patience           # использовать алгоритм patience (лучше для кода)
git diff --stat               # сводка: изменённые файлы, вставки, удаления

Понимание git diff main...feature конкретно: нотация с тремя точками показывает, что ветка feature добавила с момента отделения от main, исключая любые изменения, произошедшие в main после точки ветвления. Это почти всегда то, что нужно для ревью pull request-а, а не нотация с двумя точками main..feature, которая напрямую сравнивает текущие вершины обеих веток.

Практические сценарии использования

Сравнение конфигурационных файлов

Конфигурационные файлы (YAML, TOML, JSON, .env) являются частым источником производственных багов, когда развёрнутые версии расходятся с версиями в системе контроля версий. Перед отладкой загадочной проблемы в продакшне сравнение живого конфига с ожидаемым часто сразу выявляет причину.

Сравнение договоров и документов

Когда черновик договора возвращается от другой стороны, никогда не доверяйте краткому изложению изменений. Экспортируйте обе версии в обычный текст и запустите diff. Юристы известны тем, что меняют определённые термины, добавляют ограничения ответственности или изменяют сроки уведомления способами, которые легко пропустить при быстром чтении. Пословный diff делает каждое изменение видимым.

Верификация переведённых документов

При работе с переведённым контентом сравните структуру переведённого документа с источником. Структурный diff заголовков разделов и количества абзацев выявляет, были ли случайно пропущены или объединены разделы при переводе.

Сравнение инструментов diff

  • git diff — встроенный, построчный, унифицированный формат diff, без GUI. Базовый инструмент для всей работы с кодом.
  • vimdiff — терминальный параллельный diff внутри Vim. Мощный для быстрых сравнений без выхода из терминала; крутая кривая обучения.
  • Beyond Compare — коммерческий настольный инструмент с синхронизацией папок, бинарным diff и трёхсторонним слиянием. Золотой стандарт для сравнения документов без разработчиков.
  • Meld — бесплатный кроссплатформенный GUI-инструмент diff с поддержкой трёхстороннего слияния. Лучшая бесплатная альтернатива Beyond Compare.
  • BrowseryTools Text Diff — мгновенный, браузерный, без установки. Лучший вариант для быстрых разовых сравнений, особенно текста, который не хотелось бы вставлять в онлайн-сервис.

🛠️

Try the Tools — 100% Free, No Sign-Up

Everything runs in your browser. No uploads. No accounts. No ads.

Explore All Tools →