GitHub — Примеры

Пример 1 — Пуш, перезаписывающий опубликованную историю

Разработчик приводит коммиты в порядок, пересобирая основную линию локально, и потом отправляет её. Копия товарища по команде теперь расходится с удалённым репозиторием. Покажите, что сделал пуш, затем — как опубликовать аккуратную историю, не перезаписывая то, что у других уже есть.

git log --oneline origin/main..main   # что добавляет мой локальный main
git push --force origin main          # заменяет опубликованную ссылку
# товарищ: git pull -> "diverged" и задвоенный коммит

Решение

git fetch origin
git rebase origin/main                # переиграть мои коммиты поверх их
git push origin main                  # fast-forward, ничто не заменяется
# вместо этого для новой работы: пуш ветки и pull request
git push -u origin fix/142-coupon

Удалённый репозиторий хранит те же объекты, что и локальный, поэтому force-push не добавляет один новый коммит. Он выбрасывает ссылку, на которой держались все остальные, и направляет её в другое место. Переписывать собственные коммиты, ещё никому не отправленные, безвредно, а вот переписывание ссылки, которую другие уже забрали, обходится им в ручное восстановление. Отсюда и правило, которое применяет пример: порядок наводите в приватной копии, rebase делайте поверх опубликованного, а всё, что меняет опубликованную историю, проводите через pull request — там изменение видно.

Пример 2 — Pull request на шестьдесят файлов

Ветка накопила три несвязанных изменения за две недели. В pull request’е шестьдесят изменённых файлов; первый рецензент оставляет комментарий про форматирование и останавливается. Улучшите ревью, не меняя то, что поставляется.

git switch -c feat/dashboard   # ответвлена две недели назад
git push -u origin feat/dashboard
# хостинг: pull request в main, 60 изменённых файлов, задача не связана

Решение

git switch -c feat/dashboard-layout main        # одна забота на ветку
git switch -c fix/142-expired-coupon main
git switch -c chore/upgrade-linter main
git push -u origin fix/142-expired-coupon
# хостинг: открыть pull request, тело "Closes #142", нужно одно одобрение

Дифф, обсуждение и решение живут в pull request’е, поэтому размер его определяет качество ревью, а не остаётся деталью git. Три маленьких pull request’а читаются за минуты, каждый ссылается на задачу, объясняющую, зачем изменение существует, и каждый можно слить, не таща за собой два других. Разделение кладёт рассуждение туда, где сопровождающий найдёт его позже, ведь приватный разговор о дизайне не оставляет в репозитории ничего. А привычку к маленькому диффу делает обеспеченной принудительно, а не просто желательной, защищённая основная ветка.