Git
Chapters ▾ 2nd Edition

6.2 GitHub - Внесение собственного вклада в проекты

Внесение собственного вклада в проекты

Теперь наша учетная запись создана и настроена, давайте же пройдемся по деталям, которые будут полезны при внесении вклада в уже существующие проекты.

Создание ответвлений (fork)

Если вы хотите вносить свой вклад в уже существующие проекты, в которых у нас нет прав на внесения изменений путем отправки (push) изменений, вы можете создать свое собственное ответвление (“fork”) проекта. Это означает, что GitHub создаст вашу собственную копию проекта, данная копия будет находиться в вашем пространстве имен и вы сможете легко делать изменения путем отправки (push) изменений.

Note

Исторически так сложилось, что англоязычный термин “fork” (создание ветвления проекта) имел негативный контекстный смысл, данный термин означал, что кто-то повел или ведет проект с открытым исходным кодом в другом, отличном от оригинала, направлении, иногда данный термин так же означал создание конкурирующего проекта с раздельными авторами. В контексте GitHub, “fork” (создание ветвления проекта) просто означает создание ветвления проекта в собственном пространстве имен, что позволяет вносить публичные изменения и делать свой собственный вклад в более открытом виде.

Таким образом, проекты не обеспокоены тем, чтобы пользователи, которые хотели бы выступать в роли соавторов, имели право на внесение изменений путем их отправки (push). Люди просто могут создавать свои собственные ветвления (fork), вносить туда изменения, а затем отправлять свои внесенные изменения в оригинальный репозиторий проекта путем создания запроса на принятие изменений (Pull Request), сами же запросы на принятие изменений (Pull Request) будут описаны далее. Запрос на принятие изменений (Pull Request) откроет новую ветвь с обсуждением отправляемого кода, и автор оригинального проекта, а так же другие его участники, могут принимать участие в обсуждения предлагаемых изменений до тех пор, пока автор проекта не будет ими доволен, после чего автор проекта может добавить предлагаемые изменения в проект.

Для того, чтобы создать ответвление проекта (fork), зайдите на страницу проекта и нажмите кнопку “Cоздать ответвление” (“Fork”), которая расположена в правом верхнем углу.

Кнопка ``Cоздать ответвление'' (``Fork'').
Рисунок 89. Кнопка “Cоздать ответвление” (“Fork”).

Через несколько секунд вы будете перенаправлены на собственную новую проектную страницу, содержащую вашу копию, в которой у вас есть права на запись.

Рабочий процесс с использованием GitHub

GitHub разработан с прицелом на определённый рабочий процесс с использованием запросов на слияния. Этот рабочий процесс хорошо подходит всем: и маленьким, сплочённым вокруг одного репозитория, командам; и крупным распределёным компаниям, и группам незнакомцев, сотрудничающих над проектом с сотней копий. Рабочий процесс GitHub основан на Тематические ветки, о которых мы Ветвление в Git.

Вот как это обычно работает:

  1. Создайте тематическую ветку от ветки master.

  2. Зафиксируйте несколько изменений, улучшающих проект.

  3. Отправьте эту ветку на GitHub.

  4. Откройте запрос на слияние на GitHub.

  5. Обсуждайте его, вносите изменения, если нужно.

  6. Владелец проекта принимает решение о принятии изменений, либо об их отклонении.

Очень напоминает подход, описанный в главе Рабочий процесс с менеджером по интеграции, но вместо использования электронной почты, команда сотрудничает через веб-интерфейс.

Давайте посмотрим, как можно предложить изменения в проект, размещённый на GitHub.

Создание запроса на слияние

Тони ищет, чего бы запустить на своём новеньком Arduino. Кажется, он нашёл классный пример на https://github.com/schacon/blink.

Проект над которым мы хотим поработать.
Рисунок 90. Проект над которым мы хотим поработать.

Единственная проблема в том, что светодиод моргает слишком быстро; нам кажется, лучше установить задержку в три секунды, не одну. Так давайте исправим это и предложим изменения автору.

Для начала, нажмите кнопку "Fork", как было сказано выше, чтобы заполучить собственную копию проекта. Мы зарегистрированы на GitHub под именем "tonychacon", так что наша копия окажется по адресу https://github.com/tonychacon/blink, где мы сможем редактировать её. Мы клонируем его, создадим тематическую ветку, внесём необходимые изменения и, наконец, отправим их на GitHub.

$ git clone https://github.com/tonychacon/blink (1)
Cloning into 'blink'...

$ cd blink
$ git checkout -b slow-blink (2)
Switched to a new branch 'slow-blink'

$ sed -i '' 's/1000/3000/' blink.ino (3)

$ git diff --word-diff (4)
diff --git a/blink.ino b/blink.ino
index 15b9911..a6cc5a5 100644
--- a/blink.ino
+++ b/blink.ino
@@ -18,7 +18,7 @@ void setup() {
// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  [-delay(1000);-]{+delay(3000);+}               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  [-delay(1000);-]{+delay(3000);+}               // wait for a second
}

$ git commit -a -m 'three seconds is better' (5)
[slow-blink 5ca509d] three seconds is better
 1 file changed, 2 insertions(+), 2 deletions(-)

$ git push origin slow-blink (6)
Username for 'https://github.com': tonychacon
Password for 'https://tonychacon@github.com':
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 340 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/tonychacon/blink
 * [new branch]      slow-blink -> slow-blink
  1. Клонируем нашу копию

  2. Создаём тематическую ветку

  3. Вносим свои изменения

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

  5. Фиксируем изменения в тематической ветку

  6. Отправляем новую ветку в нашу копию на GitHub

Теперь, если мы зайдём на страничку нашей копии на GitHub, мы увидим, что GitHub заметил наши изменения и предлагает открыть запрос на слияние с помощью большой зелёной кнопки.

Также можно зайти на страницу "Branches", по адресу https://github.com/<user>/<project>/branches, найти интересующую ветку и открыть запрос оттуда.

Кнопка открытия запроса на слияние
Рисунок 91. Кнопка открытия запроса на слияние

Если нажать на эту кнопку, появится экран ввода заголовка и описания предлагаемых изменений на рассмотрение владельцу проекта. Рекомендуется серъёзно подойти к составлению описания и сделать его максимально информативным, чтобы владелец проекта понимал, зачем эти изменения и какую пользу они принесут.

Также мы видим список коммитов в нашей тематической ветке, "опередивших" ветку master (в данном случае всего один коммит) и предпросмотр всех изменений, вносимых этими коммитами.

Создание запроса на слияние.
Рисунок 92. Страница создания запроса на слияние.

После создания запроса на слияние (путём нажатия кнопки "Create pull request" на этой странице) владелец форкнутого проекта получит уведомление о предложенных изменениях со ссылкой на страницу с информацией о запросе.

Note

Запросы на слияние широко используются для публичных проектов типа описанного выше, когда контрибьютор уже подготовил все изменения для слияния с основным репозиторием. Тем не менее, часто можно встретить использование запросов на слияние во внутренних проектах в самом начале цикла разработки. Обьяснение простое: вы можете обновлять тематическую ветку после открытия запроса на слияние, поэтому сам запрос открывается как можно раньше чтобы отслеживать прогресс разработки.

Обработка запроса на слияние

На этом этапе, владелец проекта может просмореть предложенные изменения, принять, отклонить или прокомментировать их. Предположим, ему импонирует идея, но он предпочёл бы большую задержку перед включением или выключением света.

В то время как в Распределенный Git обсуждение изменений может производится через электронную почту, на GitHub всё происходит онлайн. Владелец проекта может просмотреть суммарные изменения, вносимые запросом, и прокомментировать любую отдельно взятую строку.

Комментирование строки в запросе на слияние
Рисунок 93. Комментирование определённой строки в запросе на слияние

Как только владелец прокомментирует изменения, автор запроса на слияние (а также ве подписавшиеся на этот репозиторий) получат уведомления. Далее мы рассмотрим как настроить уведомления, но сейчас, если Тони включил уведомления через электронную почту, он получит следующее письмо:

Уведомление по электронной почте
Рисунок 94. Комментарии, отправленные по электронной почте

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

Страница обсуждения запроса на слияние
Рисунок 95. Страница обсуждения запроса на слияние

Теперь контрибьютор может видеть что ему необходимо сделать для того, чтобы его изменения были приняты. К счастью, это тоже легко сделать. Используя почту, вам потребуется заново отправить свои изменения в список рассылки, а при использовании GitHub вы просто делаете коммит в тематическую ветку и повторяете push.

Когда контрибьютор сделает это, владелец проекта снова получит уведомление, а на странице запроса будет отмечено, что проблема решена. Фактически, как только строка кода имеющая коментарий будет изменена, GitHub заметит это и удалит устаревшее отличие.

Финальная стадия запроса на слияние
Рисунок 96. Финальная стадия запроса на слияние

Примечательно, что если вы перейдёте на вкладку “Files Changed” в этом запросе на слияние, то увидите “унифицированную” разницу — это суммарные изменения, которые будут включены в освновную ветку при слиянии тематической ветки. В терминологии git diff это эквивалентно команде git diff master...<branch> для ветки, на котрой основан этот запрос на слияние. В Определение применяемых изменений детальнее описан данный тип отличий.

GitHub так же проверяет может ли запрос на слияние быть применен без конфликтов и предоставляет кнопку для осуществления слияния на сервере. Эта кнопка отображается только если у вас есть права на запись в репозиторий и возможно простейшее слияние. По нажатию на неё GitHub произведет “non-fast-forward” слияние, что значит даже если слияние может быть осуществлено перемоткой вперед, всё равно будет создан коммит слияния.

При желании, можно стянуть ветку и произвести слияние локально. Если эта ветка будет слита в master ветку и отправлена на сервер, то GitHub автоматически закроет запрос на слияние.

Это основной рабочий процесс, который используется большинством проектов на GitHub. Создаются тематические ветки, открываются запросы на слияние, производится обсуждение, при необходимости производятся доработки в ветке и, наконец, запрос либо закрывается, либо сливается.

Note
Не только ответвления

Важно отметить, что можно открывать запросы на слияние между двумя ветками в одном репозитории. Если вы работаете над функционалом с кем-то ещё и у вас обоих есть права записи, то вы можете отправить свою тематическиую ветку в репозиторий и открыть запрос на слияние в master ветку в рамках одного проекта, что позволит инициировать процедуру проверки кода и его обсуждения. Создание ответвлений проекта не является обязательным.

Продвинутые запросы на слияние

На текущий момент мы рассмотрели основы участия в проекте на GitHub, давайте рассмотрим некоторые интересные секреты и уловки касательно запросов слияния, чтобы вы могли более эффективно их использовать.

Запросы слияния как Патчи

Важно понимать, что многие проекты не воспринимают запросы слияния как очередь идеальных патчей, которые должны применяться аккуратно и по порядку, как и большинство проектов, участие в которых основывается на отправке набора патчей через списки почтовых рассылок. Большинство проектов на GitHub понимают ветки запросов слияние как беседу относительно предлагаемого изменения, завершающуюся слиянием унифицированных изменений.

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

Например, если вы вернетесь и посмотрите на Финальная стадия запроса на слияние, то увидите, что контрибьютер не делал перебазирование своего коммита и не отправлял новый запрос на слияние. Вместо этого были сделаны новые коммиты и отправлены в существующую ветку. Таким образом, если вы в будущем вернетесь к к этому запросу слияния, то легко найдёте весь контекст принятого решения. По нажатию кнопки “Merge” целенаправленно создаётся коммит слияния, который указывает на запрос слиния, оставляя возможность возврата к цепочке обсуждения.

Следование за исходным репозиторием

Если ваш запрос на слияние устарел или не может быть слит без конфликтов, то вам нужно изменить его, чтобы сопровождающий мог просто его слить. GitHub проверит это за вас и под каждым из запросов на слияние отобразит уведомление, можно ли его слить без конфликтов или нет.

PR merge failure
Рисунок 97. Запрос имеет конфликты слияния

Если вы видите что-то вроде Запрос имеет конфликты слияния, то вам следует изменить свою ветку так, чтобы исключить конфликты и сопровождающий не делал лишнюю работу.

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

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

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

Предположим, что в примере “tonychacon”, который мы использовали ранее, основной автор сделал изменения, которые конфликтуют с запросом на слияние. Рассмотрим это пошагово.

$ git remote add upstream https://github.com/schacon/blink (1)

$ git fetch upstream (2)
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
From https://github.com/schacon/blink
 * [new branch]      master     -> upstream/master

$ git merge upstream/master (3)
Auto-merging blink.ino
CONFLICT (content): Merge conflict in blink.ino
Automatic merge failed; fix conflicts and then commit the result.

$ vim blink.ino (4)
$ git add blink.ino
$ git commit
[slow-blink 3c8d735] Merge remote-tracking branch 'upstream/master' \
    into slower-blink

$ git push origin slow-blink (5)
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 682 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To https://github.com/tonychacon/blink
   ef4725c..3c8d735  slower-blink -> slow-blink
  1. Добавляем исходный репозиторий как удаленный с именем “upstream”

  2. Получаем последние изменения из него

  3. Сливаем основную ветку в нашу тематическую

  4. Исправляем указанный конфликт

  5. Отправляем изменения в ту же тематическую ветку

Как только это будет сделано, запрос на слияние будет автоматически обновлен и перепроверен на возможность слияния.

PR fixed
Рисунок 98. Запрос слияния без конфликтов

Одна из замечательных особенностей Git - это то, что вы можете делать это постоянно. Если у вас очень длительный проект, вы можете легко сливать изменения из целевой ветки снова и снова и иметь дело только с конфликтами, возникшими с момента вашего последнего слияния, что делает процесс очень управляемым.

Если вы очень хотите перебазровать ветку, чтобы её почистить, то, конечно, вы можете это сделать, но настоятельно не рекомендуется переписывать ветку, к которой уже открыт запрос на слияние. Если другие люди уже стянули её и проделали много работы, то вы столкнётесь со всеми проблемами, описанными в Опасности перемещения. Вместо этого, отправьте перебазированную ветку в новую на GiHub и откройте новый запрос на слияние, который указывает на предыдущий, затем закройте исходный.

Рекомендации

Возможно, ваш следующий вопрос будет “Как мне сослаться на предыдущий запрос слияния?”. Оказывается, существует много способов ссылаться на другие вещи практически везде, где у вас есть права записи на GitHub.

Давайте начнём с перекрестных ссылок для запросов слияния или проблем. Всем запросам слияния и проблемам присваиваются уникальные номера в пределах проекта. Например, у вас не может быть запроса на слияние с номером #3 и проблемы с номером #3. Если вы хотите сослаться на любой запрос слияния или проблему из другого места, просто добавьте #<num> в коментарий или описание. Так же можно указывать более конкретно, если проблема или запрос слияния находятя где-то ещё; пишите username#<num> если ссылаетесь на проблему или запрос слияния, находящиеся в ответвленном репозитории, или username/repo#<num> если ссылаетесь на другой репозиторий.

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

Перекрестные ссылки в запросе слияния
Рисунок 99. Перекрестные ссылки в запросе слияния.

Когда мы отправим запрос на слияние, то увидим что-то вроде Отображение перекрестных ссылок в запросе слияния..

Отображение перекрестных ссылок в запросе слияния
Рисунок 100. Отображение перекрестных ссылок в запросе слияния.

Заметьте, что указаная полная ссылка на GitHub была сокращена до необходимого минимума.

Если Тони сейчас вернется назад и закроет оригинальный запрос слияния, то мы это увидим, так как он упомянут в новом, а GtHub автоматически создаст отслеживающее событие в хронике запроса слияния. Это значит, что все, кто просматривает закрытый запрос слияния, могут легко перейти к запросу слияния, который его заменил. Ссылка будет выглядеть как указано на Отображение перекрестных ссылок в закрытом запросе слияния.

Отображение перекрестных ссылок в закрытом запросе слияния
Рисунок 101. Отображение перекрестных ссылок в закрытом запросе слияния

Кроме идентификационных номеров, можно ссылаться на конкретный коммит используя SHA-1. Следует указывать полный 40 символный хэш SHA-1, но если GitHub увидит его в коментарии, то автоматически подставит ссылку на коммит. Как было сказано выше, вы можете ссылаться на коммиты как в других, так и в ответвленных репозиториях точно так же как делали это с Проблемами.

Разметка

Ссылки на другие Проблемы — это лишь часть интереснейших вещей, которые вы можете делать в текстовых полях на GitHub. Для Проблемы или запроса слияния в полях описания, коментария, коментария кода и других вы можете использовать так называемую “Дополненную разметку GitHub”. Разметка похожа на обычный текст, который основательно преобразуется.

Смотрите Пример написания и отображения текста с разметкой. для примера как использовать разметку при написании коментариев и текста.

Пример разметки
Рисунок 102. Пример написания и отображения текста с разметкой.

Дополненная разметка GitHub

GitHub расширил возможности обычной разметки. Эти возможности могут быть очень полезными при создании запросов слияния или коментариев и описаний к проблемам.

Список задач

Список задач — это первая действительно важная возможность специфической разметки GitHub, особенно для запросов слияния. Список задач представляет собой список флажков для задач, которые вы хотите выполнить. Размещение его в описании Проблемы или запроса на слияние обычно указывает на то, что должно быть сделано до того, как проблема будет считаться решенной.

Список задач можно добавить следующим образом:

- [X] Write the code
- [ ] Write all the tests
- [ ] Document the code

Если добавить этот список в описание запроса на слияние или проблемы, то он будет отображен следующим образом Отображение списка задач в коментарии.

Пример списка задач
Рисунок 103. Отображение списка задач в коментарии.

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

Так же GitHub ищет списки задач в запросах на слияние и проблемах и отображает их как метаданные на страницах, где они упоминаются. Например, если в вашем запросе на слияние есть задачи и вы просматриваете список всех запросов, то можно увидеть на сколько готов каждый из них. Это позволяет разбивать запрос на слияние на несколько подзадач и помогает други людям отслеживать прогресс ветки. Пример приведен на Статистика задач в списке запросов слияния..

Пример списка задач
Рисунок 104. Статистика задач в списке запросов слияния.

Такая возможность невероятно полезна когда вы открываете запрос на слияние на раннем этапе реализации и отслеживаете прогресс с помощью него.

Отрывки кода

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

Для добавления отрывка кода следует обрамить его обратными кавычками.

```java
for(int i=0 ; i < 5 ; i++)
{
   System.out.println("i is : " + i);
}
```

Если вы укажите название языка, как показано на примере, GitHub попробует применить к нему подсветку синтаксиса. Для приведенного примера код будет выглядеть как на Отображение обрамленного кода..

Отображение обрамленного кода
Рисунок 105. Отображение обрамленного кода.
Цитирование

Если вы отвечаете только на часть большого коментария, то можно цитировать только выбранную часть, предваряя её символом >. Это на столько часто используется, что даже существует комбинация клавиш для этого. Если в коментарии выделить текст, на который вы собираетесь ответить, и нажать клавишу r, то выделенный текст будет включен как цитата в ваш коментарий.

Цитаты выглядят примерно так:

> Whether 'tis Nobler in the mind to suffer
> The Slings and Arrows of outrageous Fortune,

How big are these slings and in particular, these arrows?

После обработки коментарий будет выглядеть как Пример отображения цитаты..

Отображение цитаты
Рисунок 106. Пример отображения цитаты.
Смайлики

Наконец, вы можете использовать смайлики. На GitHub вы можете часто встретить их в коментариях или запросах на слияние. Для них есть даже помощник. Когда вы пишите коментарий и начинаете слов с символа :, то вам будут предложены варианты автодополнения.

Помощник по смайлам
Рисунок 107. Автодополнение для смайлов в действии.

Смайлы имеют вид :<name>: и могут располагаться в любом месте коментария. Например, вы можете написать что-нибудь вроде этого:

I :eyes: that :bug: and I :cold_sweat:.

:trophy: for :microscope: it.

:+1: and :sparkles: on this :ship:, it's :fire::poop:!

:clap::tada::panda_face:

Такой коментарий будет выглядеть как на Перегруженный смайликами коментарий..

Смайлики
Рисунок 108. Перегруженный смайликами коментарий.

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

Note

На текущий момент существует много интернет сервисов, где используются смайлики. Отличную шпаргалку по поиску смайликов, которые выражают нужную вам эмоцию, можно нйти здесь:

Картинки

Технически, картинки не относятся к разметке GitHub, но их использование очень полезно. В дополнение к ссылкам на картинки в коментариях, GitHub позволяет встраивать картинки в коментарии.

Перетаскивание картинки
Рисунок 109. Перетаскивание картинки для загрузки и встраивания.

Если вернуться немного назад к Перекрестные ссылки в запросе слияния., то над областью редактирования вы увидите небольшую подсказку “Parsed as Markdown”. Нажав не неё, вы получите полную подсказку по использованию GitHub разметки.