Работа с Git и GitHub

This section explains how the community can contribute code to Django via pull requests. If you’re interested in how mergers handle them, see Коммиттинг кода.

Ниже мы покажем, как создать на GitHub pull request, содержащий изменения для Trac ticket #xxxxx. Создав полностью готовый запрос, вы облегчите работу рецензента, а это значит, что ваша работа с большей вероятностью будет внесена в Django.

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

Установка Git

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

Django Git repository размещен на GitHub, и рекомендуется также работать с помощью GitHub.

After installing Git, the first thing you should do is set up your name and email:

$ git config --global user.name "Your Real Name"
$ git config --global user.email "you@email.com"

Обратите внимание, что user.name должно быть вашим настоящим именем, а не ником на GitHub. GitHub должен знать email, который вы используете в поле user.email, поскольку он будет использоваться для привязки ваших коммитов к вашей учетной записи GitHub.

Настройка локального репозитория

После создания учетной записи GitHub с ником «GitHub_nick» и forked Django’s repository, создайте локальную копию вашего форка:

git clone https://github.com/GitHub_nick/django.git

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

cd django

Ваш репозиторий GitHub будет называться в Git «origin».

You should also set up django/django as an «upstream» remote (that is, tell git that the reference Django repository was the source of your fork of it):

git remote add upstream https://github.com/django/django.git
git fetch upstream

Аналогичным образом можно добавить другие пульты, например:

git remote add akaariai https://github.com/akaariai/django.git

Работа над билетом

When working on a ticket, create a new branch for the work, and base that work on 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

When writing the commit message, follow the commit message guidelines to ease the work of the merger. If you’re uncomfortable with English, try at least to describe precisely what the commit does.

Если вам нужно выполнить дополнительную работу над вашей веткой, делайте коммит так часто, как это необходимо:

git commit -m 'Added two more tests for edge cases'

Издательская деятельность

Вы можете опубликовать свою работу на GitHub, выполнив:

git push origin ticket_xxxxx

Когда вы зайдете на свою страницу GitHub, вы заметите, что была создана новая ветка.

Если вы работаете над тикетом Trac, вам следует указать в тикете, что ваша работа доступна из ветки ticket_xxxxx вашего репозитория на GitHub. Включите ссылку на вашу ветку.

Обратите внимание, что в языке Git вышеупомянутая ветка называется «ветка темы». Вы можете свободно переписывать историю этой ветки, используя, например, git rebase. Другие люди не должны основывать свою работу на такой ветке, потому что их клон будет поврежден, когда вы будете редактировать коммиты.

There are also «public branches». These are branches other people are supposed to fork, so the history of these branches should never change. Good examples of public branches are the main and stable/A.B.x branches in the django/django repository.

Когда вы считаете, что ваша работа готова к внедрению в Django, вы должны создать запрос на исправление на GitHub. Хорошая заявка означает:

  • коммитов с одним логическим изменением в каждом, следующим за coding style,
  • хорошо сформированные сообщения для каждого коммита: итоговая строка и затем абзацы, обернутые в 72 символа - см. committing guidelines для более подробной информации,
  • документация и тесты, если необходимо - на самом деле тесты нужны всегда, за исключением изменений в документации.

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

После того, как вы создали свой pull request, вы должны добавить комментарий в соответствующий тикет Trac, объясняющий, что вы сделали. В частности, вам следует указать среду, в которой вы проводили тесты, например: «все тесты прошли под SQLite и MySQL».

Pull requests at GitHub have only two states: open and closed. The merger who will deal with your pull request has only two options: merge it or close it. For this reason, it isn’t useful to make a pull request until the code is ready for merging – or sufficiently close that a merger will finish it themselves.

Перераспределение ветвей

В приведенном выше примере вы создали два коммита, коммит «Fixed ticket_xxxxx» и коммит «Added two more tests».

Мы не хотим иметь всю историю вашего рабочего процесса в вашем репозитории. Ваш коммит «Добавил еще два теста» будет бесполезным шумом. Вместо этого мы бы предпочли иметь только один коммит, содержащий всю вашу работу.

Чтобы переработать историю вашей ветки, вы можете объединить все коммиты в один с помощью интерактивного rebase:

git rebase -i HEAD~2

HEAD~2 выше - это сокращение для двух последних коммитов. Приведенная выше команда откроет редактор, показывающий эти два коммита с префиксом «pick».

Измените «pick» во второй строке на «squash». Это сохранит первый коммит, а второй коммит будет втиснут в первый. Сохраните и выйдите из редактора. Откроется второе окно редактора, и вы сможете переформулировать сообщение о фиксации, теперь оно включает оба ваших шага.

Вы также можете использовать опцию «edit» в rebase. Так вы можете изменить один коммит, например, исправить опечатку в docstring:

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

The work is automatically rebased using the branch you forked on, in the example case using upstream/main.

Команда rebase временно удаляет все ваши локальные исправления, применяет исправления из восходящего потока, а затем снова применяет ваши локальные исправления в работе.

Если существуют конфликты слияния, вам нужно будет разрешить их, а затем использовать git rebase --continue. В любой момент вы можете использовать git rebase --abort для возврата к исходному состоянию.

Обратите внимание, что вы хотите базироваться на upstream, а не сливаться с upstream.

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

После рассмотрения

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

В этом случае внесите изменения, требуемые рецензентом. Выполняйте коммит так часто, как это необходимо. Перед публикацией изменений перебазируйте свою работу. Если вы добавили два коммита, вы выполните:

git rebase -i HEAD~2

Втисните второй коммит в первый. Напишите сообщение о фиксации следующего содержания:

Made changes asked in review by <reviewer>

- Fixed whitespace errors in foobar
- Reworded the docstring of bar()

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

git push origin ticket_xxxxx

Теперь ваш запрос на исправление должен содержать и новый коммит.

Note that the merger is likely to squash the review commit into the previous commit when committing the code.

Работа над патчем

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

git checkout -b pull_xxxxx upstream/main
curl -L https://github.com/django/django/pull/xxxxx.patch | git am

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

For more detail on working with pull requests see the guidelines for mergers.

Резюме

  • Работайте на GitHub, если можете.
  • Объявите о своей работе в тикете Trac, указав ссылку на свою ветку GitHub.
  • Когда у вас будет что-то готово, сделайте запрос на выгрузку.
  • Делайте свои запросы на исправление ошибок как можно лучше.
  • При внесении исправлений в свою работу используйте git rebase -i для сглаживания коммитов.
  • Если восходящий поток изменился, сделайте git fetch upstream; git rebase.
Вернуться на верх