Коммиттинг кода

This section is addressed to the mergers 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.

Обработка запросов на поставку

Поскольку 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, mergers - 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 or GitHub actions test the pull request with one of the pull request builders that doesn’t run automatically, such as Oracle or Selenium. See the CI wiki page for instructions.

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

[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 main.
$ git checkout main
$ git pull upstream main
$ # Rebase the pull request on main.
$ git checkout pr/####
$ git rebase main
$ git checkout main
$ # Merge the work as "fast-forward" to main 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 main
$ # Push!
$ git push upstream main
$ # Delete the pull request branch.
$ git branch -d pr/xxxx
...\> REM Pull in the latest changes from main.
...\> git checkout main
...\> git pull upstream main
...\> REM Rebase the pull request on main.
...\> git checkout pr/####
...\> git rebase main
...\> git checkout main
...\> REM Merge the work as "fast-forward" to main 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 main
...\> REM Push!
...\> git push upstream main
...\> REM Delete the pull request branch.
...\> git branch -d pr/xxxx

Force push to the branch после ребасинга на main, но до слияния и отправки в upstream. Это позволит хэшам коммитов в main и ответвлении совпасть, что автоматически закроет запрос на pull.

Если запрос не нужно объединять в несколько коммитов, вы можете воспользоваться кнопкой «Squash and merge» на сайте GitHub. Отредактируйте сообщение о фиксации так, чтобы оно соответствовало the guidelines, и удалите номер запроса на притяжение, который автоматически добавляется к первой строке сообщения.

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

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

Practicality beats purity, so it is up to each merger 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 путем принудительного проталкивания. Если вам это абсолютно необходимо (например, по соображениям безопасности), сначала обсудите ситуацию с командой.

  • Для любых средних и больших изменений, где «средние и большие» - это по вашему мнению, пожалуйста, поднимайте вопрос в списке рассылки django-developers перед внесением изменений.

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

  • Пишите подробные сообщения о фиксации в прошедшем времени, а не в настоящем.

    • Хорошо: «Исправлена ошибка 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 ticket tracker, начните ваше сообщение о коммите с текста «Fixed #xxxxx», где «xxxxx» - номер тикета, который ваш коммит исправляет. Пример: «Fixed #123 – Added whizbang feature.». Мы настроили Trac так, что любое сообщение о фиксации в таком формате автоматически закрывает связанный с ним тикет и публикует к нему комментарий с полным сообщением о фиксации.

    Для любопытных, мы используем для этого Trac plugin.

Примечание

Обратите внимание, что интеграция Trac ничего не знает о pull request. Поэтому если вы попытаетесь закрыть pull request с фразой «closes #400» в сообщении о фиксации, GitHub закроет pull request, но плагин Trac не закроет тот же пронумерованный тикет в Trac.

  • Если ваш коммит ссылается на тикет в Django ticket tracker, но не закрывает его, включите фразу «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 main.
    

    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 merger, before you commit it in the first place!

Если обнаружена ошибочная фиксация, пожалуйста, следуйте этим рекомендациям:

  • Если возможно, попросите первоначального автора вернуть свой коммит.
  • Не возвращайте изменения другого автора без разрешения автора оригинала.
  • Используйте git revert - это сделает обратный коммит, но исходный коммит останется в истории коммитов.
  • Если автор оригинала не может быть найден (в течение разумного количества времени - день или около того) и проблема серьезная - сбойная ошибка, крупные сбои в тестировании и т.д. – то попросите возражений в списке рассылки django-developers и вернитесь, если их нет.
  • Если проблема небольшая (скажем, фиксация функции после заморозки функции), подождите.
  • If there’s a disagreement between the merger 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, сделайте обратный толчок: git push upstream :feature_antigravity
Вернуться на верх