Код-ревью — это не «посмотреть, красиво ли». Это проверка одной вещи: не сломает ли этот патч то, что уже работает, и решает ли он поставленную задачу. Смотрят при этом почти всегда не на код целиком, а на 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»)?
Стиль (последний приоритет, но не ноль)
- Отступы, именование, отсутствие мёртвого кода — но не спор о вкусе, если функционально всё чисто.
Типовые ловушки ревьюера
- «Дифф маленький — гляну на бегу». Удаление одной строки-проверки меняет весь контракт функции. Размер правки ≠ её влияние.
- Доверять подписи PR, а не коду. «Fix login» может включать рефакторинг миграции БД. Смотрите diff, а не title.
- Пропускать изменения в конфигах и миграциях. Строка в
.env, вnginx.confили в SQL-миграции опаснее правки хелпера, но часто «проскакивает» как скучная. - Комментировать следствие, не причину. «Тут
nullвернёшь?» — а надо: «эта ветка теперь возвращаетnull, тогда как раньше — объект; все вызывающие будут падать на.method». - Легитимизировать «как-нибудь потом смержим». Пройденный красными тестами мерж = ревью не работает.
Когда глаз замыливается: автоматический первичный разбор
Ревьюер обязан понимать, что искать. Но прогонять механический чек-лист по каждому куску вручную — рутина, к тому же глаз к третьему диффу за день «слепнет» к очевидному. Первичный разбор изменений по фокусам (безопасность, производительность, баги, стиль, тесты) можно доверить инструменту — а решение о мерже оставить за собой.
В codestack.space для этого есть AI Code Diff Reviewer. Он принимает два способа описания изменений и четыре уровня детальности:
Что подаёте:
- режим
unified diff— вставляете готовыйgit diffцеликом; - режим
до / после— пару версий одного участка, а diff генератор считает сам.
На что смотреть: фокус full, security, performance, bugs, style, tests — от общего обзора до прицельной проверки, например, только на N+1-запросы.
Флаги вывода:
- маркеры критичности 🔴 / 🟠 / 🟡 — сразу видно блокер против косметики;
- предлагаемое исправление — не только «тут плохо», но и патч;
- ссылки на строки/файлы — замечание привязано к конкретному месту;
- краткое резюме для PR — готовый комментарий под пул-реквест.
Инструмент находит суть только в изменённых строках, не выдумывает файлы и строки, которых нет в диффе, и ставит вердикт. Попробуйте инструмент прямо здесь, на своих данных:
Он не заменяет ревьюера: финальное решение, «хочу ли я это на проде», остаётся за человеком, потому что инструмент не знает контекст продукта и цены отката. Но первичный разбор по чек-листу выше он снимает, оставляя вам главное — суждение.
Мини-итог
Diff читают по hunk’ам, следя за парами -/+, а не только за зелёным. Ревью отвечает на пять скучных вопросов (корректность, безопасность, производительность, сопровождаемость, стиль) и остерегается ловушек «маленькая правка» и «доверяю заголовку PR». А механический первичный прогон изменений по этим фокусам можно делегировать инструменту и вернуться к решению о мерже с готовой картой находок.
👤 Зарегистрируйтесь, чтобы добавить материал в закладки.
