代码提交

本节面向合并者以及任何对了解 Django 代码如何提交感兴趣的人。如果您是社区成员,希望为 Django 贡献代码,请参阅使用 Git 和 GitHub

处理拉取请求

由于 Django 托管在 GitHub 上,因此补丁以拉取请求的形式提供。

提交拉取请求时,请确保每个单独的提交都符合下面描述的提交指南。贡献者应提供尽可能好的拉取请求。实际上,合并者(他们可能更熟悉提交指南)可能会决定自己将提交提升到标准。

您可能希望使用 Jenkins 或 GitHub Actions 使用不会自动运行的拉取请求构建器之一(例如 Oracle 或 Selenium)来测试拉取请求。有关说明,请参阅CI Wiki 页面

如果您发现自己更频繁地在本地检出拉取请求,则此 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 分支和分支上的提交哈希匹配,从而自动关闭拉取请求。

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

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

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

  • 通过逻辑分组将更改分离到不同的提交中:如果您在对文件进行其他更改的同时进行风格清理,则将更改分离到两个不同的提交中将使查看历史记录更容易。

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

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

  • 微不足道的和小的补丁通常最好在一个提交中完成。如果合理,中等至大型的工作可以拆分为多个提交。

实用性胜过纯度,因此每个合并者都必须决定对拉取请求进行多少历史修改。要点是:吸引社区、完成工作以及拥有可用的提交历史。

提交指南

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

  • 切勿通过强制推送更改django/django分支的已发布历史记录。如果您绝对必须这样做(例如出于安全原因),请先与团队讨论情况。

  • 对于任何中等至大型的更改(“中等至大型”根据您的判断),请在进行更改之前在Django 论坛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 的Co-Authored-By

  • 对于对分支的提交,请在提交消息前面加上分支名称。例如:“[1.4.x] 修复了 #xxxxx – 添加了对读心的支持。”

  • 将提交限制在最细粒度的有意义的更改。这意味着,使用频繁的小提交而不是不频繁的大提交。例如,如果实现功能 X 需要对库 Y 进行小的更改,则首先提交对库 Y 的更改,然后在单独的提交中提交功能 X。这在帮助每个人跟踪您的更改方面有很大的帮助。

  • 将错误修复与功能更改分开。根据受支持的版本,错误修复可能需要回移植到稳定分支。

  • 如果您的提交关闭了 Django工单跟踪器中的工单,请在提交消息的开头加上“Fixed #xxxxx”文本,其中“xxxxx”是您的提交修复的工单编号。例如:“Fixed #123 – 添加了 whizbang 功能”。我们已经对 Trac 进行了修改,以便任何以这种格式的提交消息都会自动关闭引用的工单,并向其发布带有完整提交消息的评论。

    出于好奇,我们正在为此使用Trac 插件

注意

请注意,Trac 集成不知道任何有关拉取请求的信息。因此,如果您尝试在提交消息中使用短语“closes #400”来关闭拉取请求,GitHub 将关闭拉取请求,但 Trac 插件不会在 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 main.
    

    Wiki 上有一个脚本可以自动执行此操作。

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

    Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.
    

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

恢复提交

没有人是完美的;错误将被提交。

但请非常努力地确保不会发生错误。仅仅因为我们有恢复策略并不意味着您可以放松您追求尽可能高的质量的责任。真的:在您首先提交它之前,请仔细检查您的工作,或让其他合并者检查它!

发现错误提交时,请遵循以下指南

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

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

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

  • 如果无法联系到原始作者(在合理的时间内 - 一天左右),并且问题很严重 - 崩溃错误、重大测试失败等 - 那么请在Django 论坛django-developers邮件列表上征求异议,然后在没有异议的情况下恢复。

  • 如果问题很小(例如功能冻结后的功能提交),请等待。

  • 如果合并者和即将恢复者之间存在分歧,请尝试在Django 论坛django-developers邮件列表上解决。如果无法达成一致,则应进行投票。

  • 如果提交引入了已确认的、公开的安全漏洞,则可以立即在未经任何人许可的情况下恢复提交。

  • 如果提交破坏了发布分支,则发布分支维护者可以在未经许可的情况下从发布分支中删除提交。

  • 如果您错误地将主题分支推送到django/django,请将其删除。例如,如果您执行了:git push upstream feature_antigravity,请执行反向推送:git push upstream :feature_antigravity

返回顶部