Урок 05 · Одно понятие
Ветка запушена и лежит на GitHub. В main при этом ничего не изменилось. Pull request — способ сказать вслух: «вот работа, посмотрите и решите, брать ли её».
Зачем это в твоей миссии
Это та самая точка, ради которой курс затевался. Три агента в трёх ветках заканчивают работу, и на GitHub появляются три PR. Всё, что было в предыдущих уроках, нужно для того, чтобы этот экран читался, а не пугал.
Ситуация после четвёртого урока. Агент сделал оплату картой в ветке feature/pay и запушил её. На GitHub ветка появилась. И дальше не происходит ничего: main прежний, сайт прежний, пользователи ничего не заметили.
Кто-то должен принять решение: брать эту работу в основную линию или нет. Способа два.
Первый — молча. Агент сливает ветку в main у себя на диске и пушит. Решение принято, но никто не видел, что именно вошло, и не осталось ни строчки о том, зачем. Через месяц в истории будет коммит «оплата», а что там внутри, вспоминать придётся заново.
Второй — вслух. Агент выкладывает предложение: «вот ветка, вот что в ней, влейте в main». Ты смотришь, спрашиваешь, просишь поправить, и только потом нажимаешь кнопку. Это и есть pull request.
Pull request — это заявка: «влейте ветку такую-то в ветку такую-то». К заявке прикладывается всё, что нужно для решения: список коммитов, разница в файлах, описание и место для обсуждения.
Важная деталь, которую редко проговаривают: в самом Git такого понятия нет. PR придумал GitHub как надстройку над ветками. Поэтому его нельзя сделать командой git: агент открывает PR либо через сайт, либо через отдельную утилиту GitHub под названием gh. Она умеет и создавать PR, и читать его, и вливать.
| Живёт в Git | Живёт на GitHub |
|---|---|
| коммит, ветка, слияние, история | PR, описание, обсуждение, ревью |
| есть у тебя на диске без сети | есть только на сайте |
управляется командами git | управляется сайтом или утилитой gh |
Отсюда прямое следствие, которое стыкуется с прошлым уроком: PR можно открыть только для ветки, которая уже на GitHub. Пока работа лежит локально, предлагать нечего.
Название сбивает с толку, и это стоит проговорить один раз, чтобы оно перестало мешать.
Родом оно из открытых проектов. Чужому человеку нельзя писать в главный репозиторий. Он делает себе копию, работает в ней и потом просит владельца: «забери мою ветку к себе». Забрать по-английски pull, просьба — request. Отсюда и «запрос на то, чтобы вы забрали».
Сейчас почти все PR открываются внутри одного репозитория, между своими же ветками, и слово «забрать» ничего не объясняет. GitLab честнее: у них та же вещь называется merge request, «запрос на слияние». В голове переводи именно так: PR — это предложение слияния.
Слева история из прошлых уроков. Справа то, что видно на странице GitHub. Стрелка ↑ у ветки означает, что она запушена.
Самое важное, что показывает демо, спрятано в четвёртом шаге. PR привязан к имени ветки, а не к набору коммитов. Всё, что после открытия PR запушат в эту ветку, попадёт в PR само.
Три следствия.
Правки не требуют нового PR. Ты оставил замечания, агент поправил и запушил в ту же ветку — PR обновился. Открывать второй незачем, а закрывать первый вредно: пропадёт обсуждение.
PR может меняться, пока ты его читаешь. Если агент продолжает работать в ветке, то, что ты видел пять минут назад, уже не совсем то, что вольётся. Поэтому агенту стоит сказать: «открыл PR — остановись, пока не посмотрю».
Из одной ветки в одну и ту же цель не бывает двух PR. Если хочется предложить две независимые вещи, это две ветки и два PR. Хорошее правило и для агентов: одна задача, одна ветка, один PR.
Страница на GitHub выглядит перегруженной, но по сути это четыре вкладки, и смотреть тебе нужно две из них.
| Вкладка | Что там | Зачем тебе |
|---|---|---|
| Conversation | описание от автора, обсуждение, итог: влит, закрыт или ждёт | читать первой. Если описания нет, это уже замечание |
| Commits | список коммитов ветки по порядку | увидеть, как шла работа. Тридцать коммитов «fix» — повод спросить |
| Checks | автоматические проверки, если настроены | пока пропускать. Появятся в уроках про практику |
| Files changed | разница в файлах: что добавлено, что убрано | читать второй. Здесь принимается решение |
Ещё одно состояние, которое стоит знать: черновик (draft). Такой PR открыт, его можно читать и обсуждать, но кнопка слияния заблокирована. Это способ сказать «я ещё не закончил, не вливайте». Для агентов удобный режим: пусть открывают черновик рано, а в готовый переводят, когда закончат.
Вкладка Files changed показывает diff — разницу между веткой и целью. Зелёные строки добавлены, красные убраны. Изменённая строка выглядит как красная и зелёная рядом: старую убрали, новую положили.
Ты не пишешь код, и читать его построчно тебе не нужно. Нужно другое: проверить, что тронуто ровно то, что было в задаче. Для этого достаточно четырёх взглядов.
pnpm-lock.yaml и подобные дают тысячи строк, GitHub их сворачивает сам. Не разворачивай, но заметь: если замок изменился, значит, менялись зависимости, и это отдельный вопрос.Если запомнить одно
Ты смотришь не код, а границы. Совпадает ли то, что изменено, с тем, что просили. Всё, что внутри границ, можно попросить агента объяснить словами. Всё, что за границами, — повод остановиться.
Нажатие кнопки на GitHub делает то же, что слияние в уроке про ветки, только на сервере: в main появляется новый коммит, у которого два родителя. Ветка после этого не нужна, и GitHub сразу предлагает её удалить. Соглашайся: история никуда не денется, а мусор в списке веток копится быстро.
Рядом с кнопкой есть выбор из трёх способов слияния. Это отдельная тема, ей посвящён урок про merge и rebase. Пока оставляй тот, что стоит по умолчанию.
И одно напоминание из прошлого урока, на котором ловятся все: слияние произошло на GitHub. Твой локальный main ничего об этом не знает и покажет старую версию, пока ты не сделаешь pull.
Если PR решено не брать, его закрывают без слияния. Ветка при этом остаётся, обсуждение остаётся, и через месяц к нему можно вернуться.
Работа закончена
Открой PR из feature/pay в main. В описании: что сделано, что не сделано, как проверить руками. Не вливай, я посмотрю сам.
Три пункта в описании — это то, чего агент сам не напишет, а тебе для решения нужно именно это. Последняя фраза удерживает его от кнопки.
Приёмка
Расскажи по файлам, что изменено в этом PR и зачем. Отдельно перечисли всё, чего не было в задаче.
Вторая фраза заставляет агента самому провести границу. Обычно именно там всплывает «попутно я ещё переделал…».
Нужны правки
Замечания в PR — поправь и запушь в ту же ветку. Новый PR не открывай, этот не закрывай.
PR обновится сам. Без явного указания агент может закрыть текущий и открыть новый, и обсуждение разъедется по двум местам.
Решение принято
Влей PR способом по умолчанию, ветку удали, потом обнови мой локальный main.
Три действия, каждое названо. Последнее — то, о котором забывают: без него у тебя на диске старая версия.
Чего просить не стоит
Слово «смёржи» без уточнений. Агент может влить ветку у себя на диске и запушить main напрямую, минуя PR. Формально просьба выполнена, а просмотра не было. Говори «через PR» или «открой PR и остановись».
Формулировка для правил проекта
Вторая строчка в CLAUDE.md, рядом с запретом force: «В main попадают только через PR. Прямой push в main запрещён». На GitHub это же правило можно сделать железным в настройках репозитория, раздел Branch protection: тогда прямой push в main отвергнет сам сервер, что бы агент ни думал.
Первоисточники к этому уроку
GitHub Docs → О запросах на вытягивание — официальное описание, на русском. Термин там переведён именно так, не пугайся.
GitHub Docs → Просмотр предлагаемых изменений — как читать Files changed и оставлять замечания к строкам.
Справка gh pr create — та самая утилита, которой агент открывает PR из терминала. Достаточно знать, что она есть.