本文旨在帮助新手小伙伴了解学习如何参与 GitHub 项目,为其献上自己的一份力,留下属于自己的足迹。
普遍流程
通过 fork 为项目做出贡献一个普遍的流程如下图:
sequenceDiagram participant 你 participant GitHub participant 项目拥有者 GitHub ->> 你: fork一个项目 你 ->> 你: 从 main 分支创建新分支 你 ->> 你: 提交一些修改来改进项目 你 ->> GitHub: 将新分支推送到 GitHub 上 你 ->> 项目拥有者: 创建一个拉取请求 (Pull Request) GitHub ->> 项目拥有者: 通知有新的拉取请求 项目拥有者 ->> 你: 讨论 PR 内容并提出修改建议 你 ->> 你: 根据反馈继续修改代码 你 ->> GitHub: 更新拉取请求 项目拥有者 ->> GitHub: 审核 PR alt 如果 PR 满意 项目拥有者 ->> GitHub: 合并拉取请求 GitHub ->> 你: 通知 PR 已合并 你 ->> GitHub: 将更新后的 main 分支同步到你的 fork 中 你 ->> GitHub: 删除你的分支 else 如果 PR 不满意 项目拥有者 ->> GitHub: 关闭拉取请求 GitHub ->> 你: 通知 PR 已关闭 end 你 ->> 你: 结束流程
使用 fork 和 pull request(简写为 pr,拉取请求) 一般是针对一个没有提交权限的项目,而你想要为它做出贡献(contribution)。这种方式被叫做 github workflow 或 fork and pull request workflow。
不用担心你的 push 会破坏原仓库,因为你工作在 forked 仓库的自建分支,并且要通过 pr 的审查才能使得你的贡献生效。
但不只是这种方式可以 contribute。
连接到 GitHub
在 GitHub 上工作
实际上,直接在 GitHub 上工作是做出贡献最快的方式,这不会涉及到任何 Git 命令,无需同步,在用户界面就能提交更改。但是这只能进行简单的操作,想要做出复杂的更改,可以选择使用 github.dev 或 GitHub Codespaces。github.dev
完全免费,但没有终端访问的功能,而GitHub Codespaces
虽然功能完善,但是每个人有每月使用限额。
在桌面工作
最常见的方式还是在本地的桌面进行工作,你可以在本地大展手脚。前提是你已经准备好必要的工作环境,比如安装好 Git 并设置了全局用户名和邮箱,如果想使用 SSH 协议连接 GitHub,还要配置 SSH 密钥。
环境配置
- 安装 Git
- 全局配置用户名和邮箱:
bash
git config --global user.name "username"
git config --global user.email "email"
- 配置 SSH 密钥:
bash
# 查看是否已有密钥
cd ~/.ssh
ls
bash
# 生成 SSH 密钥(默认在 ~/.ssh 文件下,一个以 .pub 结尾的公钥文件,一个私钥文件)
ssh-keygen -t ed25519 -C "your_email@example.com"

设置 passphrase(密码短语)可以增加一层安全保护。

bash
# 为了避免每次使用 SSH 密钥时都要输入 passphrase,将密钥添加到 ssh-agent
# 在管理员权限 PowerShell 窗口里手动启动 ssh-agent(当然也有自动方法)
Get-Service -Name ssh-agent | Set-Service -StartupType Manual
Start-Service ssh-agent
# 将你的 SSH 私钥添加到 ssh-agent
ssh-add c:/Users/YOU/.ssh/<你的私钥文件名>
工具使用
想要在本地与 GitHub 连接进行协作,有以下方式可供选择:
- 命令行形式(需要学习许多命令):
- Git Bash(Git for Window 的命令行界面)
- GitHub CLI:专门与 GitHub 交互的命令行工具,可以在本地就能发布 issue、进行 PR 的提交和审阅,还能编写脚本来自动化 GitHub 操作。
- 可视化界面:
- GitHub Desktop
- 其他软件:VSCode 的一些插件、Sourcetree 等
萝卜青菜,各有所爱。选合适自己的就行。本文是为了开拓视野,起一个铺路引导的作用,所以后面只介绍使用 Git Bash 和 Web 浏览器实现贡献流程,其他的方式可以查阅最后一节参考。
fork 仓库
有一个练手项目可以玩玩。

点击 Create a new fork:

Repository-name 后面可以追加 -你的用户名
,也可以不用。
Cope the main
branch only 复选框决定是否拷贝所有分支。
点击 create fork 后,你的仓库列表就会新增一项。
原仓库被叫做上游仓库(upstream repository)。
克隆仓库到本地
将你刚刚 fork 的仓库 clone 到本地:

bash
# 克隆 Spoon-Knife
git clone https://github.com/YOUR-USERNAME/Spoon-Knife.git
# 进入仓库
cd Spoon-Knife/
创建新分支
你应该从你想要修改的分支创建一个新分支来进行你的工作:
bash
git branch BRANCH-NAME
git checkout BRANCH-NAME
# 或者
git checkout -b BRANCH-NAME
推送步骤
修改文件:
bash
# 追加内容
echo 'my change' >> README.md
进行某类操作后,将其快照提交到 Git 仓库:
bash
git add .
git commit -m "a short description of the change"
推送前最好同步一下 fork,因为上游仓库大概率有更新,会与你的仓库产生冲突,因此执行以下代码去完成冲突的合并:
bash
# 查看配置的远程仓库
git remote -v
# 指定要同步的远程上游仓库
git remote add upstream https://github.com/ORIGINAL-OWNER/ORIGINAL-REPOSITORY.git
# fetch 上游仓库
git fetch upstream
# 查看本地默认分支
git checkout main
# 同步上游默认分支到你的默认分支,可能是快速合并(fast-forward,自动合并)或其它合并(手动合并)
git merge upstream/main
# 切换到你的分支
git checkout BRANCH-NAME
# 合并上游默认分支到你的分支(前面有冲突发生就进行这一步)
git merge upstream/main
# 开始推送
git push origin BRANCH-NAME --force
创建 PR
之前的一切处理完毕后,就到了真正做出贡献的一步了:提交 PR。
访问你的 fork 仓库,切换分支到你新建的分支。

打开 Contribute 下拉框,点击 Open pull request。

选择你的 base repository 和 head repository 以及它们中要合并的 base 分支 和 compare 分支,然后为这次 PR 提供一个标题概括其目的,还可以做一个较为详细的描述。

点击 Create pull request。等待审阅。
删除分支
如果 PR 被合并,建议删除你的分支以便以后再次提交新的 PR。
bash
# 删除远程分支
git push origin --delete BRANCH-NAME
# 同步上游主分支
git checkout main
git pull upstream main
git push origin main
# 删除本地分支
git branch -d BRANCH-NAMEh # 安全删除(仅当分支已合并)
git branch -D BRANCH-NAME # 强制删除(未合并时慎用)
参考
- GitHub 流 - GitHub 文档 --- GitHub flow - GitHub Docs
- 连接到 GitHub - GitHub 文档 --- Connecting to GitHub - GitHub Docs
- 为项目做出贡献 - GitHub 文档 --- Contributing to a project - GitHub Docs
- Fork 仓库 - GitHub 文档 --- Fork a repository - GitHub Docs
- 创建拉取请求 - GitHub 文档 --- Creating a pull request - GitHub Docs
- 关于拉取请求审查 - GitHub 文档 --- About pull request reviews - GitHub Docs
- 删除和恢复拉取请求中的分支 - GitHub 文档 --- Deleting and restoring branches in a pull request - GitHub Docs
- 起步-初次运行 Git 前的配置-Pro Git 2
- 服务器上的 Git-生成 SSH 公钥-Pro Git 2
- 生成新的 SSH 密钥并将其添加到 ssh-agent - GitHub 文档 --- Generating a new SSH key and adding it to the ssh-agent - GitHub Docs
- 使用 SSH 密钥密码 - GitHub 文档 --- Working with SSH key passphrases - GitHub Docs
- 同步分支 - GitHub 文档 --- Syncing a fork - GitHub Docs
- 配置分叉的远程仓库 - GitHub 文档 --- Configuring a remote repository for a fork - GitHub Docs