{"title":"提交代码","version":"2.2","locale":"zh-hans","docname":"internals/contributing/committing-code","url":"/zh-hans/2.2/internals/contributing/committing-code/","canonical":"https://djangodocs.dev/zh-hans/2.2/internals/contributing/committing-code/","summary":"本部分针对提交者以及任何有兴趣了解如何为Django贡献代码的人员。如果您是想向Django贡献代码的社区成员，请查看：doc：writing-code / working-with-git。","html":"<h1>提交代码<a class=\"heading-anchor\" href=\"#committing-code\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>本部分针对提交者以及任何有兴趣了解如何为Django贡献代码的人员。 如果您是想向Django贡献代码的社区成员，请查看：doc：writing-code / working-with-git。</p>\n<section id=\"handling-pull-requests\">\n<span id=\"id1\"></span><h2>处理 pull 请求<a class=\"heading-anchor\" href=\"#handling-pull-requests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>由于Django现在在GitHub上托管，因此大多数补丁都是以pull请求的形式提供的。</p>\n<p>提交请求时，请确保每个单独的提交符合下面提到的提交准则。贡献者将尽可能提供最佳的请求。 然而，在实践中，提交者 - 谁可能更熟悉提交准则 - 可能会决定提交一个自己的提交标准。</p>\n<p>您可能希望让Jenkins使用其中一个不自动运行的拉取请求构建器测试拉取请求，例如Oracle或Selenium。有关说明，请参阅Jenkins wiki页面。</p>\n<p>你可以通过在&quot;~/.gitconfig&quot;文件中添加别名的方式来更简单地在本地获取新的pull request. (例如将&quot;~/.gitconfig&quot;中的upstream设置为&quot;django/django&quot;):</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>[alias]\n    pr = !sh -c \\&quot;git fetch upstream pull/${1}/head:pr/${1} &amp;&amp; git checkout pr/${1}\\&quot;\n</code></pre></div>\n<p>现在你可以轻松地通过执行&quot;git pr ####&quot;来获取对应的pull request.</p>\n<p>到了这个阶段,你可以着手于代码.使用&quot;git rebase -i&quot;和&quot;git commit --ammend&quot; 来确保你的提交准确无误. 一旦你准备好了:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span><span class=\"c1\"># Pull in the latest changes from master.</span>\n<span class=\"gp\">$ </span>git checkout master\n<span class=\"gp\">$ </span>git pull upstream master\n<span class=\"gp\">$ </span><span class=\"c1\"># Rebase the pull request on master.</span>\n<span class=\"gp\">$ </span>git checkout pr/####\n<span class=\"gp\">$ </span>git rebase master\n<span class=\"gp\">$ </span>git checkout master\n<span class=\"gp\">$ </span><span class=\"c1\"># Merge the work as &quot;fast-forward&quot; to master to avoid a merge commit.</span>\n<span class=\"gp\">$ </span><span class=\"c1\"># (in practice, you can omit &quot;--ff-only&quot; since you just rebased)</span>\n<span class=\"gp\">$ </span>git merge --ff-only pr/XXXX\n<span class=\"gp\">$ </span><span class=\"c1\"># If you&#39;re not sure if you did things correctly, check that only the</span>\n<span class=\"gp\">$ </span><span class=\"c1\"># changes you expect will be pushed to upstream.</span>\n<span class=\"gp\">$ </span>git push --dry-run upstream master\n<span class=\"gp\">$ </span><span class=\"c1\"># Push!</span>\n<span class=\"gp\">$ </span>git push upstream master\n<span class=\"gp\">$ </span><span class=\"c1\"># Delete the pull request branch.</span>\n<span class=\"gp\">$ </span>git branch -d pr/xxxx\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM Pull in the latest changes from master.</span>\n<span class=\"gp\">...\\&gt;</span> git checkout master\n<span class=\"gp\">...\\&gt;</span> git pull upstream master\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM Rebase the pull request on master.</span>\n<span class=\"gp\">...\\&gt;</span> git checkout pr/####\n<span class=\"gp\">...\\&gt;</span> git rebase master\n<span class=\"gp\">...\\&gt;</span> git checkout master\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM Merge the work as &quot;fast-forward&quot; to master to avoid a merge commit.</span>\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM (in practice, you can omit &quot;--ff-only&quot; since you just rebased)</span>\n<span class=\"gp\">...\\&gt;</span> git merge --ff-only pr/XXXX\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM If you&#39;re not sure if you did things correctly, check that only the</span>\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM changes you expect will be pushed to upstream.</span>\n<span class=\"gp\">...\\&gt;</span> git push --dry-run upstream master\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM Push!</span>\n<span class=\"gp\">...\\&gt;</span> git push upstream master\n<span class=\"gp\">...\\&gt;</span> <span class=\"c1\">REM Delete the pull request branch.</span>\n<span class=\"gp\">...\\&gt;</span> git branch -d pr/xxxx\n</code></pre></div></div></div>\n<p>在对master进行rebase之后但在合并并推送到上游之前强制推送到分支。这允许master和branch上的提交哈希值匹配，从而自动关闭pull请求。</p>\n<p>如果拉请求不需要合并为多个提交，则可以在网页上使用Github的“挤压和合并”按钮。根据需要编辑提交消息以符合：ref:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>The guidelines&lt;committing-guidelines&gt;`并删除自动附加到消息第一行的请求编号。</p>\n<p>当重写pull请求的提交历史时，目标是使Django的提交历史尽可能可用：</p>\n<ul class=\"simple\">\n<li><p>如果补丁包含来回提交，则将其重写为一个。例如，如果提交添加了一些代码，第二个提交修复了第一次提交中引入的样式问题，那么这些提交应该在合并之前被压缩。</p></li>\n<li><p>通过逻辑分组对不同提交进行单独更改：如果在对文件进行其他更改的同时进行样式清理，则将更改分成两个不同的提交将使查看历史记录变得更容易。</p></li>\n<li><p>注意拉取请求中上游分支的合并。</p></li>\n<li><p>测试应该通过，文档应该在每次提交后构建。测试和文档都不应该发出警告。</p></li>\n<li><p>随意和小型的补丁通常最好在一次提交中完成。如果有意义，可以将中型到大型工作分成多个提交。</p></li>\n</ul>\n<p>实用性胜过纯度，所以每个贡献者都要决定为拉取请求做多少历史记录。主要观点是参与社区，完成工作以及拥有可用的提交历史记录。</p>\n</section>\n<section id=\"committing-guidelines\">\n<span id=\"id2\"></span><h2>提交指南<a class=\"heading-anchor\" href=\"#committing-guidelines\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>此外，在将代码提交到Django的Git存储库时，请遵循以下准则：</p>\n<ul>\n<li><p>永远不要通过强制推动来改变“django / django``分支的已发布历史。如果您绝对必须（出于安全原因），请先与团队讨论情况。</p></li>\n<li><p>对于任何根据您的判断“中到大”的变化，请在进行更改之前在django开发者邮件列表上提出。</p>\n<p>如果你对Django开发人员提出了一些建议，但没有人回应，请不要认为这意味着你的想法很棒，应该立即实施，因为没有人反对。每个人都没有足够的时间立即阅读邮件列表讨论，因此您可能需要等待几天才能得到答复。</p>\n</li>\n<li><p>以过去时态写出详细的提交消息，而不是现在时。</p>\n<ul class=\"simple\">\n<li><p>正确：&quot;Fixed Unicode bug in RSS API.&quot;</p></li>\n<li><p>错误：&quot;Fixes Unicode bug in RSS API.&quot;</p></li>\n<li><p>错误：&quot;Fixing Unicode bug in RSS API.&quot;</p></li>\n</ul>\n<p>提交消息最多应为72个字符。 应该有一个主题行，用空白行分隔，然后是72个字符行的段落。 限制很软。 对于主题行，越短越好。 在提交消息的主体中，更多细节优于更少：</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"None code\"><code>Fixed #18307 -- Added git workflow guidelines.\n\nRefactored the Django&#39;s documentation to remove mentions of SVN\nspecific tasks. Added guidelines of how to use Git, GitHub, and\nhow to use pull request together with Trac instead.\n</code></pre></div>\n<p>如果补丁不是拉请求，您应该在提交消息中对贡献者进行评价：“感谢A提供报告，B提供补丁，C提供审查。”</p>\n</li>\n<li><p>对于提交到分支，请在提交消息前面加上分支名称。例如：“[1.4.x]Fixed XXXX——增加了对思维阅读的支持。”</p></li>\n<li><p>限制承诺最细微的变化是有意义的。这意味着，使用频繁的小额承诺，而不是很少的大额承诺。例如，如果实现功能X需要对库Y做一个小的更改，那么首先将更改提交到库Y，然后在单独的提交中提交功能X。这对帮助每个人跟踪你的变化有很大的帮助。</p></li>\n<li><p>将错误修复与功能更改分开。根据：ref:supported versions policy，可能需要将错误修复返回到稳定分支。</p></li>\n<li><p>If your commit closes a ticket in the Django <a class=\"reference external\" href=\"https://code.djangoproject.com/\">ticket tracker</a>, begin\nyour commit message with the text &quot;Fixed #xxxxx&quot;, where &quot;xxxxx&quot; is the\nnumber of the ticket your commit fixes. Example: &quot;Fixed #123 -- Added\nwhizbang feature.&quot;. We've rigged Trac so that any commit message in that\nformat will automatically close the referenced ticket and post a comment\nto it with the full commit message.</p>\n<p>For the curious, we're using a <a class=\"reference external\" href=\"https://github.com/trac-hacks/trac-github\">Trac plugin</a> for this.</p>\n</li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Note that the Trac integration doesn't know anything about pull requests.\nSo if you try to close a pull request with the phrase &quot;closes #400&quot; in your\ncommit message, GitHub will close the pull request, but the Trac plugin\nwill also close the same numbered ticket in Trac.</p>\n</aside>\n<ul>\n<li><p>If your commit references a ticket in the Django <a class=\"reference external\" href=\"https://code.djangoproject.com/\">ticket tracker</a> but\ndoes <em>not</em> close the ticket, include the phrase &quot;Refs #xxxxx&quot;, where &quot;xxxxx&quot;\nis the number of the ticket your commit references. This will automatically\npost a comment to the appropriate ticket.</p></li>\n<li><p>使用此模式为后端端口编写提交消息：</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"None code\"><code>[&lt;Django version&gt;] Fixed &lt;ticket&gt; -- &lt;description&gt;\n\nBackport of &lt;revision&gt; from &lt;branch&gt;.\n</code></pre></div>\n<p>例如：</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"None code\"><code>[1.3.x] Fixed #17028 -- Changed diveintopython.org -&gt; diveintopython.net.\n\nBackport of 80c0cbf1c97047daed2c5b41b296bbc56fe1d7e3 from master.\n</code></pre></div>\n<p>There's a <a class=\"reference external\" href=\"https://code.djangoproject.com/wiki/CommitterTips#AutomatingBackports\">script on the wiki</a>\nto automate this.</p>\n<p>如果提交修复了回归，请将其包含在提交消息中：</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"None code\"><code>Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.\n</code></pre></div>\n<p>（使用引入回归的提交哈希）。</p>\n</li>\n</ul>\n</section>\n<section id=\"reverting-commits\">\n<h2>恢复提交<a class=\"heading-anchor\" href=\"#reverting-commits\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>没有人是完美的；一些错误可能会被提交</p>\n<p>但要努力确保错误不会发生。仅仅因为我们有一个退换货政策，并不能放松你的责任，使你的目标尽可能达到最高的质量。真的：仔细检查你的工作，或者让另一个提交者检查它，在你首先提交它**之前**！</p>\n<p>当你发现了一个错误的提交，请遵循如下步骤：</p>\n<ul class=\"simple\">\n<li><p>可能的话，让原始作者撤回他们的提交。</p></li>\n<li><p>不要在未获得原始作者同意的情况下还原其他作者的更改。</p></li>\n<li><p>Use git revert -- this will make a reverse commit, but the original\ncommit will still be part of the commit history.</p></li>\n<li><p>If the original author can't be reached (within a reasonable amount\nof time -- a day or so) and the problem is severe -- crashing bug,\nmajor test failures, etc. -- then ask for objections on the\n<a class=\"reference internal\" href=\"/zh-hans/2.2/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a> mailing list then revert if there are none.</p></li>\n<li><p>If the problem is small (a feature commit after feature freeze,\nsay), wait it out.</p></li>\n<li><p>If there's a disagreement between the committer and the\nreverter-to-be then try to work it out on the <a class=\"reference internal\" href=\"/zh-hans/2.2/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a>\nmailing list. If an agreement can't be reached then it should\nbe put to a vote.</p></li>\n<li><p>If the commit introduced a confirmed, disclosed security\nvulnerability then the commit may be reverted immediately without\npermission from anyone.</p></li>\n<li><p>The release branch maintainer may back out commits to the release\nbranch without permission if the commit breaks the release branch.</p></li>\n<li><p>If you mistakenly push a topic branch to <code class=\"docutils literal notranslate\">django/django</code>, just delete it.\nFor instance, if you did: <code class=\"docutils literal notranslate\">git push upstream feature_antigravity</code>,\njust do a reverse push: <code class=\"docutils literal notranslate\">git push upstream :feature_antigravity</code>.</p></li>\n</ul>\n</section>","rootId":"committing-code","toc":[{"title":"处理 pull 请求","anchor":"handling-pull-requests","children":[]},{"title":"提交指南","anchor":"committing-guidelines","children":[]},{"title":"恢复提交","anchor":"reverting-commits","children":[]}],"breadcrumbs":[{"docname":"internals/index","title":"Django internals","url":"/zh-hans/2.2/internals/"},{"docname":"internals/contributing/index","title":"为 Django 做贡献","url":"/zh-hans/2.2/internals/contributing/"}],"prev":{"docname":"internals/contributing/localizing","title":"使 Django 本地化","url":"/zh-hans/2.2/internals/contributing/localizing/"},"next":{"docname":"internals/mailing-lists","title":"Mailing lists","url":"/zh-hans/2.2/internals/mailing-lists/"},"formats":{"html":"/zh-hans/2.2/internals/contributing/committing-code/","markdown":"/zh-hans/2.2/internals/contributing/committing-code.md","json":"/zh-hans/2.2/internals/contributing/committing-code.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/internals/contributing/committing-code.txt","official":"https://docs.djangoproject.com/zh-hans/2.2/internals/contributing/committing-code/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}