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

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

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

Поскольку Django теперь размещается на GitHub, большинство исправлений предоставляются в форме запросов на исправление.

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

Возможно, вы захотите, чтобы Jenkins протестировал заявку с помощью одного из конструкторов заявок, которые не запускаются автоматически, например, Oracle или Selenium. Инструкции см. в Jenkins wiki page.

Простой способ локально проверить запрос на вытягивание - добавить псевдоним к вашему ~/.gitconfig (upstream предполагается как django/django):

[alias]
    pr = !sh -c \"git fetch upstream pull/${1}/head:pr/${1} && git checkout pr/${1}\"

Теперь вы можете просто выполнить команду 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 после ребасинга на master, но до слияния и отправки в upstream. Это позволит хэшам коммитов на master и в ответвлении совпасть, что автоматически закроет запрос на pull.

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

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

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

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

Рекомендации по принятию обязательств

Кроме того, следуйте следующим рекомендациям при фиксации кода в 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 за патч и C за обзор».

  • Для фиксации в ветке, префикс сообщения о фиксации должен содержать имя ветки. Например: «[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 master.
    

    Для автоматизации этого существует script on the wiki.

    Если фиксация исправляет регрессию, включите это в сообщение о фиксации:

    Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.
    

    (используйте хэш коммита, в котором была введена регрессия).

Отмена фиксаций

Никто не совершенен; будут совершаться ошибки.

Но мы очень стараемся, чтобы ошибок не было. То, что у нас есть политика возврата, не снимает с вас ответственности за достижение максимально возможного качества. Действительно: перепроверьте свою работу или попросите другого коммиттера проверить её до того, как вы её зафиксируете!

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

  • Если возможно, попросите первоначального автора вернуть свой коммит.
  • Не возвращайте изменения другого автора без разрешения автора оригинала.
  • Используйте git revert - это сделает обратный коммит, но исходный коммит останется в истории коммитов.
  • Если автор оригинала не может быть найден (в течение разумного количества времени - день или около того) и проблема серьезная - сбойная ошибка, крупные сбои в тестировании и т.д. – то попросите возражений в списке рассылки django-developers и вернитесь, если их нет.
  • Если проблема небольшая (скажем, фиксация функции после заморозки функции), подождите.
  • Если между коммиттером и будущим ревертером есть разногласия, то попробуйте решить их в списке рассылки django-developers. Если соглашение не может быть достигнуто, то его следует вынести на голосование.
  • Если фиксация внесла подтверждённую, раскрытую уязвимость безопасности, то фиксация может быть немедленно отменена без чьего-либо разрешения.
  • Сопровождающий релизной ветви может отменять коммиты в релизной ветви без разрешения, если коммит нарушает релизную ветвь.
  • Если вы по ошибке переместили ветку темы в django/django, просто удалите ее. Например, если вы сделали: git push upstream feature_antigravity, просто сделайте обратный толчок: git push upstream :feature_antigravity.
Вернуться на верх