GitHub 使用 Fork 和 PR 进行协作的标准流程
本文介绍了在 GitHub 上通过 Fork 和 Pull Request (PR) 进行非协作者协作的标准工作流。主要步骤包括:Fork 目标仓库、克隆到本地、配置上游远程仓库 (Upstream)、创建新分支、修改文件并提交、推送至个人仓库,最后发起 PR 请求合并。文章详细解释了 git fetch 与 pull 的区别,以及 PR 提交后的审查流程,旨在帮助新手规范参与开源项目贡献。

本文介绍了在 GitHub 上通过 Fork 和 Pull Request (PR) 进行非协作者协作的标准工作流。主要步骤包括:Fork 目标仓库、克隆到本地、配置上游远程仓库 (Upstream)、创建新分支、修改文件并提交、推送至个人仓库,最后发起 PR 请求合并。文章详细解释了 git fetch 与 pull 的区别,以及 PR 提交后的审查流程,旨在帮助新手规范参与开源项目贡献。

在使用 GitHub 进行多人协作时,通常存在两种情况:一是作为仓库协作者,可直接创建分支;二是未被选为协作者,需通过提交 Pull Request (PR) 请求合并修改。本文以向非协作者仓库提交资料为例,演示标准的 Fork 和 PR 工作流程。
进入目标仓库页面,点击右上角的 Fork 按钮复刻仓库。成功后,该仓库将出现在您的个人账号下。

成功后会在我们的个人仓库中创建一个目标仓库的 fork 仓库。

现在 fork 后的仓库已属于我们,而左上角可明显看到'复刻自...仓库'。
由于页面操作在实际工作流中有诸多不便,因此我们在添加或修改仓库中文件代码时,一般需要提前将仓库 clone 到本地。这一系列步骤就是我们熟悉的 git clone 了。

在本地选择一个目录,输入对应的 git clone "fork 仓库的 URL"。
注意!这里 clone 的仓库是我们 fork 后的仓库,而不是原来的仓库!由 URL 可以看出仓库的所有者已经是我,而不是原仓库的所有者。 现在 clone 成功后便可在本地查看该仓库的所有文件:


将仓库 clone 到本地后,我们还需要对该本地仓库进行相关的初始配置,以便于后续获取仓库的更新等。
使用命令关联原始仓库为上游:
git remote add upstream 目标仓库 URL

关联原始仓库后,我们便可以更为方便地随时获取原始仓库的更新情况。 举个例子,我们 Fork 并在本地克隆了仓库,但在我们修改代码的这段时间,原始仓库的其他贡献者提交了新的内容并被维护者合并了,那我们本地的文件版本就比原始仓库旧了。如果没有 upstream 这个连接,我们将很难获取到原始仓库的最新变化;而有了 upstream,我们可以轻松地执行相关命令,让本地仓库保持最新。
如以下命令:
# 从原始仓库(upstream)获取最新数据
git fetch upstream
# 将原始仓库 main 分支的最新内容合并到你本地的 main 分支
git checkout main
git merge upstream/main
执行相关命令后,便可获取原始仓库的最新文件更新。
这时候一些新手朋友或接触过 git 工具的朋友可能就会觉得,该步骤相关命令的作用和平时使用的 git pull 挺像的,都是拉取仓库的最新状况,这两者有什么区别呢?
首先 git pull 命令实际上是两个命令的结合:git fetch + git merge 或 git rebase,也就是包含两个主要动作下载 + 合并。而合并便有可能产生冲突,即如果原始仓库的更新和本地的修改在同一个文件或同一行,Git 会自动触发合并(Merge)或冲突(Conflict)。 而 git fetch 则只是单纯的下载,因此它只会将原始仓库的最新数据下载到本地 Git 仓库中,但不会自动修改你当前工作目录中的任何文件。
我们平时使用的单纯的 git pull 默认形式其实为 git pull origin main,也就是将我们自己的仓库的仓库拉取到 main 分支合并。
一般来说,在工作流中克隆到本地后的 main 都是最新的,但为确保严谨,还是需要对主分支进行更新。
git checkout main # 将分支切换到主分支
git pull upstream main # 拉取原仓库的 main 分支,合并到我们本地 fork 仓库的 main 分支

按协作规范,我们一般不会直接在 main 分支上对项目进行修改,而是使用命令新建一个自己的分支。
git checkout -b your-contribution-name # checkout -b 可创建新分支并直接切换至该新创建的分支
git branch # 该命令用于查看当前的分支情况

我这边创建的新分支名为 ckys-add,绿色字体和左边的星号代表目前我正处于 ckys-add 分支。
现在我们已成功配置了仓库的信息并创建了一个新分支,因此算是做完了所有的准备工作。接下来便是正式对仓库的文件进行修改。
在该步骤中你可以将自己的代码添加进仓库,或是修改项目中的代码,进行任何你想要的增删查改。 在本示例中,我只是简单地将一些新的文件添加到了该仓库中。
我这边将图中的相关文件添加进了相关目录。
对项目的修改进行完毕后便是我们最熟悉的 add+commit+push 三板斧了。这里稍微值得注意的是,在标准的多人协作中,commit 的信息一般需要遵守相应的格式,如 conventional commit 规范。对于 conventional commit 规范我在这里并不详细说明,读者可自行在访问官网 Coventional Commit,或是社区搜索各个大佬分享的博客。

现在我们需要推送分支到我们的 GitHub 仓库 (origin),即我们 fork 出来的那个仓库,即执行以下命令:
git push origin ckys-add
对于该命令有两个选项:
现在我们返回 github 网页,进入我们的 fork 仓库,可以看到这里仓库名称下方出现了比较 & 拉取请求按钮,说明仓库已经检测到了我们通过 ckys-add 分支 push 了新的推送,可以进行拉取请求(pull request)操作了。

点击比较 & 拉取请求按钮后,我们会看到如下页面,在该页面的顶部会出现四个重要信息,这里我在图中已经框中并标号了,分别为基础仓库(base repository)、基础分支(base branch)、头部仓库(head repository)、比较分支(compare branch)。

对四个配置信息进行简单解释:
| 配置项 | 显示内容 | 解释 |
|---|---|---|
| base repository | HDU-Course/HDU-FinalExamPaper | 目标仓库,即我们的贡献最终要去的地方,也就是原始仓库。 |
| base branch | main | 目标分支:原始仓库默认接收贡献的分支(默认通常是 main,但也可以是其他分支)。 |
| head repository | C-KyS/HDU-FinalExamPaper | 来源仓库:这是我们推送了修改的仓库(你的 Fork)。 |
| compare branch | ckys-add | 来源分支:这是我们进行了修改的那个分支。 |
通过这四个信息我们可以完成最终的 PR 提交确认。
在上张图片的中间,我们可以看到添加标题和添加描述的按钮填写框,在这里我们需要详细说明我们修改的功能改动和实现思路,同时严格的话还需要 @ 项目评审,等待评审人员的 review 和留言。
确认无误后,点击绿色的 创建拉取请求 (Create pull request) 按钮,提交成功。

在提交成功后,页面上方的菜单栏中有四个功能可供我们查看,分别为讨论(Conversation)、提交(Commits)、检查(Checks)、更改的文件(Files changed)。

该页面是第一个主视图,也就上图所展示的,用于沟通和状态概览。

这里按时间顺序显示我们在这个分支(我这里是 ckys-add 分支)上做的所有 git commit 记录。
这里在规范的仓库中一般会有自动化检查成果 (CI/CD),所有的自动化测试、格式检查等流水线的结果会在这里显示。

该页面用于显示我们提交的文件与目标分支之间的所有差异。 评审者通常会在这里对文件的特定行进行评论(即 Thread/会话)。当我们处理完一个意见后,我们会回到'Conversation'标签页点击'Resolve conversation'关闭它。


微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online