使用 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 仓库中的 mainstable/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

返回顶部