# Django 6.0.7 documentation

# 使用 Git 和 GitHub 工作

This section explains how the community can contribute code to Django via pull requests. If you're interested in how mergers handle them, see 处理 pull 请求.

接下来，我们将展示如何创建一个包含 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"，并且 fork 了 Django 的存储库，创建你的 fork 的本地副本：

    git clone https://github.com/GitHub_nick/django.git

这将创建一个新的目录 "django"，其中包含你 GitHub 存储库的克隆。此页面上的其余 Git 命令都需要在克隆的目录中运行，所以现在切换到该目录：

    cd django

在 Git 中，你的 Github 仓库会被称做“origin”。

你还应该将 `django/django` 设置为一个 "upstream" 远程仓库（也就是告诉 Git 参照 Django 的存储库作为你 fork 的源头）：

    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` 变更基本。 其他人不应在这样的分支上进行工作，因为当您编辑提交时，他们的副本会损坏。

还有"公共分支"。其他人应该 fork 这些分支，因此这些分支的历史永远不应该更改。`django/django` 存储库中的 "main" 和 "stable/A.B.x" 分支就是很好的公共分支的示例。

当您准备将工作成果并入Django时，应在GitHub上创建一个pull请求。好的拉取请求要求：

- commits with one logical change in each, following the coding style,

- 每次提交的格式正确的消息：摘要行，其后以72个字符包装的段落——有关详细信息，请参见 committing guidelines 。

- 如果需要，带有文档和测试——实际上一直需要测试，除了文档更改外。

测试套件必须通过，并且文档的构建必须没有警告。

一旦你创建了拉取请求，你应该在相关的 Trac 问题中添加一个评论，解释你所做的事情。特别是，你应该注明你运行测试的环境，例如："在 SQLite 和 MySQL 下都通过了所有测试"。

GitHub 上的拉取请求只有两种状态：打开和关闭。将处理你的拉取请求的合并者只有两个选项：合并它或关闭它。因此，在代码准备好合并或足够接近以便合并者可以自己完成之前，创建拉取请求并没有太大的用处。

### Editing commit messages

To change the message of the most recent commit, run:

    git commit --amend

This opens an editor with the current commit message. Edit it, save, and close to update the commit.

To change the message of an earlier commit, use the "reword" option in interactive rebase. For example, to reword one of the last three commits:

    git rebase -i HEAD~3

This opens an editor listing the three commits, each prefixed with the word "pick". Change "pick" to "reword" (or "r") on the line of the commit you want to change, then save and close. A new editor will open for each commit marked as "reword", allowing you to update the message.

See 提交指南 for the required commit message format.

After rewriting a commit that has already been pushed to GitHub, you will need to force-push your branch:

    git push --force-with-lease origin ticket_xxxxx

### 分支变基

In the example above, you created two commits, the "Fixed #xxxxx -- ..." commit and the "Added two more tests ..." commit.

我们不想在您的代码库中拥有您工作过程的全部历史记录。您的提交“添加了两个以上的测试”将毫无助益。相反，我们只希望一次提交包含您的所有工作。

要重塑你的分支历史，你可以使用交互式变基将多个提交合并成一个：

    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 --force-with-lease origin ticket_xxxxx

请注意，这将重写 ticket_xxxxx 的历史 - 如果你在 GitHub 上操作之前和之后检查提交哈希值，你会注意到提交哈希值不再匹配。这是可以接受的，因为这个分支是一个主题分支，没有人应该以它为基础进行工作。

### 在上游发生变化之后

当上游（`django/django`）发生变化时，你应该重新基于你的工作。要做到这一点，使用以下命令：

    git fetch upstream
    git rebase upstream/main

工作会自动使用你 fork 的分支进行重新基于，在示例中使用的是 `upstream/main`。

rebase命令暂时删除所有本地提交，应用上游提交，然后在工作上再次应用本地提交。

如果出现合并冲突，你需要解决它们，然后使用 `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`。