Ревью кода по диффу: как читать изменения и находить блокеры

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

Из чего состоит diff

Unified diff (тот, что даёт git diff) описывает изменения кусками — hunk’ами:

diff --git a/auth.php b/auth.php
--- a/auth.php
+++ b/auth.php
@@ -12,6 +12,9 @@ function check_login($user, $pass) {
     $hash = get_hash($user);
+    if (!$hash) {
+        return new Result('unknown_user');
+    }
     if (!verify($hash, $pass)) {
         return false;
     }

Что здесь важно уметь читать:

  • @@ -12,6 +12,9 @@ — «в старом файле кусок начинается со строки 12 и занимает 6 строк; в новом — с 12 и занимает 9». Числа после запятой говорят, сколько строк добавилось/убралось.
  • + — новая строка, - — удалённая, пробел — контекст (было и осталось). Контекст нужен, чтобы понять, где именно правка и не ломает ли она соседа.
  • Пустой hunk-заголовок без функции (просто @@ -1,3 +1,4 @@) означает, что правка не «прилеплена» к знакомому месту — её сложнее вписать в логику.

Главное правило чтения диффа: не доверяй только зелёным +. Смысл часто спрятан в паре -/+ на одной строке — это не «дописали», это заменили, и замена могла унести условие, скобку или return, которые держали поведение.

Чек-лист: на что смотреть в изменённом коде

Дифф сам по себе молчит о намерении. Задача ревьюера — задать несколько скучных вопросов по каждому куску. Рабочий список, разбитый по фокусам:

Корректность

  • Изменённая ветка (if/цикл) теперь возвращает/пропускает то же, что раньше, или это осознанная смена поведения?
  • Добавленное условие не делает код ниже мёртвым (ранний return съедает последующие проверки)?
  • Новые переменные инициализированы на всех путях, а не только на happy path?

Безопасность

  • Вход, приехавший в правку, экранируется/проверяется до использования (SQL, HTML, shell, path)?
  • Не появилось ли секретного значения в коде (токен, ключ, пароль) вместо конфига?
  • Новый маршрут/хендлер защищён проверкой полномочий, а не только «фронт не покажет»?

Производительность

  • Не добавился ли запрос к БД/API внутри цикла (N+1)?
  • Тяжёлая операция не переехала ли в горячий путь (конструктор, обработчик каждого запроса)?

Сопровождаемость

  • Изменение сопровождается тестом, который упадёт при откате правки?
  • Имя переменной/функции не поехало ли без обновления вызовов (частая причина «локально ок, на проде — undefined»)?

Стиль (последний приоритет, но не ноль)

  • Отступы, именование, отсутствие мёртвого кода — но не спор о вкусе, если функционально всё чисто.

Типовые ловушки ревьюера

  1. «Дифф маленький — гляну на бегу». Удаление одной строки-проверки меняет весь контракт функции. Размер правки ≠ её влияние.
  2. Доверять подписи PR, а не коду. «Fix login» может включать рефакторинг миграции БД. Смотрите diff, а не title.
  3. Пропускать изменения в конфигах и миграциях. Строка в .env, в nginx.conf или в SQL-миграции опаснее правки хелпера, но часто «проскакивает» как скучная.
  4. Комментировать следствие, не причину. «Тут null вернёшь?» — а надо: «эта ветка теперь возвращает null, тогда как раньше — объект; все вызывающие будут падать на .method».
  5. Легитимизировать «как-нибудь потом смержим». Пройденный красными тестами мерж = ревью не работает.

Когда глаз замыливается: автоматический первичный разбор

Ревьюер обязан понимать, что искать. Но прогонять механический чек-лист по каждому куску вручную — рутина, к тому же глаз к третьему диффу за день «слепнет» к очевидному. Первичный разбор изменений по фокусам (безопасность, производительность, баги, стиль, тесты) можно доверить инструменту — а решение о мерже оставить за собой.

В codestack.space для этого есть AI Code Diff Reviewer. Он принимает два способа описания изменений и четыре уровня детальности:

Что подаёте:

  • режим unified diff — вставляете готовый git diff целиком;
  • режим до / после — пару версий одного участка, а diff генератор считает сам.

На что смотреть: фокус full, security, performance, bugs, style, tests — от общего обзора до прицельной проверки, например, только на N+1-запросы.

Флаги вывода:

  • маркеры критичности 🔴 / 🟠 / 🟡 — сразу видно блокер против косметики;
  • предлагаемое исправление — не только «тут плохо», но и патч;
  • ссылки на строки/файлы — замечание привязано к конкретному месту;
  • краткое резюме для PR — готовый комментарий под пул-реквест.

Инструмент находит суть только в изменённых строках, не выдумывает файлы и строки, которых нет в диффе, и ставит вердикт. Попробуйте инструмент прямо здесь, на своих данных:

ИИ-ревью изменений кода
Гость
Токены: 0 / 50 000
Гостевой лимит — 50 000 токенов. Зарегистрируйтесь, для пользователей лимит + 200 000 токенов.

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

Мини-итог

Diff читают по hunk’ам, следя за парами -/+, а не только за зелёным. Ревью отвечает на пять скучных вопросов (корректность, безопасность, производительность, сопровождаемость, стиль) и остерегается ловушек «маленькая правка» и «доверяю заголовку PR». А механический первичный прогон изменений по этим фокусам можно делегировать инструменту и вернуться к решению о мерже с готовой картой находок.

👤 Зарегистрируйтесь, чтобы добавить материал в закладки.