Первый pull request на новой работе читают не как вклад в продукт, а как образец вашего стиля. Ревьюер ещё не знает, аккуратный вы человек или тот, кто приносит 800 строк «заодно». Один маленький, чистый diff с понятным описанием сильнее большой фичи, которую потом неделю чинят.
Ниже — как выбрать задачу, пройти пайплайн, оформить описание и спокойно закрыть ревью. Без героизма и без «я пока учусь, извините». Цель первого PR — показать, что вы умеете доводить кусок до конца в правилах этой команды.
Коротко:
- Берите маленькую задачу с понятным критерием готовности: баг, тест, документация, мелкая правка.
- Сначала скопируйте стиль недавних смёрженных PR, а не «как принято в индустрии».
- Один PR — одно изменение. Смешанный diff ревьюят хуже и дольше.
- Описание отвечает на три вопроса: что, зачем, как проверить.
- Комментарии ревью — про код, не про вас. Спрашивайте, не спорьте из принципа.
Зачем первый PR важнее размера задачи
Команда смотрит не на объём. Смотрят, умеете ли вы довести изменение до продакшена в их процессе: ветка, тесты, описание, реакция на замечания, отсутствие сюрпризов. Если первый вклад — огромный рефакторинг «я сразу улучшил архитектуру», вас запомнят как человека, которого нужно тормозить. Если первый вклад — 20 строк и зелёный пайплайн, вас запомнят как человека, с которым можно работать.
Это особенно заметно на удалёнке. В офисе новичка видят. На удалёнке вас видно по артефактам: сообщения в чате, тикеты, PR. Первый мёрж — самый дешёвый способ показать, что вы уже внутри процесса. Как встроиться в первую неделю в целом — отдельно в материале про первую неделю разработчика.
Какую задачу брать первой
Идеальный первый PR закрывает четыре условия:
- Результат видно за один-два дня, не за две недели.
- Критерий готовности ясен без продуктового спора.
- Затронутый код можно прочитать, не поднимая полсистемы.
- Есть к кому сходить с одним конкретным вопросом, если застряли.
Подходят: опечатка в пользовательском тексте, правка README после того, как вы сами споткнулись об инструкцию, недостающий тест на уже починенный баг, мелкий UI-баг с понятным воспроизведением, добавление лога в уже известное место. Не подходят: «переписать модуль», «навести порядок в зависимостях», «оптимизировать всё медленное», задача без описания и без шагов воспроизведения.
Если менеджер даёт крупную фичу в первый день, не геройствуйте молча. Спросите, можно ли вырезать из неё первый кусок: контракт, тест, кусок API, правку документации. Крупное изменение всё равно разобьют на ревью — лучше разбить сами. Как вообще читать незнакомый репозиторий, чтобы выбрать этот кусок, — в гайде как разобраться в чужой кодовой базе.
Подготовка до кнопки Create
До оформления PR пройдите локальный конвейер так, как его проходит команда, а не «у меня на машине работает».
- Обновите основную ветку и перебазируйтесь или смёржьте её в свою, как принято здесь. Не приносите конфликт «разберётесь на ревью».
- Прогоните линтер и тесты той командой, что в CI. Если CI гоняет подмножество — гоняйте то же подмножество плюс то, что вы трогали.
- Посмотрите diff целиком глазами. Уберите отладочные принты, закомментированный код, случайные переформатирования чужих файлов, личные заметки.
- Проверьте имена: ветка, коммиты, файлы. Если в проекте принят префикс тикета — поставьте его. Если squashing на мёрже — не устраивайте роман из десяти «fix»-коммитов, если вас об этом не просили.
Если тесты локально красные ещё до ваших правок — это отдельный разговор в чате, не часть вашего PR. Зафиксируйте: «на main уже падает X, моё изменение это не трогает». Иначе ревьюер решит, что сломали вы.
Как оформить описание
Заголовок — одно предложение в повелительном или изъяснительном наклонении, как в соседних PR. Не «правки», не «WIP пожалуйста посмотрите». Описание держит четыре блока. Их можно уложить в короткий шаблон.
Что изменилось: одной фразой, без истории жизни.
Зачем: баг / дырка в доке / пробел в тесте. Ссылка на тикет, если тикет есть.
Как проверить: шаги, команды, что считать успехом. Скрин или лог — только если без них не воспроизвести.
Риски и что не вошло: миграции, флаги, места, которые вы сознательно не трогали.
Если в репозитории уже есть шаблон — заполняйте его, не изобретайте свой. Пустые секции «Checklist: [ ] tests» с галочками наугад хуже честной строки «тестов на этот слой в проекте нет, проверил вручную так-то».
Пример 1. Фикс бага в API
Задача: при пустом списке заказов ручка отдаёт 500 вместо пустого массива. Junior backend, первая неделя.
Fix empty orders list returning 500.
Что: в GET /orders при отсутствии записей сервис бросал исключение на разборе None. Теперь возвращаем пустой список и 200.
Зачем: тикет JS-1842, воспроизводится на пустой базе после онбординга. Ломает кабинет менеджера.
Как проверить: поднять API по README, очистить таблицу orders или зайти под новым пользователем, вызвать GET /orders. Ожидание: 200 и []. Добавил тест test_list_orders_empty.
Риски: поведение для «пользователь не найден» не менял — там по-прежнему 404. Миграций нет.
Почему это проходит: ревьюер за пять секунд понимает вход, выход и как не сломать руками. Diff маленький, тест есть, граница изменения названа.
Пример 2. Правка документации как первый вклад
Вы полдня поднимали проект, потому что в README была старая команда миграций. Это нормальный первый PR, если правка точная.
Update local migrate command in README.
Что: в разделе «Local setup» команда миграций заменена на ту, что реально использует CI и Makefile. Добавил примечание про переменную DATABASE_URL для пустой локальной базы.
Зачем: по текущей инструкции сервис не поднимается на чистой машине. Сам упёрся в это в день 1.
Как проверить: пройти шаги README с нуля до make test на новой ветке. Главное: миграции применяются без ручного psql.
Риски: прод-документацию и runbook дежурства не трогал. Только local setup.
Такой PR не «мелкий». Он экономит следующий онбординг и показывает, что вы фиксируете трение, а не копите его в личных заметках.
Что проверять в diff до отправки
Откройте файлы изменений и пробегитесь по списку. Это быстрее, чем цикл «ревьюер нашёл мусор — вы извиняетесь».
- Нет файлов, которые вы не собирались менять. Если форматтер переписал чужой модуль — откатите и ограничьте форматтер своим куском, как принято в репо.
- Нет секретов, дампов, .env, персональных данных из локальной базы.
- Имена тестов и фикстур понятны без открытия файла.
- Комментарии в коде объясняют неочевидное «почему», а не пересказывают строку.
- Если меняли контракт API — обновили клиента, схему, пример в доке. Иначе это уже второй сюрприз для соседней команды.
Большой diff с пометкой «это в основном пробелы» всё равно большой. Ревьюер читает его как большой. Дробите или уберите шум.