介绍
Git 是一个开源的分布式版本控制系统,它使协作软件项目更易于管理。许多项目将文件存储在 Git 仓库中,而像 GitHub 这样的平台则使代码共享和贡献变得便捷、高效且有价值。.
托管在公共存储库中的开源项目可以通过拉取请求从更广泛的开发者社区获得贡献,拉取请求会请求项目接受你对其代码存储库所做的更改。.
本教程将指导您如何通过命令行向 Git 存储库发出拉取请求,以便您可以为开源软件项目做出贡献。.
先决条件
您的本地计算机上必须安装 Git。本指南将帮助您检查计算机上是否已安装 Git,并引导您完成适用于您操作系统的安装过程。.
您还需要拥有或创建一个GitHub帐户。您可以通过GitHub网站github.com完成此操作,然后登录或创建您的帐户。.
截至 2020 年 11 月,GitHub 已移除基于密码的身份验证。因此,要通过命令行访问 GitHub 代码库,您需要创建个人访问令牌或添加您的 SSH 公钥信息。.
最后,你需要找到一个可以贡献代码的开源软件项目。你可以阅读这篇介绍了解更多关于开源项目的信息。.
创建存储库的副本
仓库(简称 repo)本质上是项目的根目录。仓库包含所有相关的项目文件,包括文档,并存储每个文件的编辑历史记录。在 GitHub 上,仓库可以有多位协作者,并且可以是公开的或私有的。.
要参与开源项目,首先需要获取代码仓库的副本。为此,你需要先 fork 该代码仓库,然后克隆它以获得本地工作副本。.
Fork 仓库
您可以通过在浏览器中访问您想要贡献的开源项目的 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”按钮开始 fork 过程。您将在浏览器窗口中收到一条通知,提示您正在 fork 的仓库正在处理中:
流程完成后,您的浏览器将跳转到与之前的仓库页面类似的页面,只是在页面顶部,您会在仓库名称之前看到您的用户名,并且在 URL 中,您也会在仓库名称之前看到您的用户名。.
所以,在上面的例子中,页面顶部的 do-community/cloud_haiku 会变成 yourusername/cloud_haiku,新的 URL 将如下所示:
https://github.com/your-username/cloud_haiku仓库 fork 完成后,就可以克隆它,从而获得代码库的本地副本。.
模拟存储库
要创建您自己的本地存储库副本,以便为之做出贡献,我们首先打开一个终端窗口。.
我们使用 git clone 命令以及指向您的仓库分支的 URL。.
这个 URL 与上面的 URL 相同,只是结尾变成了 .git。在上面的 cloud_haiku 示例中,URL 看起来会像这样,其中你的用户名会被替换成你实际的用户名:
https://github.com/your-username/cloud_haiku.git您还可以使用从与主仓库页面分离的仓库页面中的绿色«⤓ 代码»按钮复制 URL。单击该按钮后,您可以单击 URL 旁边的剪贴板按钮来复制 URL:
获取到 URL 后,我们就可以克隆仓库了。为此,我们在终端窗口的命令行中,将 `git clone` 命令与仓库 URL 结合起来:
git clone https://github.com/your-username/repository.git
创建一个新分支
在协作项目中,你和其他贡献代码的开发者会同时提出不同的新功能或修复方案。有些新功能实现起来很快,但有些则需要一些时间。因此,创建分支非常重要,它可以帮助你管理工作流程、隔离代码,并控制哪些功能最终会合并到项目主分支。.
项目代码库的初始分支通常称为主分支(master branch)。建议将主分支中的所有内容都保持可部署状态,以便其他人可以随时使用。.
注意:GitHub 于 2020 年 6 月更新了术语,将默认源代码分支称为 master 分支,而不是 master 分支。如果您的默认分支仍然显示为 master,您可以通过更改默认分支设置将其更新为 master。.
基于现有项目创建分支时,应从父分支创建新分支。此外,分支名称应具有描述性。例如,不要使用“my-branch”这样的名称,而应使用类似“frontend-hook-migration”或“fix-documentation-type”这样的名称。.
要在终端窗口中创建分支,我们需要将工作目录切换到代码仓库目录。请务必使用实际的代码仓库名称(例如 cloud_haiku)来切换到该目录。.
cd repository
现在,我们将使用 git branch 命令创建一个新分支。请确保给它起一个描述性的名称,以便项目的其他参与者知道你正在做什么。.
git branch new-branch
现在新分支已经创建完成,我们可以使用 git checkout 命令在其上进行工作:
git checkout new-branch
输入 git checkout 命令后,您将收到以下输出:
Output
Switched to branch 'new-branch'您还可以通过创建并切换到新分支来压缩上述两个命令,使用以下命令和 -b 标志:
git checkout -b new-branch
如果要恢复到原始状态,可以使用带有原始分支名称的 checkout 命令:
git checkout main
通过结账功能,您可以在多个分支之间切换,从而可以同时处理多个功能。.
此时,您可以修改分支中的现有文件或向项目中添加新文件。.
在本地做出改变
为了演示如何创建拉取请求,我们将使用 cloud_haiku 代码库示例,并在本地副本中创建一个新文件。请使用您喜欢的文本编辑器创建一个新文件,以便我们按照帮助文档中的说明添加新的俳句。例如,我们可以使用 nano 编辑器,并将示例文件命名为 filename.md。您应该使用文件名加上扩展名 .md 来命名您的文件,因为 .md 是 Markdown 格式。.
nano filename.md
接下来,我们将按照帮助文档的说明,向新文件中添加一些文本。我们需要使用 Jekyll 模板,并添加一首断行俳句。下面的文件是一个示例文件,您需要提供一首原创俳句。.
--- 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 提交可能如下所示。.
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 命令后,根据您使用的默认文本编辑器,终端窗口应该会显示一个供您编辑的文档,内容大致如下:
# 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
根据您所做的更改,您将得到类似于以下内容的输出:
Output
On branch new-branch
nothing to commit, working tree clean此时,您可以使用 git push 命令将更改应用到您 fork 的仓库的当前分支:
git push --set-upstream origin new-branch
此命令将输出结果以告知您进度,结果类似于以下内容:
Output
Counting 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 仓库,并导航到您推送的分支,在浏览器中查看您所做的更改。.
此时,可以向主存储库请求拉取更新,但如果您尚未这样做,则需要确保您的本地存储库与上游存储库保持同步。.
本地存储库更新
在与其他贡献者共同开发项目时,你需要保持本地代码库与项目同步,因为你不希望提交的拉取请求会导致代码冲突(尽管在共享代码项目中,冲突几乎不可避免)。为了保持本地代码库的更新,你需要同步更改。.
首先,我们将配置叉子的远程控制,然后同步叉子。.
配置叉子的遥控器
远程仓库允许您与他人协作处理 Git 项目。每个远程仓库都是项目的一个版本,托管在您有权访问的互联网或网络上。根据您的用户权限,每个远程仓库对您来说应该是只读或读写的。.
为了将你在 fork 中所做的更改与你正在使用的主仓库同步,你需要配置一个指向上游仓库的远程仓库。你只需要在上游仓库中设置一次远程仓库即可。.
我们先来检查一下你配置了哪些远程仓库。`git remote` 命令会列出你之前指定的所有远程仓库,所以如果你像上面那样克隆了你的仓库,至少会得到源仓库的输出,也就是 Git 为克隆目录设置的默认名称。.
在终端窗口的仓库目录中,我们使用带有 -v 标志的 git remote 命令来显示 Git 存储的 URL 及其对应的远程仓库短名称(例如“origin”):
git remote -v
由于我们模拟了一个存储库,因此我们的输出应该类似于这样:
Output
origin https://github.com/your-username/forked-repository.git (fetch)
origin https://github.com/your-username/forked-repository.git (push)如果您已经设置了多个远程仓库,git remote -v 命令将列出所有远程仓库。.
接下来,我们指定一个新的远程仓库来与 fork 版本同步。这个远程仓库就是我们 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 术语中,“upstream”指的是我们克隆的源仓库。如果我们想添加指向协作者仓库的远程指针,则可能需要提供该协作者的用户名或短别名作为简称。.
再次从仓库目录使用 git remote -v 命令,我们可以验证远程指针是否已正确添加到上游仓库:
git remote -v
Output
origin 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)现在你可以在命令行中引用上游,而无需输入完整的 URL,即可将你的 fork 与主仓库同步。.
同步分叉
一旦我们配置好指向 GitHub 上上游和主存储库的远程仓库,我们就可以同步我们的存储库分支以保持其最新状态。.
为了同步我们的 fork,我们在终端窗口的本地仓库目录中,使用 `git fetch` 命令从上游仓库获取分支及其对应的提交。由于我们使用了简称“upstream”来指代上游仓库,因此我们将该名称传递给命令。.
git fetch upstream
根据我们 fork 仓库后所做的更改次数,您的输出可能会有所不同,并且可能包含多行用于计数、压缩和解包对象的信息。您的输出最终将类似于下面的几行,但可能会根据项目中的分支数量而有所不同:
Output
From https://github.com/original-owner-username/original-repository
* [new branch] main -> upstream/main现在,对主分支的提交存储在名为 upstream/main 的本地分支中。.
让我们切换到本地仓库的 master 分支:
git checkout main
Output
Switched to branch 'main'现在,我们将通过本地上游/主分支访问的主仓库主分支所做的任何更改合并到本地主分支中:
git merge upstream/main
此处的输出会有所不同,但如果代码有更改或已是最新版本,则会首先显示更新信息。如果自您 fork 该仓库以来没有任何更改,则不会显示任何内容。.
您的分支的主分支现在与上游仓库同步,您所做的本地更改不会丢失。.
根据您的工作流程和修改代码所花费的时间,您可以根据需要随时将您的 fork 与主仓库中的上游代码同步。但您务必在提交 pull request 之前同步您的 fork,以确保不会自动推送冲突的代码。.
拉取请求
此时,您就可以向主仓库提交拉取请求了。.
你需要前往你的 fork 仓库,然后点击屏幕左侧的“新建 pull request”按钮。.
下一页可以切换分支。在每一侧,您都可以从下拉菜单中选择相应的仓库和分支。.
例如,当您在左侧选择主仓库分支,在右侧选择您新创建的分支时,应该会看到一个屏幕,提示您的分支可以合并。如果没有冲突的代码:
您需要在相应的字段中添加标题和评论,然后点击“创建拉取请求”按钮。.
此时,主代码库维护者将决定是否接受您的拉取请求。他们可能会要求您提交代码审查以编辑或修复代码,然后再接受您的拉取请求。.
结果
至此,您已成功向开源软件仓库提交了拉取请求。之后,在等待审核期间,请务必更新和修改您的代码。项目维护者可能会要求您修改代码,因此您应该做好准备。.
参与开源项目,成为一名活跃的开源开发者,是一件非常有意义的事情。定期为你经常使用的软件做出贡献,可以确保它对其他最终用户来说尽可能地有价值。.














