如何在GitHub上创建拉取请求

来自菜鸟教程
跳转至:导航、​搜索

介绍

Git 是一个开源分布式版本控制系统,它使协作软件项目更易于管理。 许多项目将他们的文件保存在 Git 存储库中,而 GitHub 等平台使代码共享和贡献变得可访问、有价值且有效。

托管在公共存储库中的开源项目受益于更广泛的开发人员社区通过 拉取请求 所做的贡献,该请求要求项目接受您对其代码存储库所做的更改。

本教程将指导您通过命令行向 Git 存储库发出拉取请求,以便您可以为开源软件项目做出贡献。

先决条件

你应该在本地机器上安装了 Git。 您可以按照本指南检查您的计算机上是否安装了Git并完成操作系统的安装过程。

您还需要拥有或创建一个 GitHub 帐户。 您可以通过 GitHub 网站 github.com 进行操作,并且可以登录或创建您的帐户。

截至 2020 年 11 月,GitHub 删除了基于密码的身份验证。 因此,您需要创建一个 个人访问令牌 或添加您的 SSH 公钥信息 以便通过命令行访问 GitHub 存储库。

最后,您应该确定一个要贡献的开源软件项目。 通过阅读这篇介绍,您可以更加熟悉开源项目。

创建存储库的副本

repository,或简称 repo,本质上是项目的主文件夹。 存储库包含所有相关的项目文件,包括文档,还存储每个文件的修订历史记录。 在 GitHub 上,存储库可以有多个协作者,并且可以是公共的或私有的。

为了处理开源项目,您首先需要制作自己的存储库副本。 为此,您应该分叉存储库,然后克隆它,以便您拥有本地工作副本。

分叉存储库

您可以通过浏览器导航到您想要贡献的开源项目的 GitHub URL,在 GitHub 上创建一个存储库。

GitHub 存储库 URL 将引用与存储库所有者关联的用户名以及存储库名称。 例如,DigitalOcean Community(用户名:do-community)是 cloud_haiku 项目存储库的所有者,因此该项目的 GitHub URL 是:

https://github.com/do-community/cloud_haiku

在上面的示例中,do-community 是用户名,cloud_haiku 是存储库名称。

一旦你确定了你想要贡献的项目,你可以导航到 URL,它的格式如下:

https://github.com/username/repository

或者,您可以使用 GitHub 搜索栏搜索项目。

当您在存储库的主页上时,一个 Fork 按钮将显示在页面的右上角,在您的用户图标下方:

单击 Fork 按钮开始分叉过程。 在您的浏览器窗口中,您将收到一条通知,您正在处理您正在分叉的存储库:

完成该过程后,您的浏览器将转到与上一个存储库屏幕类似的屏幕,除了在顶部您会在存储库名称之前看到您的用户名,并且在 URL 中它还会在存储库名称之前显示您的用户名。

因此,在上面的示例中,您将看到 your-username / cloud_haiku 而不是页面顶部的 do-community / cloud_haiku,并且新 URL 将显示为类似对此:

https://github.com/your-username/cloud_haiku

分叉存储库后,您就可以克隆它,以便拥有代码库的本地工作副本。

克隆存储库

要制作您自己想要贡献的存储库的本地副本,让我们首先打开一个终端窗口。

我们将使用 git clone 命令以及指向您的存储库分支的 URL。

此 URL 将类似于上面的 URL,不同之处在于它现在将以 .git 结尾。 在上面的 cloud_haiku 示例中,URL 将与此类似,用您的实际用户名替换 your-username

https://github.com/your-username/cloud_haiku.git

您也可以使用从原始存储库页面派生的存储库页面中的绿色 “⤓ 代码” 按钮来复制 URL。 单击该按钮后,您将能够通过单击 URL 旁边的剪贴板按钮来复制 URL:

获得 URL 后,我们就可以克隆存储库了。 为此,我们将在终端窗口的命令行中将 git clone 命令与存储库 URL 结合起来:

git clone https://github.com/your-username/repository.git

现在我们有了代码的本地副本,我们可以继续创建一个新的分支来处理代码。

创建一个新分支

每当您在协作项目上工作时,您和其他为存储库做出贡献的程序员都会对新功能或修复有不同的想法。 其中一些新功能不会花费大量时间来实施,但其中一些将持续进行。 因此,对存储库进行分支非常重要,这样您才能管理工作流、隔离代码并控制将哪些功能返回到项目存储库的主分支。

项目存储库的主要分支通常称为 main 分支。 推荐的做法是将主分支上的任何内容都视为可随时部署以供其他人使用。

注意:2020 年 6 月,GitHub 更新了其术语,将默认源代码分支称为 main 分支,而不是 master 分支。 如果您的默认分支仍然显示为 master,您可以通过 更改默认分支设置 将其更新为 main


在基于现有项目创建分支时,从主分支创建新分支非常重要。 您还应该确保您的分支名称是描述性的。 与其将其称为 my-branch,不如使用 frontend-hook-migrationfix-documentation-typos 之类的名称。

要从终端窗口创建分支,让我们更改目录,以便我们在存储库的目录中工作。 请务必使用存储库的实际名称(例如 cloud_haiku)更改到该目录。

cd repository

现在,我们将使用 git branch 命令创建我们的新分支。 确保以描述性的方式命名它,以便从事该项目的其他人了解您正在从事的工作。

git branch new-branch

现在我们的新分支已创建,我们可以使用 git checkout 命令切换以确保我们正在处理该分支:

git checkout new-branch

输入 git checkout 命令后,您将收到以下输出:

OutputSwitched to branch 'new-branch'

或者,您可以使用以下命令和 -b 标志来压缩上述两个命令,创建并切换到新分支:

git checkout -b new-branch

如果您想切换回 main,您将使用带有主分支名称的 checkout 命令:

git checkout main

checkout 命令将允许您在多个分支之间切换,因此您可以同时处理多个功能。

此时,您现在可以修改现有文件或将新文件添加到您自己分支上的项目中。

在本地进行更改

为了演示提出拉取请求,让我们使用示例 cloud_haiku 存储库并在我们的本地副本中创建一个新文件。 使用您喜欢的文本编辑器创建一个新文件,以便我们可以添加新的俳句,如 贡献指南 中所述。 例如,我们可以使用 nano 并调用我们的示例文件 filename.md。 您需要使用 Markdown 的 .md 扩展名将您的文件称为原始名称。

nano filename.md

接下来,我们将按照 贡献指南 将一些文本添加到新文件中。 我们需要使用 Jekyll 格式并添加带有换行符的俳句。 以下文件是一个示例文件,因为您需要贡献一个原始的俳句。

文件名.md

---
layout: haiku
title: Octopus Cloud
author: Sammy
---

Distributed cloud <br>
Like the octopuses' minds <br>
Across the network <br>

包含文本后,保存并关闭文件。 如果您使用 nano,请按 CTRL + X,然后按 Y,然后按 ENTER

一旦您修改了现有文件或将新文件添加到您选择的项目中,您可以将其暂存到本地存储库,我们可以使用 git add 命令执行此操作。 在我们的示例 filename.md 中,我们将键入以下命令。

git add filename.md 

我们将创建的文件的名称传递给此命令,以将其暂存到我们的本地存储库。 这可确保您的文件已准备好添加。

如果您希望将所有已修改的文件添加到特定目录中,则可以使用以下命令将它们全部暂存:

git add . 

在这里,句号或句号将添加所有相关文件。

如果您希望递归添加所有更改,包括子目录中的更改,您可以键入:

git add -A

或者,您也可以为所有要暂存的新文件键入 git add -all

暂存文件后,我们将要记录使用 git commit 命令对存储库所做的更改。

提交更改

提交消息 是您代码贡献的一个重要方面; 它可以帮助维护人员和其他贡献者充分了解您所做的更改、为什么要进行更改以及更改的重要性。 此外,提交消息提供整个项目更改的历史记录,帮助未来的贡献者。

如果我们有一个非常短的消息,我们可以使用 -m 标志和引号中的消息来记录。 在我们添加俳句的示例中,我们的 git commit 可能类似于以下内容。

git commit -m "Added a new haiku in filename.md file"

除非它是次要或预期的更改,否则我们可能希望包含更长的提交消息,以便我们的合作者完全跟上我们的贡献。 要记录这条更大的消息,我们将运行 git commit 命令,该命令将打开默认文本编辑器:

git commit

运行此命令时,您可能会注意到您在 vim 编辑器中,您可以通过键入 :q 退出。 如果你想配置你的默认文本编辑器,你可以使用 git config 命令,并将 nano 设置为默认编辑器,例如:

git config --global core.editor "nano"

或vim:

git config --global core.editor "vim"

运行 git commit 命令后,根据您使用的默认文本编辑器,您的终端窗口应显示一个可供您编辑的文档,类似于以下内容:

GNU nano 2.0.6 文件:…用户名/存储库/.git/COMMIT_EDITMSG

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch new-branch
# Your branch is up-to-date with 'origin/new-branch'.
#
# Changes to be committed:
#       modified:   new-feature.py
#

在介绍性注释下方,您应该将提交消息添加到文本文件中。

要编写有用的提交消息,您应该在第一行包含大约 50 个字符长的摘要。 在此之下,并分解为易于理解的部分,您应该包含一个描述,说明您进行此更改的原因、代码如何工作,以及将在合并时对其进行上下文化和澄清以供其他人查看工作的附加信息。 尽量提供帮助和积极主动,以确保维护项目的人员能够充分理解您的贡献。

推送更改

保存并退出提交消息文本文件后,您可以使用以下命令验证 Git 将提交的内容:

git status

根据您所做的更改,您将收到类似于以下内容的输出:

OutputOn branch new-branch
nothing to commit, working tree clean

此时,您可以使用 git push 命令将更改推送到分叉存储库的当前分支:

git push --set-upstream origin new-branch

该命令将为您提供输出以让您了解进度,它将类似于以下内容:

OutputCounting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 336 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/your-username/repository.git
   a1f29a6..79c0e80  new-branch  -> new-branch
Branch new-branch set up to track remote branch new-branch from origin.

您现在可以导航到 GitHub 网页上的分叉存储库并切换到您推送的分支以查看您在浏览器中所做的更改。

此时,可以 向原始存储库发出拉取请求,但如果您还没有这样做,您需要确保您的本地存储库是最新的上游存储库。

更新本地存储库

当您与其他贡献者一起处理项目时,保持本地存储库与项目保持同步很重要,因为您不希望对会自动导致冲突的代码发出拉取请求(尽管在协作代码项目,必然会发生冲突)。 要保持代码库的本地副本更新,您需要同步更改。

我们将首先为 fork 配置远程,然后同步 fork。

为分叉配置远程

远程存储库 使您可以在 Git 项目上与他人协作。 每个远程存储库都是托管在 Internet 或您有权访问的网络上的项目版本。 您应该可以只读或读写的方式访问每个远程存储库,具体取决于您的用户权限。

为了能够将您在分叉中所做的更改与您正在使用的原始存储库同步,您需要配置一个引用上游存储库的远程。 您应该只将远程设置到上游存储库一次。

让我们首先检查您配置了哪些远程服务器。 git remote 命令将列出您已经指定的任何远程存储库,因此如果您像我们上面所做的那样克隆存储库,您至少会收到有关原始存储库的输出,这是 Git 为克隆的目录。

在终端窗口的存储库目录中,让我们使用 git remote 命令和 -v 标志来显示 Git 存储的 URL 以及相关的远程短名称(如“origin ”):

git remote -v

由于我们克隆了一个存储库,我们的输出应该类似于:

Outputorigin    https://github.com/your-username/forked-repository.git (fetch)
origin    https://github.com/your-username/forked-repository.git (push)

如果您之前设置了多个遥控器,git remote -v 命令将提供所有遥控器的列表。

接下来,我们将指定一个新的远程上游存储库,以便我们与 fork 同步。 这将是我们从中分叉的原始存储库。 我们将使用 git remote add 命令执行此操作。

git remote add upstream https://github.com/original-owner-username/original-repository.git

对于我们的 cloud_haiku 示例,此命令如下:

git remote add upstream https://github.com/do-community/cloud_haiku.git

在此示例中,upstream 是我们为远程存储库提供的简称,因为在 Git 方面,“上游”是指我们从中克隆的存储库。 如果我们想添加一个指向协作者存储库的远程指针,我们可能希望提供该协作者的用户名或短名称的缩写昵称。

我们可以通过再次使用存储库目录中的 git remote -v 命令来验证我们指向上游存储库的远程指针是否正确添加:

git remote -v
Outputorigin    https://github.com/your-username/forked-repository.git (fetch)
origin    https://github.com/your-username/forked-repository.git (push)
upstream    https://github.com/original-owner-username/original-repository.git (fetch)
upstream    https://github.com/original-owner-username/original-repository.git (push)

现在您可以在命令行中引用 upstream 而不是编写整个 URL,并且您已准备好将您的 fork 与原始存储库同步。

同步分叉

一旦我们在 GitHub 上配置了引用上游和原始存储库的远程,我们就可以同步存储库的分支以使其保持最新。

为了同步我们的分支,从终端窗口中的本地存储库的目录中,我们将使用 git fetch 命令从上游存储库中获取分支及其各自的提交。 由于我们使用短名称“upstream”来指代上游存储库,因此我们将其传递给命令。

git fetch upstream

根据我们对存储库进行分叉后进行了多少更改,您的输出可能会有所不同,并且可能包括几行关于计数、压缩和解包对象的内容。 您的输出将类似于以下几行结束,但可能会因项目中有多少分支而异:

OutputFrom https://github.com/original-owner-username/original-repository
 * [new branch]      main     -> upstream/main

现在,对主分支的提交将存储在名为 upstream/main 的本地分支中。

让我们切换到存储库的本地主分支:

git checkout main
OutputSwitched to branch 'main'

现在,我们将通过本地 upstream/main 分支访问原始存储库的主分支中所做的任何更改与我们的本地主分支:

git merge upstream/main

此处的输出会有所不同,但如果进行了更改,它将以 UpdatingAlready up-to-date 开头。 如果自您分叉存储库以来未进行任何更改。

您的 fork 的主分支现在与上游存储库同步,并且您所做的任何本地更改都不会丢失。

根据您自己的工作流程和进行更改所花费的时间,您可以将您的 fork 与原始存储库的上游代码同步多次,这对您来说是有意义的。 但是您当然应该在发出拉取请求之前同步您的分叉,以确保您不会自动提供冲突的代码。

创建拉取请求

此时,您已准备好向原始存储库发出拉取请求。

您应该导航到您的分叉存储库,然后按页面左侧的 New pull request 按钮。

您可以在下一个屏幕上修改分支。 在任一侧,您都可以从下拉菜单和适当的分支中选择适当的存储库。

例如,一旦您选择了左侧原始存储库的主分支,以及右侧分叉存储库的 new-branch,您应该会收到一个屏幕:声明如果没有竞争代码,您的分支可以合并:

您应该在适当的字段中添加标题和评论,然后按 创建拉取请求 按钮。

此时,原始存储库的维护人员将决定是否接受您的拉取请求。 他们可能会要求您在通过提交代码审查接受拉取请求之前编辑或修改您的代码。

结论

至此,您已成功向开源软件存储库发送拉取请求。 在此之后,您应该确保在等待审核时更新和重新定义您的代码。 项目维护人员可能会要求您重新编写代码,因此您应该准备好这样做。

为开源项目做贡献——并成为一名活跃的开源开发者——可能是一种有益的经历。 定期为您经常使用的软件做出贡献可以确保该软件对其他最终用户尽可能有价值。

如果您有兴趣了解有关 Git 的更多信息并在开源软件上进行协作,您可以阅读我们题为 An Introduction to Open Source 的教程系列。 如果您已经熟悉 Git,并且想要一份备忘单,可以参考“如何使用 Git:参考指南”。