Working with Git and GitHub

本节介绍社区如何通过pull请求为Django贡献代码。如果您对核心开发人员如何处理它们感兴趣,请参阅Committing code

下面,我们将展示如何创建一个包含Trac票据#xxxxx的更改的GitHub pull请求。通过创建一个完全准备的pull请求,您将使审阅者的工作更容易,这意味着您的工作更有可能被合并到Django。

你也可以上传一个传统的补丁到Trac,但它不太实用的评论。

Installing Git

Django使用Git作为其源代码控制。您可以下载 Git,但通常使用操作系统的软件包管理器更容易。

Django的Git存储库托管在GitHub上,建议您也使用GitHub。

安装Git后,你应该做的第一件事是设置你的名字和电子邮件:

$ git config --global user.name "Your Real Name"
$ git config --global user.email "[email protected]"

请注意,user.name应该是您的真实姓名,而不是您的GitHub nick。GitHub应该知道您在user.email字段中使用的电子邮件,因为这将用于将您的提交与您的GitHub帐户相关联。

Setting up local repository

当你创建了你的GitHub帐户,使用缺口“github_nick”和分叉的Django的存储库,创建你的fork的本地副本:

git clone [email protected]:github_nick/django.git

这将创建一个新目录“django”,其中包含您的GitHub存储库的克隆。此页面上的其余git命令需要在克隆目录中运行,现在切换到它:

cd django

您的GitHub存储库将在Git中称为“origin”。

您还应该将django / django设置为“上游”远程(即,告诉git引用Django存储库是它的源代码):

git remote add upstream [email protected]:django/django.git
git fetch upstream

您可以类似地添加其他远程文件,例如:

git remote add akaariai [email protected]:akaariai/django.git

Working on a ticket

当在票证上工作创建一个新的分支的工作,并基于上游/主机上的工作:

git checkout -b ticket_xxxxx upstream/master

-b标志在本地为您创建一个新的分支。不要犹豫,为最小的事情创建新的分支 - 这就是他们在那里。

如果相反你正在1.4分支上修复,你会做:

git checkout -b ticket_xxxxx_1_4 upstream/stable/1.4.x

假设工作在ticket_xxxxx分支上进行。进行一些更改并提交它们:

git commit

在编写提交消息时,请按照commit message guidelines来简化提交者的工作。如果你对英语不舒服,至少尝试描述提交是什么。

如果您需要在您的分支上执行其他操作,请按需提交:

git commit -m 'Added two more tests for edge cases'

Publishing work

你可以在GitHub上发布你的工作:

git push origin ticket_xxxxx

当你去你的GitHub页面,你会注意到一个新的分支已创建。

如果您正在使用Trac票,您应该在票证中提到您的工作可从您的github repo的分支ticket_xxxxx获得。包括指向您分支的链接。

注意,上述分支在Git中被称为“主题分支”。例如,您可以使用git rebase来自由重写此分支的历史记录。其他人不应该将他们的工作基于这样的分支,因为他们的克隆将在您编辑提交时损坏。

还有“公共分支”。这些是其他人应该分叉的分支,所以这些分支的历史不应该改变。公共分支的好例子是django / django存储库中的masterstable/A.B.x分支。

当你认为你的工作准备好进入Django时,你应该在GitHub上创建一个pull请求。良好的牵引请求意味着:

  • coding style之后,在每个中提交一个逻辑更改,
  • 每个提交的格式正确的消息:汇总行,然后段落包裹在72个字符之后 - 有关更多详细信息,请参阅committing guidelines
  • 文档和测试,如果需要 - 实际上总是需要测试,除了文档更改。

测试套件必须通过,文档必须构建而不出现警告。

一旦你创建了pull请求,你应该在相关的Trac票证中添加一条评论,解释你做了什么。特别是你应该注意运行测试的环境,例如:“所有测试通过SQLite和MySQL”。

在GitHub的pull请求只有两个状态:打开和关闭。提交者将处理你的pull请求只有两个选项:合并或关闭它。为此,在代码准备好合并之前,或者足够接近提交者自己完成它之前,提出pull请求是没有用的。

Rebasing branches

在上面的示例中,您创建了两个提交,“Fixed ticket_xxxxx”提交和“添加另外两个测试”提交。

我们不想在您的存储库中有整个工作过程的历史记录。你的承诺“增加了两个测试”将是无益的噪音。相反,我们宁愿只有一个包含所有工作的提交。

要重做您的分支的历史,您可以通过使用交互式rebase将提交压缩为一个:

git rebase -i HEAD~2

上面的HEAD〜2是两个最新提交的缩写。上面的命令将打开一个编辑器,显示两个提交,前面加上“pick”一词。

将第二行上的“选择”改为“挤压”。这将保持第一个提交,并将第二个提交压缩到第一个提交。保存并退出编辑器。第二个编辑器窗口应该打开,因此您可以为提交重新编写提交消息,因为它包括两个步骤。

您还可以在rebase中使用“编辑”选项。这样,您可以更改单个提交,例如修复docstring中的错误:

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操作之前和之后的提交哈希,你会注意到提交哈希不再匹配。这是可以接受的,因为分支只是一个主题分支,没有人应该根据它的工作。

After upstream has changed

当上游(django / django)已经改变,你应该rebase你的工作。为此,请使用:

git fetch upstream
git rebase

工作将使用您分支的分支自动重组,在示例中使用upstream / master。

rebase命令临时删除所有本地提交,应用上游提交,然后再次对工作应用本地提交。

如果存在合并冲突,您需要先解决它们,然后使用git rebase - 继续在任何时候,您都可以使用git rebase - abort返回原始状态。

请注意,您想要在上游改变,而不是合并上游。

这样做的原因是,通过重基础,您的提交将总是上游的工作之上,而不是混合在上游的变化。这样,您的分支将仅包含与其主题相关的提交,这使得压缩更容易。

After review

在审核人员要求更改的情况下,将任何不重要的代码量包含到核心中是不寻常的。在这种情况下,通常最好将更改作为一个增量提交添加到工作中。这允许审阅者容易地检查您做了什么改变。

在这种情况下,请进行审阅者所需的更改。根据需要经常提交。在发布更改之前,重命名您的工作。如果添加了两个提交,您将运行:

git rebase -i HEAD~2

将第二个提交放入第一个提交。写一个提交消息的行:

Made changes asked in review by <reviewer>

- Fixed whitespace errors in foobar
- Reworded the docstring of bar()

最后把你的工作推回到你的GitHub仓库。由于你在rebase期间没有触摸公共提交,你不需要强制push:

git push origin ticket_xxxxx

您的pull请求现在应该包含新的提交。

请注意,提交者可能会在提交代码时将审核提交压缩到之前的提交中。

Working on a patch

开发人员可以为Django做出贡献的方法之一是查看补丁。这些补丁通常作为pull请求存在于GitHub上,并且可以轻松地集成到您的本地存储库:

git checkout -b pull_xxxxx upstream/master
curl https://github.com/django/django/pull/xxxxx.patch | git am

这将创建一个新的分支,然后将更改从拉请求应用到它。此时,您可以运行测试或执行任何其他操作来调查补丁的质量。

有关处理拉取请求的更多详细信息,请参阅guidelines for committers

Summary

  • 如果可以的话,在GitHub上工作。
  • 通过链接到您的GitHub分支宣布您的工作在Trac票。
  • 当你有一些准备好,做一个拉请求。
  • 使你的请求尽可能好。
  • 在修正工作时,请使用git rebase -i来压缩提交。
  • 当上游发生变化时,请执行git fetch upstream; git rebase