Dev
June 12, 2020

Как сделать свой Pull Request

Minecraft.biz является проектом с открытым исходным кодом, это означает что каждый желающий может внести свои изменения в проекте на GitHub. Описываемый процесс является достаточно распространенным и вы сможете применять его за пределами нашего сообщества. Предполагается знание основ системы контроля версий Git (официальная русская документация). Вам также потребуется аккаунт на GitHub.

Краткое содержание процесса.

  1. Форкните проект.
  2. Склонируйте репозиторий.
  3. Создайте ветку для своей работы.
  4. Сделайте изменения в файлах. Закоммитьте их в только что созданную ветку.
  5. Убедитесь что проект работает после ваших изменений.
  6. Сделайте Pull Request.
  7. Обсудите его с рецензентом в процессе Code Review, при необходимости, внесите изменения в свой Pull Request.
  8. Когда все довольны, Pull Request принимают — с этого момента ваши изменения попали в исходный репозиторий (upstream) и являются частью проекта.

Теперь рассмотрим каждый этап подробнее.

Форкаем проект

Вы не можете отправлять коммиты (git push) напрямую в исходный репозиторий. По желанию хозяин проекта может это разрешить, но обычно доступ на запись есть только у людей, поддерживающих проект, а все остальные работают через Pull Request’ы («запросы на вливание изменений»; о них — ниже).

Поэтому мы форкаем проект — это создаст копию репозитория в вашем аккаунте. При этом у вас появится доступ на запись в вашу копию.

[фото репозитория]

Клонируем репозиторий

Затем нужно склонировать репозиторий на вашу локальную машину. Для этого нам нужен URL репозитория. Нажав на кнопку справа, вы скопируете его в буфер обмена.

смотрим каждый этап подробнее.

Форкаем проект

Вы не можете отправлять коммиты (git push) напрямую в исходный репозиторий. По желанию хозяин проекта может это разрешить, но обычно доступ на запись есть только у людей, поддерживающих проект, а все остальные работают через Pull Request’ы («запросы на вливание изменений»; о них — ниже).

Поэтому мы форкаем проект — это создаст копию репозитория в вашем аккаунте. При этом у вас появится доступ на запись в вашу копию.

Клонируем репозиторий

Затем нужно склонировать репозиторий на вашу локальную машину. Для этого нам нужен URL репозитория. Нажав на кнопку справа, вы скопируете его в буфер обмена.

Затем выполняем команду в терминале (или командной строке Windows):

git clone <URL>

Репозиторий склонируется в под-директорию текущей директории. Например, репозиторий проекта называется minecraft, у вас появится каталог minecraft.

Создаем ветку

Ветка по умолчанию — dev. Чтобы изменениями было проще управлять и они не смешивались друг с другом, создадим отдельную ветку, где и будем работать. При этом ветку стоит назвать так, чтобы имя говорило о её назначении.

Например, мы хотим исправить ошибку в реализации графического интерфейса лаунчера, так что наша ветка будет называться fix-launcher-gui.

Теперь заходим в наш склонированный репозиторий и создаём ветку:
Код:

cd foobar
git checkout -b fix-launcher-gui

Вторая команда создаст ветку и перейдёт на неё (сделает checkout).

Если после этого выполнить git status, он покажет
Код:

On branch fix-launcher-gui
nothing to commit, working directory clean

Эту команду стоит запомнить — когда не понимаете, в каком состоянии репозиторий, просто выполните её. Чаще всего в её выводе git покажет другие команды, которые делают то, что вы (скорее всего) и хотите сделать.

Вносим изменения

Теперь приступаем к работе. Редактируем код, обновляем документацию, чиним тесты, дополняем README.

Эти изменения мы коммитим в нашу ветку. Как это сделать — ниже.

При этом старайтесь делать коммиты часто, а сами коммиты — небольшими по объёму. Каждый коммит должен делать ровно одну вещь, и при этом поддерживать работоспособность проекта. Стремиться нужно к тому, чтобы в будущем можно было перейти на любой коммит и получить рабочий проект.

Если у вас сразу не получается придерживаться такой дисциплины, или изменения затрагивают весь проект «насквозь», допустимо ломать проект и постепенно чинить его в следующих коммитах.

Если вы уже достаточно разбираетесь в Git, такие не-атомарные изменения потом нужно объединить в один коммит с помощью interactive rebase и squash.

Итак, после редактирования файлов мы имеем следующую ситуацию (это вывод git status):
Код:

On branch fix-launcher-gui
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   launcher/src/main/java/biz/minecraft/launcher/Main.java

no changes added to commit (use "git add" and/or "git commit -a")

В выводе есть все необходимые вам команды:

  • git add <file>... добавляет файл в содержимое коммита, который вы собираетесь записать
  • git checkout -- <file>... откатывает ваши изменения файла

Поэтому делаем git add launcher/src/main/java/biz/minecraft/launcher/Main.java, а затем git commit -m "Сообщение коммита".

Сообщение коммита — это описание того, что вы сделали. Его читают другие участники проекта и рецензент. Поэтому оно должно быть осмысленным и читаемым.

Пример сообщения коммита, исправляющего неисправность связанную с графическим элементом Progress bar на ОС Windows:
Код:

Fix launcher progress bar width on Windows

Когда вы ввели сообщение коммита в редакторе, сохранили файл и закрыли его, можно выполнить git log и убедиться, что коммит записан в историю.

Проверяем изменения

Когда вы сделали правки, стоит их проверить — если только это не что-то абсолютно тривиальное.

Для этого нужно собрать проект и запустить тесты, если они есть. В любом случае стоит проверить работу кода, который вы написали или изменили, запустив программу. Смотрите по крайней мере на те места, которые вы правили.

Создаём Pull Request

Когда работа и проверка закончены, пора создавать Pull Request. Pull Request — это запрос на вливание изменений из вашей ветки в основную ветку исходного репозитория. Таким образом они попадут к хозяевам проекта.

Чтобы создать Pull Request, зайдём на страницу вашего форка. Справа от выпадающего меню с выбором ветки есть кнопка «New pull request».

Нажимаем её.

Вы попадаете в окно сравнения веток.

Элементы этого окна, по порядку:

  1. Базовый репозиторий, в который будет создаваться PR. Это должен быть репозиторий, от которого вы делали форк. Если вы форкнули проект scavver/minecraft, а ваше имя пользователя GitHub — user, то у вас будет проект user/minecraft.
  2. Базовая ветка в этом репозитории, обычно dev.
  3. Репозиторий, откуда должны вливаться изменения. Здесь должен быть выбран репозиторий в вашем аккаунте — user/minecraft.
  4. Ветка, откуда будут вливаться изменения. Это должна быть ветка, которую мы создали в разделе «Создаём ветку».

Дальше просмотрите изменения — то ли это, что вы делали? Если да, то нажимайте кнопку «Create pull request». В моём примере её нет, т. к. ветки в форке и в оригинале находятся в одинаковом состоянии. В вашем же случае внизу будет список коммитов, которые попадут в исходный репозиторий, и, на других вкладках — сами изменения и комментарии к изменениям.

После нажатия кнопки появится окно ввода сообщения Pull Request.

Сообщение PR — это описание того, что сделано и зачем. В отличие от сообщения коммита, здесь уже нужно писать высокоуровневое описание того, какие изменения сделаны. Короткий заголовок (Title), в Comment — описание, а затем служебная информация.

Затем нажимаем «Create pull request». Он создаётся, о нём приходит уведомление людям, поддерживающим проект, и он становится виден в исходном репозитории на вкладке «Pull requests». С этого момента начинается рецензирование изменений (code review).

Подсказка: если сразу после того, как вы отправили ветку в свой репозиторий (git push origin) зайти на страницу репозитория, там будет предложение создать Pull Request на вливание недавно отправленной ветки в dev. Сделать это можно как в вашем форке, так и в исходном репозитории. Это будет отдельная кнопка вверху, и при её нажатии в качестве ветки для слияния будет указана та, куда вы делали git push.

Участвуем в Code Review

На этом этапе люди, поддерживающие проект, смотрят на сделанный вами Pull Request и обсуждают его с вами. Возможно, какие-то вещи нужно будет исправить, улучшить, или доделать в процессе рецензирования — в этом нет ничего необычного, и это не значит что вы плохо поработали.

Со стороны автора Pull Request (а раз вы читаете это руководство, вы наверняка автор) требуется с пониманием относиться к комментариям рецензента — они направлены на повышение качества проекта. Если ошибка в сборке выявляется в процессе рецензирования, это гораздо лучше, чем если она попадёт в репозиторий, а следующий человек, который попытается поучаствовать в проекте, не сможет этого сделать из-за той самой ошибки. Да и это касается не только сборки, разумеется.

Также отмечу, что общаться в комментариях к PR следует вежливо и с уважением. Даже если вы общаетесь не с рецензентом. Не надо делать разнообразные далекоидущие выводы относительно пола, возраста, расы, интеллектуальных способностей и других черт человека. Если вы будете грубить рецензенту, в следующий раз он просто не захочет смотреть PR от вас. Не забывайте, что рецензирование — это тоже работа. Так что будьте добры и уважайте труд людей — они делают это бесплатно.

Когда этот этап завершается, рецензент нажимает кнопку «Merge Pull Request». Ваши изменения влиты в основной репозиторий проекта.

Поздравляем! Теперь вы полноправный участник проекта.

Завершение работы

После вливания PR нужно прибраться в репозитории. Если ваши изменения самодостаточны и после PR не требуется продолжать работу дальше, стоит удалить ветку. Как вы помните, мы создали её раньше, чтобы удобнее управлять изменениями.

Но сначала лучше обновить вашу локальную master-ветку — тогда git убедится, что ваша ветка уже влита в dev, и не будет предупреждать, что вы можете потерять свои изменения.

Итак, обновляем нашу локальную рабочую копию. Для этого добавим ещё один remote — так называется удалённый репозиторий. Сейчас он у вас только один — origin, и он указывает на ваш форк. Добавим remote с именем upstream, который будет указывать на исходный репозиторий:
Код:

git remote add upstream https://github.com/scavver/minecraft.git

URL в конце — это URL того репозитория, который вы форкнули. (На всякий случай — он написан в небольшом поле справа от переключателя «HTTPS-SSH», правее зелёной кнопки «New pull request».)

Добавив его, можно обновить наш локальный dev:
Код:

git checkout dev
git pull --rebase upstream/dev

А теперь можно удалить нашу ветку fix-launcher-gui локально:
Код:

git branch -d fix-launcher-gui

и на сервере:
Код:

git push --delete origin fix-launcher-gui

Теперь у нас чистый, обновлённый репозиторий. Можно начинать работу над новым PR.

Если у вас что-то не получилось сделать, или непонятно написано — пишите об этом на форум.

Если в какой-то момент возникают ошибки — сделайте git status. Очень часто git сам подсказывает, что можно сделать и как это сделать. Если всё равно не получилось — обращайтесь на форум, поможем.

Хороших вам коммитов, пусть проект собирается и тесты проходят. Присылайте ваши Pull Request’ы!