guide/read-unified-diff.md

Как читать unified diff (patch) — руководство для ревью кода

Разбираем на примере заголовки --- и +++, числа в заголовке блока @@, контекстные строки, пометку No newline at end of file и расширенные заголовки diff --git.

Обновлено: 2026-09-23

Патчи в ревью кода, отчётах об ошибках и рассылках почти всегда имеют формат unified diff. Его используют git diff, diff -u и «raw diff» на GitHub. Поначалу символов кажется много, но правила простые.

Общий вид

diff --git a/greet.py b/greet.pyindex 3b18e51..a6f4c2d 100644--- a/greet.py+++ b/greet.py@@ -1,5 +1,6 @@ def greet(name):-    print("Hello " + name)+    message = f"Hello, {name}!"+    print(message)  def main():     greet("world")

Сверху вниз идут расширенные заголовки git, заголовки файла (---, +++) и блоки (hunk — фрагменты, начинающиеся с @@). В одном файле может быть несколько блоков, а в одном патче — несколько файлов.

Заголовки файла: --- и +++

Заголовок блока @@ -a,b +c,d @@

@@ -1,5 +1,6 @@ означает: «показаны 5 строк файла до изменения начиная со строки 1 и 6 строк файла после изменения начиная со строки 1».

Посчитаем сами: контекстных строк (начинающихся с пробела) в примере выше четыре — def greet(name):, пустая строка, def main(): и greet("world"). До изменения — 4 контекстные строки плюс 1 строка -, итого 5; после — 4 контекстные плюс 2 строки +, итого 6. Отсюда заголовок -1,5 +1,6.

Три вида строк в теле

Первый символЗначение
ПробелКонтекстная строка, одинаковая в обоих файлах
-Строка есть только до изменения (удаление)
+Строка есть только после изменения (добавление)

По умолчанию контекст — 3 строки до и после изменения (можно изменить, например git diff -U5). Контекстные строки нужны, чтобы при применении патча найти правильное место. Если номера строк немного сдвинулись, но контекст совпадает, patch применит изменение со смещением (offset).

Исправление одной строки выглядит как пара: строка -, за ней строка +. В формате unified нет отдельного символа для «изменения», поэтому полезно читать группу строк - и группу строк + вместе, сопоставляя их сверху вниз.

\ No newline at end of file

@@ -1,2 +1,2 @@ host=example.com-port=8080\ No newline at end of file+port=8080

Эта пометка означает, что строка прямо над ней — последняя в файле и в её конце нет символа перевода строки. В примере содержимое одинаково, а завершающий перевод строки добавлен только в файл после изменения. Подробнее — в статье Концы строк и невидимые различия.

Расширенные заголовки git

Строки после diff --git a/path b/path — дополнительная информация, которую выводит только git.

Полезные приёмы для ревью

  1. Посмотрите сначала на разницу в числе строк в заголовке блока — она даёт представление о размере изменения. -10,7 +10,30 означает, что добавилось 23 строки.
  2. Чтобы отсеять блоки, где изменились только пробелы, используйте git diff -w. Особенно полезно, когда в коммите смешаны выравнивание отступов и реальные изменения (Опции игнорирования пробелов).
  3. Чтобы увидеть, что изменилось внутри строки, используйте git diff --word-diff или вставьте diff в инструмент с подсветкой внутри строк, как этот сайт.
  4. Перед применением патча проверьте командой git apply --check file.patch, что он применяется без ошибок. Вне git-репозитория используйте patch -p1 --dry-run < file.patch.

Попробуйте в этом инструменте

Объединённый вид в сравнении текстов показывает группу -, затем группу + в том же порядке, что и этот формат, и дополнительно подсвечивает изменённые слова внутри строк. Кнопка patch на панели результата копирует стандартный текст unified diff, а соседняя кнопка сохранения скачивает файл diff.patch. Patch, созданный при выключенных опциях игнорирования, можно применить к оригиналу через patch -p1 или git apply.

Перейти к сравнению текстов