Работа с Git и GitHub¶
В этом разделе объясняется, как сообщество может добавлять код в Django с помощью запросов на включение. Если вас интересует, как слияния <mergers-team>` обрабатывают, см. Работа с запросами на принятие изменений (Pull requests, пул-реквесты).
Ниже мы покажем, как создать запрос на принятие изменений в GitHub, содержащий изменения для тикета Trac #xxxxx. Создав полностью готовый запрос на включение изменений, вы облегчите работу рецензента, а это значит, что ваша работа с большей вероятностью будет включена в Django.
Вы также можете загрузить традиционный патч в Trac, но это менее практично для проверки.
Установка Git¶
Django использует Git для управления исходным кодом. Вы можете скачать Git, но часто проще установить его с помощью менеджера пакетов вашей операционной системы.
Репозиторий Git Django размещен на GitHub, и рекомендуется также работать с GitHub.
После установки Git первое, что вам следует сделать, это указать свое имя и адрес электронной почты:
$ git config --global user.name "Your Real Name"
$ git config --global user.email "you@email.com"
Обратите внимание, что user.name должно быть вашим настоящим именем, а не вашим ником GitHub. GitHub должен знать адрес электронной почты, который вы используете в поле user.email, поскольку он будет использоваться для связывания ваших коммитов с вашей учетной записью GitHub.
Настройка локального репозитория¶
Когда вы создали свою учетную запись GitHub с ником «GitHub_nick», и сделали форк репозитория Django, создайте локальную копию вашей форкнутой копии:
git clone https://github.com/GitHub_nick/django.git
Это создаст новый каталог «django», содержащий клон вашего репозитория GitHub. Остальные команды git на этой странице должны быть запущены внутри клонированного каталога, поэтому переключитесь на него сейчас:
cd django
Ваш репозиторий GitHub будет называться в Git «origin».
Вам также следует настроить django/django как «upstream» remote (то есть, сообщить git, что репозиторий Django был источником вашего форка его):
git remote add upstream https://github.com/django/django.git
git fetch upstream
Аналогичным образом можно добавить и другие удаленные репозитории, например:
git remote add akaariai https://github.com/akaariai/django.git
Работа над тикетом¶
Работая над тикетом, создайте новую ветку для работы и разместите ее на upstream/main:
git checkout -b ticket_xxxxx upstream/main
Флаг -b создает для вас новую ветку локально. Не стесняйтесь создавать новые ветки даже для самых незначительных вещей — для этого они и нужны.
Если бы вместо этого вы работали над исправлением ветки 1.4, вы бы сделали следующее:
git checkout -b ticket_xxxxx_1_4 upstream/stable/1.4.x
Предположим, что работа ведется в ветке ticket_xxxxx. Внесите изменения и зафиксируйте их:
git commit
При написании сообщения о коммите следуйте руководству по написанию сообщения о коммите, чтобы облегчить работу мерджеру. Если вам неудобен английский, попробуйте хотя бы точно описать, что делает коммит.
Если вам нужно выполнить дополнительную работу в вашей ветке, фиксируйте изменения так часто, как необходимо:
git commit -m 'Added two more tests for edge cases'
Публикация работы¶
Вы можете опубликовать свою работу на GitHub, выполнив:
git push origin ticket_xxxxx
Когда вы перейдете на свою страницу GitHub, вы увидите, что была создана новая ветка.
Если вы работаете над тикетом Trac, вам следует указать в тикете, что ваша работа доступна из ветки ticket_xxxxx вашего репозитория GitHub. Включите ссылку на вашу ветку.
Обратите внимание, что указанная выше ветка называется «topic branch» («тематическая ветка») в терминологии Git. Вы можете свободно переписывать историю этой ветки, используя git rebase для примера. Другие люди не должны основывать свою работу на такой ветке, потому что их клон будет поврежден, когда вы редактируете коммиты.
Также существуют «public branches» («публичные ветки»). Это ветки, которые другие люди должны форкать, поэтому история этих веток никогда не должна меняться. Хорошими примерами публичных веток являются ветки main и stable/A.B.x в репозитории django/django.
Когда вы считаете, что ваша работа готова к загрузке в Django, вам следует создать запрос на принятие изменений на GitHub. Хороший запрос на принятие изменений означает:
фиксирует по одному логическому изменению в каждом, следуя стилю кодирования,
правильно сформированные сообщения для каждого коммита: строка саммари, а затем абзацы со строками длиной не более 72 символов – см. руководства по коммиту для получения более подробной информации,
документация и тесты, если нужны – на самом деле тесты всегда нужны, за исключением изменений в документации.
Набор тестов должен быть пройден, а документация должна быть собрана без предупреждений.
После создания запроса на принятие изменений вам следует добавить комментарий в соответствующий тикет Trac, описывающий, что вы сделали. В частности, вам следует отметить среду, в которой вы запускали тесты, например: «все тесты проходят под SQLite и MySQL».
Запросы на принятие изменений в GitHub имеют только два состояния: открытое и закрытое. У того, кто будет заниматься вашим запросом на включение изменений, есть только два варианта: слить его или закрыть его. По этой причине бесполезно делать запрос на включение изменений, пока код не будет готов к объединению — или достаточно близок к тому, чтобы слияние само его завершило.
Перебазирование веток¶
В примере выше вы создали два коммита: коммит «Fixed ticket_xxxxx» и коммит «Added two more tests».
Мы не хотим хранить всю историю вашего рабочего процесса в вашем репозитории. Ваш коммит «Added two more tests» будет бесполезным шумом. Вместо этого мы бы предпочли иметь только один коммит, содержащий всю вашу работу.
Чтобы переработать историю вашей ветки, вы можете объединить коммиты в один, используя интерактивное перебазирование (interactive rebase):
git rebase -i HEAD~2
HEAD~2 выше — это сокращение для двух последних коммитов. Команда выше откроет редактор, показывающий два коммита, с префиксом «pick».
Измените «pick» во второй строке на «squash». Это сохранит первый коммит и сожмет второй коммит в первый. Сохраните и выйдите из редактора. Должно открыться второе окно редактора, так что вы можете перефразировать сообщение для коммита, теперь, когда оно включает оба ваших шага.
Вы также можете использовать опцию «edit» в rebase. Таким образом вы можете изменить отдельный коммит, например, чтобы исправить опечатку в строке документации:
git rebase -i HEAD~3
# Choose edit, pick, pick for the commits
# Now you are able to rework the commit (use git add normally to add changes)
# When finished, commit work with "--amend" and continue
git commit --amend
# Reword the commit message if needed
git rebase --continue
# The second and third commits should be applied.
Если ваша тематическая ветка уже опубликована на GitHub, например, если вы вносите незначительные изменения, чтобы учесть отзыв, вам нужно будет принудительноотправить изменения:
git push -f origin ticket_xxxxx
Обратите внимание, что это приведет к переписыванию истории ticket_xxxxx - если вы проверите хэши коммитов до и после операции на GitHub, вы заметите, что хэши коммитов больше не совпадают. Это приемлемо, поскольку ветка является тематической веткой, и никто не должен основывать свою работу на ней.
После того, как удаленная ветка изменилась¶
Когда удаленная ветка (django/django) изменилась, вам следует перебазировать свою работу. Чтобы сделать это, запустите:
git fetch upstream
git rebase upstream/main
Работа автоматически перебазируется с использованием ветки, на которой вы делали форк, в примере с использованием upstream/main.
Команда rebase временно удаляет все ваши локальные коммиты, применяет вышестоящие коммиты, а затем снова применяет ваши локальные коммиты.
Если возникнут конфликты слияния, вам нужно будет разрешить их, а затем использовать git rebase --continue. В любой момент вы можете использовать git rebase --abort чтобы вернуться в исходное состояние.
Обратите внимание, что вы хотите перебазировать по удаленной ветке, а не замерджить в нее.
Причина этого в том, что при перебазировании ваши коммиты всегда будут поверх работы вышестоящего звена, а не смешаны с изменениями в вышестоящем звене. Таким образом, ваша ветка будет содержать только коммиты, относящиеся к ее теме, что упростит склеивание.
После проверки¶
Не стоит вносить в ядро большой объем кода без обсуждения с рецензентами.В этом случае часто бывает хорошей идеей добавить изменения в виде одного коммита в вашу работу. Это позволяет рецензенту легко проверить, какие изменения вы внесли.
В этом случае внесите изменения, требуемые рецензентом. Делайте коммиты так часто, как необходимо. Перед публикацией изменений перебазируйте свою работу. Если вы добавили два коммита, вы должны выполнить:
git rebase -i HEAD~2
Склейте второй коммит с первым. Напишите сообщение коммита в соответствии со строками:
Made changes asked in review by <reviewer>
- Fixed whitespace errors in foobar
- Reworded the docstring of bar()
Наконец, отправьте свою работу обратно в репозиторий GitHub. Поскольку вы не трогали публичные коммиты во время перемещения, вам не нужно принудительно отправлять (с использованием force):
git push origin ticket_xxxxx
Теперь ваш запрос на принятие также должен содержать новый коммит.
Обратите внимание, что мерджер, скорее всего, склеит ревью коммит с предыдущим коммитом.
Работа над патчем¶
Один из способов, с помощью которого разработчики могут внести свой вклад в Django, — это просмотр патчей. Эти патчи обычно существуют в виде пул реквестов на GitHub и могут быть легко интегрированы в ваш локальный репозиторий:
git checkout -b pull_xxxxx upstream/main
curl -L https://github.com/django/django/pull/xxxxx.patch | git am
Это создаст новую ветку, а затем применит к ней изменения из запроса на принятие. На этом этапе вы можете запустить тесты или сделать что-нибудь еще, что вам нужно сделать для исследования качества патча.
Более подробную информацию о работе с запросами на принятие см. в руководстве по слияниям.
Краткое содержание¶
Если можете, работайте на GitHub.
Анонсируйте свою работу над тикетом Trac, указав ссылку на свою ветку GitHub.
Когда у вас что-то будет готово, сделайте запрос на принятие.
Сделайте ваши запросы на принятие внесенных изменений как можно более качественными.
При внесении исправлений в свою работу используйте
git rebase -i, чтобы склеить коммиты.Если upstream изменился, выполните
git fetch upstream; git rebase.