前言
此文是我近期尝试参与开源项目的经历,结合AI整理总结而来,分享给大家。希望给其他想要参与开源项目的朋友带来一点帮助。
目录
- [一、为什么参与开源前必须熟悉 Git 流程](#一、为什么参与开源前必须熟悉 Git 流程)
- [二、第一步:Fork 项目到自己的 GitHub](#二、第一步:Fork 项目到自己的 GitHub)
- [三、第二步:Clone 项目到本地](#三、第二步:Clone 项目到本地)
- [四、第三步:配置 upstream 上游仓库](#四、第三步:配置 upstream 上游仓库)
- 五、第四步:创建独立开发分支
- 六、第五步:修改代码后查看变更
- [七、第六步:提交 commit](#七、第六步:提交 commit)
- [八、第七步:推送分支到自己的 fork](#八、第七步:推送分支到自己的 fork)
- [九、第八步:在 GitHub 上创建 Pull Request](#九、第八步:在 GitHub 上创建 Pull Request)
- 十、第九步:同步上游仓库最新代码
- [十一、第十步:让开发分支跟上最新 upstream](#十一、第十步:让开发分支跟上最新 upstream)
- 十二、处理合并冲突
- [十三、常用 GitHub CLI 指令:gh 能帮我们做什么](#十三、常用 GitHub CLI 指令:gh 能帮我们做什么)
- 十四、参与开源时的几个好习惯
- 十五、常用命令速查表
- 十六、总结
一、为什么参与开源前必须熟悉 Git 流程
很多同学第一次参与开源项目时,最容易卡住的地方并不是代码本身,而是 Git 和 GitHub 的协作流程。
- 项目应该 clone 谁的仓库?
- 为什么要 fork?
origin和upstream是什么?- 修改代码前为什么要新建分支?
- commit 后为什么还要 push?
- PR 提交后,原项目更新了怎么办?
- 出现 conflict 应该怎么处理?
这些问题看起来零散,但其实都属于同一条工作流。参与开源项目,本质上通常是:
text
fork 项目 -> clone 到本地 -> 创建分支 -> 修改代码 -> commit -> push -> 提交 PR -> 根据反馈继续修改
下面就按照这个顺序,把常用的 Git 和 GitHub 指令整理一遍。
二、第一步:Fork 项目到自己的 GitHub
参与别人的开源项目时,一般不会直接往原仓库提交代码,而是先点击 GitHub 页面右上角的 Fork。
Fork 之后,你的账号下会出现一份项目副本,例如:
text
原仓库:github.com/owner/project
你的 fork:github.com/yourname/project
后续我们通常把代码推送到自己的 fork,再从自己的 fork 向原仓库提交 Pull Request。
三、第二步:Clone 项目到本地
Fork 完成后,把你自己账号下的仓库 clone 到本地:
bash
git clone https://github.com/yourname/project.git
进入项目目录:
bash
cd project
查看当前远程仓库:
bash
git remote -v
你会看到类似结果:
text
origin https://github.com/yourname/project.git (fetch)
origin https://github.com/yourname/project.git (push)
这里的 origin 指的是你自己的 fork 仓库。
四、第三步:配置 upstream 上游仓库
因为你的 fork 只是原项目的副本,原项目后续还会继续更新。为了方便同步原项目代码,我们一般会添加一个 upstream。
bash
git remote add upstream https://github.com/owner/project.git
再次查看远程仓库:
bash
git remote -v
正常情况下会看到:
text
origin https://github.com/yourname/project.git (fetch)
origin https://github.com/yourname/project.git (push)
upstream https://github.com/owner/project.git (fetch)
upstream https://github.com/owner/project.git (push)
简单理解:
origin:你自己的 fork,用来 push 代码。upstream:原始开源项目,用来同步最新代码。
五、第四步:创建独立开发分支
不要直接在 main 或 master 分支上改代码。更推荐为每个 issue 或功能创建一个单独分支。
bash
git checkout -b fix-issue-123
或者使用新版本 Git 的写法:
bash
git switch -c fix-issue-123
分支名建议简短清晰,例如:
text
fix-doc-typo
fix-login-error
add-user-cache
update-readme-example
这样做的好处是:每个 PR 的改动范围更清楚,也方便后续维护。
六、第五步:修改代码后查看变更
修改代码后,先查看工作区状态:
bash
git status
查看具体改了什么:
bash
git diff
如果只想查看某个文件的改动:
bash
git diff path/to/file
这是一个很重要的习惯。提交前一定要确认自己没有带入无关改动,比如格式化了整个项目、误删文件、改了本地配置等。
七、第六步:提交 commit
确认改动没问题后,把需要提交的文件加入暂存区:
bash
git add path/to/file
如果确实要提交当前所有改动,可以使用:
bash
git add .
但初学者更建议谨慎使用 git add .,因为它可能把不相关文件也加进去。
提交 commit:
bash
git commit -m "fix: correct typo in README"
commit message 建议说明"做了什么",不要写得太随意。例如:
text
不好:update
不好:fix bug
较好:fix: handle empty response in parser
较好:docs: update installation guide
很多开源项目会有自己的 commit 规范,提交前最好先看项目的 CONTRIBUTING.md 或 README。
八、第七步:推送分支到自己的 fork
本地 commit 之后,还需要把分支 push 到自己的 GitHub fork:
bash
git push origin fix-issue-123
如果是第一次推送这个分支,也可以写成:
bash
git push -u origin fix-issue-123
-u 的作用是建立本地分支和远程分支的追踪关系。之后再 push,可以直接使用:
bash
git push
九、第八步:在 GitHub 上创建 Pull Request
push 成功后,打开 GitHub 页面,通常会看到 Compare & pull request 按钮。
创建 PR 时要注意:
- base repository:原始开源项目。
- base branch:通常是
main,也可能是master或项目指定分支。 - compare branch:你 fork 里的开发分支。
PR 描述里建议写清楚:
- 解决了哪个 issue。
- 主要改了什么。
- 怎么测试的。
- 是否有未解决的问题。
如果 PR 对应某个 issue,可以在描述里写:
text
Fixes #123
当 PR 合并后,GitHub 会自动关闭对应 issue。
十、第九步:同步上游仓库最新代码
开源项目一直在变化。你开始开发前,或者 PR 等待 review 的过程中,原仓库可能已经更新了。
先拉取 upstream 的最新代码:
bash
git fetch upstream
切回主分支:
bash
git checkout main
或者:
bash
git switch main
合并上游最新代码:
bash
git merge upstream/main
再把更新后的主分支推送到自己的 fork:
bash
git push origin main
注意,有些老项目主分支叫 master,对应命令要改成:
bash
git merge upstream/master
十一、第十步:让开发分支跟上最新 upstream
如果你已经在开发分支上写了代码,而原仓库又更新了,可以把开发分支同步到最新主分支。
先切到开发分支:
bash
git switch fix-issue-123
方式一:使用 merge:
bash
git merge upstream/main
方式二:使用 rebase:
bash
git rebase upstream/main
简单理解:
merge:保留合并记录,操作相对直观。rebase:提交历史更线性,但处理冲突时对初学者稍微复杂。
如果不确定项目偏好,先看贡献指南;如果没有明确要求,初学者可以先使用 merge。
十二、处理合并冲突
当多人修改了同一段代码,就可能出现冲突。Git 会在文件里标记冲突内容:
text
<<<<<<< HEAD
你的代码
=======
别人的代码
>>>>>>> upstream/main
处理冲突的基本步骤是:
- 打开冲突文件。
- 判断应该保留哪部分代码,或者手动合并两边逻辑。
- 删除
<<<<<<<、=======、>>>>>>>这些标记。 - 重新运行测试。
- 添加并提交冲突解决结果。
bash
git status
git add path/to/conflict-file
git commit
如果你是在 rebase 过程中遇到冲突,解决后通常执行:
bash
git add path/to/conflict-file
git rebase --continue
如果发现自己处理乱了,不要急着乱删文件,可以先查看状态:
bash
git status
必要时可以中止当前 rebase:
bash
git rebase --abort
十三、常用 GitHub CLI 指令:gh 能帮我们做什么
除了 Git 本身,GitHub 还提供了官方命令行工具 GitHub CLI,对应命令是 gh。
登录 GitHub:
bash
gh auth login
查看登录状态:
bash
gh auth status
查看 issue:
bash
gh issue view 123
查看 issue 评论:
bash
gh issue view 123 --comments
查看 PR:
bash
gh pr view 456
查看 PR diff:
bash
gh pr diff 456
把某个 PR 拉到本地:
bash
gh pr checkout 456
查看 PR 检查结果:
bash
gh pr checks 456
查看 GitHub Actions 日志:
bash
gh run view --log
gh 不是必须工具,但如果你经常参与开源项目,它会很方便,尤其适合查看 PR、issue、CI 失败日志和 review 状态。
十四、参与开源时的几个好习惯
第一,开始前先读项目文档。
重点看:
README.mdCONTRIBUTING.md- issue 里的维护者评论
- PR 模板
- CI 配置
第二,一个 PR 只解决一个明确问题。
不要在修 bug 的同时顺手重构一堆无关代码,也不要把格式化整个项目和业务修改混在一起。维护者 review 时最怕这种大而杂的 diff。
第三,提交前自己先检查 diff。
bash
git status
git diff
git diff --stat
第四,尽量写清楚 PR 描述。
不要只写一句:
text
fix issue
更好的写法是:
text
## What changed
- Fixed empty response handling in parser.
- Added a focused regression test.
## Tests
- pytest tests/test_parser.py
Fixes #123
第五,不要随意强推公共分支。
如果你只是自己的 PR 分支,必要时可以按照项目要求 force push;但如果是多人协作分支,就要非常谨慎。
bash
git push --force-with-lease
相比 --force,--force-with-lease 更安全一些,因为它会检查远程分支是否被别人更新过。
十五、常用命令速查表
| 场景 | 命令 |
|---|---|
| 克隆仓库 | git clone <repo-url> |
| 查看远程仓库 | git remote -v |
| 添加上游仓库 | git remote add upstream <repo-url> |
| 创建分支 | git checkout -b <branch> |
| 切换分支 | git switch <branch> |
| 查看状态 | git status |
| 查看改动 | git diff |
| 添加文件 | git add <file> |
| 提交改动 | git commit -m "message" |
| 推送分支 | git push origin <branch> |
| 拉取上游更新 | git fetch upstream |
| 合并上游主分支 | git merge upstream/main |
| rebase 到上游主分支 | git rebase upstream/main |
| 查看提交记录 | git log --oneline |
| 查看 PR | gh pr view <number> |
| 查看 issue | gh issue view <number> |
| 查看 PR 检查 | gh pr checks <number> |
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,你们的支持就是我坚持下去的动力!