提交代码

这一节是针对合并以及任何有兴趣了解如何将代码提交到Django中的人。如果您是想要为Django贡献代码的社区成员,请查看 使用Git和Github 取而代之的是。

处理拉请求

因为Django托管在GitHub上,所以补丁是以拉请求的形式提供的。

在提交Pull请求时,请确保每个单独的提交都与下面描述的提交指导原则相匹配。预计贡献者将提供尽可能最佳的拉取请求。在实践中,合并者--他们可能会更熟悉承诺准则--可能会决定让自己的承诺达到标准。

您可能希望让Jenkins或GitHub Actions使用一个不自动运行的拉请求构建器(如Oracle或Selify)测试拉请求。请参阅 CI wiki page 以获取说明。

如果您发现自己更频繁地在本地签出拉请求,这个GIT别名将会很有帮助:

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

把它加到你的 ~/.gitconfig 并设置 upstream 成为 django/django . 然后你就可以跑了 git pr #### 以签出相应的拉请求。

此时,您可以处理代码。使用 git rebase -igit 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

在Main基础上重建后但在合并并推向上游之前强制推送到分支。这允许Main和BRANCH上的提交散列匹配,从而自动关闭Pull请求。

如果拉请求不需要合并为多个提交,则可以在网站上使用Github的“挤压和合并”按钮。根据需要编辑提交消息以符合 the guidelines 并删除自动附加到消息第一行的请求号。

重写拉请求的提交历史记录时,目标是使Django的提交历史记录尽可能可用:

  • 如果一个补丁包含来回提交,那么将它们重写为一个。例如,如果一个提交添加了一些代码,而第二个提交修复了第一个提交中引入的样式问题,那么应该在合并之前将这些提交压缩。

  • 通过逻辑分组将对不同提交的更改分开:如果您在对文件进行其他更改的同时进行样式清理,将更改分成两个不同的提交将使审阅历史记录更加容易。

  • 注意拉请求中上游分支的合并。

  • 测试应该通过,文档应该在每次提交之后构建。测试和文档都不应发出警告。

  • 小补丁和小补丁通常最好在一次提交中完成。如果有意义,可以将中型到大型工作拆分为多个提交。

实用性胜过纯洁性,因此由每个合并决定对拉入请求进行多少历史破坏。要点是让社区参与进来,完成工作,并拥有可用的提交历史记录。

提交指导原则

此外,在将代码提交到Django的Git存储库时,请遵循以下准则:

  • 从未改变 django/django 用力推树枝。如果您必须(例如出于安全原因),请首先与团队讨论情况。

  • 对于任何中到大的变化,其中“中到大”是根据您的判断,请在 Django Forum 或|Django-Developers|更改前的邮件列表。

    如果你提出了什么,但没有人回应,请不要认为这意味着你的想法很好,应该立即实施,因为没有人反对。每个人并不总是有很多时间立即阅读邮件列表讨论,所以你可能需要等几天才能得到回复。

  • 用过去时而不是现在时写详细的提交消息。

    • 好:“修复了RSS API中的Unicode错误。”

    • 错误:“修复了RSS API中的Unicode错误。”

    • 错误:“修复RSS API中的Unicode错误。”

    提交消息的行数应不超过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提供审查。”使用Git's Co-Authored-By 适当时。

  • 对于提交到分支,请在提交消息前面加上分支名称。例如: [1.4.x] 修正了XXXXX——增加了对读心术的支持。”

  • 限制承诺最细微的变化是有意义的。这意味着,使用频繁的小额承诺,而不是很少的大额承诺。例如,如果实现功能X需要对库Y做一个小的更改,那么首先将更改提交到库Y,然后在单独的提交中提交功能X。这是一个 漫长的道路 帮助每个人跟随你的变化。

  • 将错误修复与功能更改分开。根据 支持的版本 .

  • 如果你的承诺在Django关闭了一张票 ticket tracker ,以文本“Fixed XXXX”开始提交消息,其中“XXXX”是您提交修复的票据编号。示例:“Fixed 123——添加了Whizbang功能。”我们已经对trac进行了修改,使该格式的任何提交消息都将自动关闭引用的票据,并用完整的提交消息向其发布注释。

    出于好奇,我们使用了 Trac plugin 为此。

备注

请注意,Trac集成对拉请求一无所知。因此,如果您尝试关闭在提交消息中包含短语“Close#400”的Pull请求,GitHub将关闭Pull请求,但Trac插件不会关闭Trac中相同编号的票据。

  • 如果您的提交引用了Django中的一张票据 ticket tracker 但确实 not 关闭票据,包括短语“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.
    

    有一个 script on the wiki 使这一过程自动化。

    如果提交修复了回归,请将其包含在提交消息中:

    Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.
    

    (使用引入回归的提交哈希)。

恢复承诺

没有人是十全十美的,会犯错误的。

但要非常努力地确保错误不会发生。仅仅因为我们有一个回归政策,并不能减轻你追求最高质量的责任。真的:仔细检查你的工作,或者让另一家公司检查你的工作 before 你把它放在了第一位!

当发现错误承诺时,请遵循以下准则:

  • 如果可能,让原始作者恢复他们自己的提交。

  • 未经原作者的许可,不要还原其他作者的更改。

  • 使用git revert——这将进行反向提交,但原始提交仍然是提交历史的一部分。

  • 如果无法联系到原始作者(在一段合理的时间内--一天左右),并且问题很严重--崩溃的错误、重大的测试失败等--那么请求对 Django Forum 或者|Django-Developers|邮件列表,如果没有邮件列表,则恢复。

  • 如果问题很小(例如,在特性冻结后提交特性),请等待解决。

  • 如果合并和未来的逆转之间存在分歧,那么试着在 Django Forum 或|Django-Developers|邮件列表。如果不能达成协议,就应该付诸表决。

  • 如果提交引入了一个已确认的、已公开的安全漏洞,那么可以在没有任何人许可的情况下立即恢复提交。

  • 如果提交中断了发布分支,则发布分支维护人员可以不经许可而退出对发布分支的提交。

  • 如果错误地将主题分支推到 django/django ,删除它。例如,如果您这样做了: git push upstream feature_antigravity ,反向推动: git push upstream :feature_antigravity .