Коммит кода¶
This section is addressed to the committers and to anyone interested in knowing how code gets committed into Django. If you’re a community member who wants to contribute code to Django, look at Работа с Git и GitHub instead.
Работа с запросами на принятие изменений (Pull requests, пул-реквесты)¶
Поскольку Django размещен на GitHub, исправления предоставляются в форме пул-реквестов.
When committing a pull request, make sure each individual commit matches the commit guidelines described below. Contributors are expected to provide the best pull requests possible. In practice however, committers - who will likely be more familiar with the commit guidelines - may decide to bring a commit up to standard themselves.
You may want to have Jenkins test the pull request with one of the pull request builders that doesn’t run automatically, such as Oracle or Selenium. See the Jenkins wiki page for instructions.
If you find yourself checking out pull requests locally more often, this git alias will be helpful:
[alias]
pr = !sh -c \"git fetch upstream pull/${1}/head:pr/${1} && git checkout pr/${1}\"
Добавьте его в свой ~/.gitconfig и установите upstream на django/django. Затем вы можете запустить git pr ####, чтобы переключиться на соответствующий pull request.
Теперь вы можете работать над кодом. Используйте git rebase -i и git commit --amend, чтобы убедиться, что коммиты имеют ожидаемый уровень качества. Когда вы будете готовы:
$ # Pull in the latest changes from master.
$ git checkout master
$ git pull upstream master
$ # Rebase the pull request on master.
$ git checkout pr/####
$ git rebase master
$ git checkout master
$ # Merge the work as "fast-forward" to master to avoid a merge commit.
$ # (in practice, you can omit "--ff-only" since you just rebased)
$ git merge --ff-only pr/XXXX
$ # If you're not sure if you did things correctly, check that only the
$ # changes you expect will be pushed to upstream.
$ git push --dry-run upstream master
$ # Push!
$ git push upstream master
$ # Delete the pull request branch.
$ git branch -d pr/xxxx
...\> REM Pull in the latest changes from master.
...\> git checkout master
...\> git pull upstream master
...\> REM Rebase the pull request on master.
...\> git checkout pr/####
...\> git rebase master
...\> git checkout master
...\> REM Merge the work as "fast-forward" to master to avoid a merge commit.
...\> REM (in practice, you can omit "--ff-only" since you just rebased)
...\> git merge --ff-only pr/XXXX
...\> REM If you're not sure if you did things correctly, check that only the
...\> REM changes you expect will be pushed to upstream.
...\> git push --dry-run upstream master
...\> REM Push!
...\> git push upstream master
...\> REM Delete the pull request branch.
...\> git branch -d pr/xxxx
Force push to the branch after rebasing on master but before merging and pushing to upstream. This allows the commit hashes on master and the branch to match which automatically closes the pull request.
Если не нужно объединять несколько разных коммитов в пул-реквесте, вы можете использовать кнопку GitHub «Squash and merge» на веб-сайте. Отредактируйте сообщение о коммите, как необходимо, чтобы соответствовать руководствам и удалите номер пул-реквеста, который автоматически добавляется к первой строке сообщения.
При переписывании истории коммитов запроса на извлечение цель состоит в том, чтобы сделать историю коммитов Django максимально пригодной для использования:
Если патч содержит несколько коммитов, которое логически могут быть объединены, то перепишите их в один. Например, если коммит добавляет некоторый код, а второй коммит исправляет стилистические проблемы, возникшие в первом коммите, эти коммиты следует объединить перед слиянием.
Разделяйте изменения в разные коммиты с помощью логической группировки: если вы выполняете чистку кода одновременно с другими изменениями в файле, разделение изменений на два разных коммита. Это упростит просмотр истории.
Следите, чтобы в вашем пул-реквесте не было слияний с remote ветками
Тесты должны проходить успешно, а документация должна собираться после каждого коммита. Ни тесты, ни документация не должны выдавать предупреждения.
Тривиальные и небольшие патчи обычно лучше всего выполнять в одном коммите. Среднюю и большую работу можно разделить на несколько коммитов, если это имеет смысл.
Practicality beats purity, so it is up to each committer to decide how much history mangling to do for a pull request. The main points are engaging the community, getting work done, and having a usable commit history.
Инструкция по коммиту кода¶
При передаче кода в репозиторий Git Django следуйте следующим рекомендациям:
Никогда не изменяйте опубликованную историю веток
django/django. Если вам это абсолютно необходимо (например, по соображениям безопасности), сначала обсудите ситуацию с командой.For any medium-to-big changes, where «medium-to-big» is according to your judgment, please bring things up on the django-developers mailing list before making the change.
If you bring something up on django-developers and nobody responds, please don’t take that to mean your idea is great and should be implemented immediately because nobody contested it. Everyone doesn’t always have a lot of time to read mailing list discussions immediately, so you may have to wait a couple of days before getting a response.
Пишите подробные сообщения о коммитах в прошедшем времени, а не в настоящем.
Хорошо: «Исправлена ошибка Unicode в RSS API».
Плохо: «Исправляет ошибку Unicode в RSS API».
Плохо: «Исправление ошибки Unicode в RSS API».
Сообщение о коммите должно быть в строках длиной максимум 72 символа. Должна быть тема сообщения, разделенная пустой строкой, а затем абзацы по 72 символа. Ограничения мягкие. Для строки темы лучше сделать ее короче. В теле сообщения о коммите предоставьте как можно больше подробностей:
Fixed #18307 -- Added git workflow guidelines. Refactored the Django's documentation to remove mentions of SVN specific tasks. Added guidelines of how to use Git, GitHub, and how to use pull request together with Trac instead.
Укажите авторов в сообщении о коммите: «Спасибо A за отчет и B за рецензию.» Используйте Co-Authored-By в git по мере необходимости»
Для коммитов в ветку добавьте к сообщению коммита префикс в виде имени ветки. Например: «[1.4.x] Исправлен #xxxxx – Добавлена поддержка чтения мыслей.»
Ограничьте коммиты наиболее мелкими изменениями, которые имеют смысл. Это означает, что используйте частые небольшие коммиты вместо нечастых крупных коммитов. Например, если реализация функции X требует небольшого изменения в библиотеке Y, сначала зафиксируйте изменение в библиотеке Y, а затем зафиксируйте функцию X в отдельном коммите. Это очень помогает всем следить за вашими изменениями.
Отделите исправления ошибок от изменений функций. Исправления ошибок могут потребовать обратного переноса в стабильную ветку в соответствии с Поддерживаемые версии.
Если ваш коммит закрывает тикет в тикет трекере Django, начните свое сообщение о коммите с текста «Исправлено #xxxxx», где «xxxxx» — это номер тикета, который ваш коммит исправляет. Пример: «Исправлено #123 — Добавлена крутая функция.». Мы настроили Trac так, что любое сообщение о коммите в этом формате будет автоматически закрывать указанный тикет и публиковать к нему комментарий с полным сообщением о коммите.
Для любопытных: для этого мы используем Trac-плагин.
Примечание
Note that the Trac integration doesn’t know anything about pull requests. So if you try to close a pull request with the phrase «closes #400» in your commit message, GitHub will close the pull request, but the Trac plugin will also close the same numbered ticket in Trac.
Если ваш коммит ссылается на тикет в тикет-трекере Django, но не закрывает тикет, включите фразу «Refs #xxxxx», где «xxxxx» — это номер тикета, на который ссылается ваш коммит. Это автоматически опубликует комментарий к соответствующему тикету.
Пишите сообщения о коммитах для бэкпортов, используя следующий шаблон:
[<Django version>] Fixed <ticket> -- <description> Backport of <revision> from <branch>.
Например:
[1.3.x] Fixed #17028 -- Changed diveintopython.org -> diveintopython.net. Backport of 80c0cbf1c97047daed2c5b41b296bbc56fe1d7e3 from master.
There’s a script on the wiki to automate this.
Если коммит исправляет регрессию, включите это в сообщение коммита:
Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.
(используйте хэш коммита, где была введена регрессия).
Откат коммитов¶
Никто не идеален; коммиты будут создавать ошибки.
But try very hard to ensure that mistakes don’t happen. Just because we have a reversion policy doesn’t relax your responsibility to aim for the highest quality possible. Really: double-check your work, or have it checked by another committer, before you commit it in the first place!
При обнаружении ошибочного коммита следуйте следующим рекомендациям:
Если возможно, попросите автора отменить свой коммит.
Не отменяйте изменения, внесенные другим автором, без его разрешения.
Используйте git revert – это сделает обратный коммит, но исходный коммит все равно останется частью истории коммитов.
If the original author can’t be reached (within a reasonable amount of time – a day or so) and the problem is severe – crashing bug, major test failures, etc. – then ask for objections on the django-developers mailing list then revert if there are none.
Если проблема небольшая (например, коммит функциионала после его заморозки), подождите, как ситуация решится.
If there’s a disagreement between the committer and the reverter-to-be then try to work it out on the django-developers mailing list. If an agreement can’t be reached then it should be put to a vote.
Если коммит привел к подтвержденной, раскрытой уязвимости безопасности, то коммит может быть немедленно отменен без разрешения кого-либо.
Сопровождающий ветки релиза может отменять коммиты в ветке релиза без разрешения, если коммит нарушает работоспособность кода в релизной ветке.
Если вы по ошибке отправили ветку в
django/django, удалите ее. Например, если вы сделали:git push upstream feature_antigravity, выполните обратный push:git push upstream :feature_antigravity.