创建 Pull Request

本章介绍了维护者如何创建并向其他维护者提交 Pull Request。这对于将变更从一个维护者的代码树(tree)转移到另一个维护者的代码树非常有用。

本文档由 Tobin C. Harding(当时他还不是一位经验丰富的维护者)编写,主要基于 Greg Kroah-Hartman 和 Linus Torvalds 在 LKML 上的评论。Jonathan Corbet 和 Mauro Carvalho Chehab 提供了建议和修正。文中如有表达不当之处,纯属无心,但也难以避免,请直接向 Tobin C. Harding <me@tobin.cc> 反馈。

原始邮件讨论串

https://lore.kernel.org/r/20171114110500.GA21175@kroah.com

创建分支

首先,你需要将希望包含在 Pull Request 中的所有变更放在一个独立的分支上。通常,你会基于你打算向其发送 Pull Request 的开发者的代码树中的某个分支来创建此分支。

为了创建 Pull Request,你必须首先为你刚刚创建的分支打标签(tag)。建议选择一个有意义的标签名称,以便你和其他人在一段时间后仍能理解。一个好的做法是在名称中包含来源子系统和目标内核版本的标识。

Greg 提供了以下建议。一个针对 drivers/char 的包含杂项内容的 Pull Request,若要应用于内核版本 4.15-rc1,可以命名为 char-misc-4.15-rc1。如果该标签是从名为 char-misc-next 的分支生成的,你将使用以下命令

git tag -s char-misc-4.15-rc1 char-misc-next

这将创建一个名为 char-misc-4.15-rc1 的签名标签,该标签基于 char-misc-next 分支的最后一次提交,并使用你的 GPG 密钥进行签名(参见 配置 Git)。

Linus 只接受基于签名标签的 Pull Request。其他维护者可能会有不同要求。

当你运行上述命令时,git 会让你进入编辑器并要求描述该标签。在这种情况下,你是在描述一个 Pull Request,因此请概述其中包含的内容、为何应合并它,以及已进行了哪些测试(如果有)。所有这些信息最终都会进入标签本身,并在维护者合并该 Pull Request 时进入他们所做的合并提交(merge commit)中。所以请认真撰写,因为它将永远留在内核代码树中。

正如 Linus 所说

Anyway, at least to me, the important part is the *message*. I want
to understand what I'm pulling, and why I should pull it. I also
want to use that message as the message for the merge, so it should
not just make sense to me, but make sense as a historical record
too.

Note that if there is something odd about the pull request, that
should very much be in the explanation. If you're touching files
that you don't maintain, explain _why_. I will see it in the
diffstat anyway, and if you didn't mention it, I'll just be extra
suspicious.  And when you send me new stuff after the merge window
(or even bug-fixes, but ones that look scary), explain not just
what they do and why they do it, but explain the _timing_. What
happened that this didn't go through the merge window..

I will take both what you write in the email pull request _and_ in
the signed tag, so depending on your workflow, you can either
describe your work in the signed tag (which will also automatically
make it into the pull request email), or you can make the signed
tag just a placeholder with nothing interesting in it, and describe
the work later when you actually send me the pull request.

And yes, I will edit the message. Partly because I tend to do just
trivial formatting (the whole indentation and quoting etc), but
partly because part of the message may make sense for me at pull
time (describing the conflicts and your personal issues for sending
it right now), but may not make sense in the context of a merge
commit message, so I will try to make it all make sense. I will
also fix any speeling mistaeks and bad grammar I notice,
particularly for non-native speakers (but also for native ones
;^). But I may miss some, or even add some.

                Linus

Greg 给出的一个 Pull Request 示例如下

Char/Misc patches for 4.15-rc1

Here is the big char/misc patch set for the 4.15-rc1 merge window.
Contained in here is the normal set of new functions added to all
of these crazy drivers, as well as the following brand new
subsystems:
        - time_travel_controller: Finally a set of drivers for the
          latest time travel bus architecture that provides i/o to
          the CPU before it asked for it, allowing uninterrupted
          processing
        - relativity_shifters: due to the affect that the
          time_travel_controllers have on the overall system, there
          was a need for a new set of relativity shifter drivers to
          accommodate the newly formed black holes that would
          threaten to suck CPUs into them.  This subsystem handles
          this in a way to successfully neutralize the problems.
          There is a Kconfig option to force these to be enabled
          when needed, so problems should not occur.

All of these patches have been successfully tested in the latest
linux-next releases, and the original problems that it found have
all been resolved (apologies to anyone living near Canberra for the
lack of the Kconfig options in the earlier versions of the
linux-next tree creations.)

Signed-off-by: Your-name-here <your_email@domain>

标签信息的格式就像 Git 提交 ID(的信息格式)一样。顶部一行用于“摘要主题”,并在底部务必进行签名(sign-off)。

现在你已经有了一个本地签名标签,需要将其推送到可以被获取的地方

git push origin char-misc-4.15-rc1

创建 Pull Request

最后要做的事情是创建 Pull Request 消息。git 可以通过 git request-pull 命令便捷地为你完成此操作,但它需要一点帮助来确定你想要拉取的内容,以及基于什么来拉取(以显示要拉取的正确变更和差异统计 diffstat)。以下命令将生成一个 Pull Request

git request-pull master git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/ char-misc-4.15-rc1

引用 Greg 的话

This is asking git to compare the difference from the
'char-misc-4.15-rc1' tag location, to the head of the 'master'
branch (which in my case points to the last location in Linus's
tree that I diverged from, usually a -rc release) and to use the
git:// protocol to pull from.  If you wish to use https://, that
can be used here instead as well (but note that some people behind
firewalls will have problems with https git pulls).

If the char-misc-4.15-rc1 tag is not present in the repo that I am
asking to be pulled from, git will complain saying it is not there,
a handy way to remember to actually push it to a public location.

The output of 'git request-pull' will contain the location of the
git tree and specific tag to pull from, and the full text
description of that tag (which is why you need to provide good
information in that tag).  It will also create a diffstat of the
pull request, and a shortlog of the individual commits that the
pull request will provide.

Linus 回应说他倾向于使用 git:// 协议。其他维护者可能有不同的偏好。此外,请注意,如果你在创建没有签名标签的 Pull Request,那么 https:// 可能是更好的选择。请查看原始讨论串以获取完整讨论。

提交 Pull Request

Pull Request 的提交方式与普通补丁相同。以嵌入式电子邮件的形式发送给维护者,并根据需要抄送(CC)LKML 和任何子系统特定的列表。发送给 Linus 的 Pull Request 通常具有类似以下的主题行

[GIT PULL] <subsystem> changes for v4.15-rc1