使用 Git 和 GitHub¶
本节介绍社区如何通过拉取请求为 Django 贡献代码。如果您对 合并者 如何处理它们感兴趣,请参阅 提交代码。
下面,我们将演示如何创建一个包含 Trac 问题 #xxxxx 更改的 GitHub 拉取请求。通过创建一个完全准备好的拉取请求,您将使审阅者更容易工作,这意味着您的工作更有可能被合并到 Django 中。
您也可以将传统的补丁上传到 Trac,但这对于审查来说不太实用。
安装 Git¶
Django 使用 Git 进行源代码控制。您可以 下载 Git,但通常使用操作系统的包管理器进行安装更容易。
Django 的 Git 仓库 托管在 GitHub 上,建议您也使用 GitHub 进行工作。
安装 Git 后,您应该做的第一件事是设置您的姓名和电子邮件
$ git config --global user.name "Your Real Name"
$ git config --global user.email "you@email.com"
请注意,user.name
应为您的真实姓名,而不是您的 GitHub 昵称。GitHub 应该知道您在 user.email
字段中使用的电子邮件,因为这将用于将您的提交与您的 GitHub 帐户关联起来。
设置本地仓库¶
创建 GitHub 帐户后,使用昵称“GitHub_nick”并 分叉 Django 的仓库,创建您分叉仓库的本地副本
git clone https://github.com/GitHub_nick/django.git
这将在包含您 GitHub 仓库克隆的“django”目录中创建一个新目录。本页上的其余 git 命令需要在克隆的目录中运行,因此请立即切换到该目录
cd django
您的 GitHub 仓库在 Git 中将被称为“origin”。
您还应该将 django/django
设置为“上游”远程(即,告诉 git 参考 Django 仓库是您分叉它的来源)
git remote add upstream https://github.com/django/django.git
git fetch upstream
您可以类似地添加其他远程,例如
git remote add akaariai https://github.com/akaariai/django.git
处理问题¶
处理问题时,为工作创建一个新分支,并将该工作基于 upstream/main
git checkout -b ticket_xxxxx upstream/main
-b 标志为您在本地创建了一个新分支。即使是最小的事情也不要犹豫创建新分支——这就是它们存在的意义。
如果您改为处理 1.4 分支上的修复,则执行以下操作
git checkout -b ticket_xxxxx_1_4 upstream/stable/1.4.x
假设工作在 ticket_xxxxx 分支上进行。进行一些更改并提交它们
git commit
编写提交消息时,请遵循 提交消息指南 以便于合并者的工作。如果您不习惯英语,请至少尝试准确描述提交的作用。
如果需要对分支进行其他工作,请根据需要经常提交
git commit -m 'Added two more tests for edge cases'
发布工作¶
您可以通过运行以下命令在 GitHub 上发布您的工作
git push origin ticket_xxxxx
转到您的 GitHub 页面时,您会注意到已创建了一个新分支。
如果您正在处理 Trac 问题,则应在问题中提到您的工作可从 GitHub 仓库的 ticket_xxxxx 分支获得。包含指向您分支的链接。
请注意,上述分支在 Git 行话中称为“主题分支”。您可以通过使用 git rebase
等方式重写此分支的历史记录。其他人不应基于此类分支进行工作,因为当您编辑提交时,他们的克隆将变得损坏。
还有“公共分支”。这些是其他人应该分叉的分支,因此这些分支的历史记录不应该改变。公共分支的良好示例是 django/django
仓库中的 main
和 stable/A.B.x
分支。
当您认为您的工作已准备好被拉入 Django 时,您应该在 GitHub 上创建一个拉取请求。一个好的拉取请求意味着
每个提交包含一个逻辑更改,遵循 编码风格,
每个提交都具有格式良好的消息:一个摘要行,然后是之后换行到 72 个字符的段落——有关更多详细信息,请参阅 提交指南,
如有必要,请提供文档和测试——实际上,除了文档更改之外,始终需要测试。
测试套件必须通过,并且文档必须在没有警告的情况下构建。
创建拉取请求后,您应该在相关的 Trac 问题中添加一条评论,说明您做了什么。特别是,您应该注意运行测试的环境,例如:“所有测试在 SQLite 和 MySQL 下都通过”。
GitHub 上的拉取请求只有两种状态:打开和关闭。将处理您的拉取请求的合并者只有两个选项:合并它或关闭它。因此,在代码准备好合并之前(或足够接近合并者自己完成它)创建拉取请求是没有意义的。
变基分支¶
在上面的示例中,您创建了两个提交,“修复 ticket_xxxxx”提交和“添加了两个更多测试”提交。
我们不希望在您的仓库中包含整个工作流程的历史记录。您的提交“添加了两个更多测试”将是无用的噪声。相反,我们宁愿只拥有一个包含所有工作的提交。
要重做分支的历史记录,您可以使用交互式变基将提交压缩为一个
git rebase -i HEAD~2
上面的 HEAD~2 是两个最新提交的简写。上述命令将打开一个编辑器,显示两个提交,并在前面加上“pick”一词。
将第二行的“pick”更改为“squash”。这将保留第一个提交,并将第二个提交压缩到第一个提交中。保存并退出编辑器。应该会打开第二个编辑器窗口,以便您可以在提交消息中重新措辞提交,因为现在它包含了您的两个步骤。
您也可以在变基中使用“edit”选项。这样您就可以更改单个提交,例如修复文档字符串中的错别字
git rebase -i HEAD~3
# Choose edit, pick, pick for the commits
# Now you are able to rework the commit (use git add normally to add changes)
# When finished, commit work with "--amend" and continue
git commit --amend
# Reword the commit message if needed
git rebase --continue
# The second and third commits should be applied.
如果您的主题分支已在 GitHub 上发布,例如,如果您正在进行细微更改以考虑审查,则需要强制推送更改
git push -f origin ticket_xxxxx
请注意,这将重写 ticket_xxxxx 的历史记录——如果您在 GitHub 上检查操作前后提交的哈希值,您会注意到提交的哈希值不再匹配。这是可以接受的,因为该分支是主题分支,任何人都不能基于它进行工作。
上游更改后¶
当上游(django/django
)发生更改时,您应该变基您的工作。为此,请使用
git fetch upstream
git rebase upstream/main
工作会自动使用您分叉的分支进行变基,在本例中使用 upstream/main
。
变基命令会暂时删除所有本地提交,应用上游提交,然后再次在上游工作上应用本地提交。
如果存在合并冲突,您需要解决它们,然后使用 git rebase --continue
。在任何时候,您都可以使用 git rebase --abort
返回到原始状态。
请注意,您希望在上游变基,而不是合并上游。
这样做的原因是,通过变基,您的提交将始终位于上游工作的顶部,而不是与上游的更改混合。这样,您的分支将只包含与其主题相关的提交,这使得压缩更容易。
审查后¶
在没有审阅者要求的更改的情况下,将任何数量的非微不足道的代码放入核心是不寻常的。在这种情况下,通常最好将更改作为增量提交添加到您的工作中。这允许审阅者轻松检查您所做的更改。
在这种情况下,进行审阅者要求的更改。根据需要经常提交。在发布更改之前,请变基您的工作。如果您添加了两个提交,则运行
git rebase -i HEAD~2
将第二个提交压缩到第一个提交中。编写类似以下内容的提交消息
Made changes asked in review by <reviewer>
- Fixed whitespace errors in foobar
- Reworded the docstring of bar()
最后,将您的工作推回您的 GitHub 仓库。由于您在变基期间没有触及公共提交,因此您不应该需要强制推送
git push origin ticket_xxxxx
您的拉取请求现在也应该包含新的提交。
请注意,合并者在提交代码时可能会将审查提交压缩到上一个提交中。
处理补丁¶
开发人员为 Django 做贡献的方法之一是审查补丁。这些补丁通常会作为 GitHub 上的拉取请求存在,并且可以轻松地集成到您的本地仓库中
git checkout -b pull_xxxxx upstream/main
curl -L https://github.com/django/django/pull/xxxxx.patch | git am
这将创建一个新分支,然后将拉取请求中的更改应用到该分支。此时,您可以运行测试或执行任何其他需要执行的操作来调查补丁的质量。
有关处理拉取请求的更多详细信息,请参阅 合并者指南。
总结¶
如果可以,请在 GitHub 上工作。
通过链接到您的 GitHub 分支在 Trac 问题中宣布您的工作。
准备好后,发出拉取请求。
使您的拉取请求尽可能好。
在修复工作时,使用
git rebase -i
来压缩提交。当上游发生更改时,执行
git fetch upstream; git rebase
。