引言 #
Working on [freenode] helped me earn many of the skills I later used for my studies in university and my actual job. I think working on open source projects helps me as much as it helps the project!
— @errietta, “Why I love contributing to open source software”
首先尝试开源之前,强烈推荐阅读 Open Source Guides (附有多种语言),下文很多做法也是借鉴于这个手册。
另外非常推荐尝试下面这个 first-contributions 这个项目进行提交,下文也会以这个项目为例,进行一次 contribution 的提交。
🚀✨ Help beginners to contribute to open source projects
那么就让我们开始吧!🚀
Contribute 前的准备工作 #
在某一个开源项目扎根多年,这意味着你只是对这一个开源项目无比的熟悉。若是切换到不同的项目,可能会发现完全是另外一回事,所谓的使用词汇、习惯用语、沟通方式都发生了变化。
所以先不要着急提交,先了解一个项目。
在准备贡献之前,如果你有一个好的想法,做一些快速的检查项(issue、pr),以确保没有人讨论过你的想法。
- 如果没有人提这个 issue,先创建一个 issue:
- 报告你自己无法解决的错误
- 讨论一个高级主题或想法(例如. 社区、远景、政策等)
- 期望实现某新的特性,或者其它项目的想法
- 如果刚好有一个开放的 issue,和你不谋而合:
- 添加评论,告诉他人你将负责这个。这样的话,可以避免他人重复劳动。
- 如果说某个 issue 已经开放很久了, 这可能是已经有人正在解决中,又或者是早已经解决过了,所以也请添加评论,在打算开启工作之前,最好是确认一下。
- 如果你创建了一个 issue,但是没多久自己解决了, 也要添加评论,让其他人知道,然后关闭该 issue。记录本身就是为社区的贡献。
Contribute 步骤 #
下面会以 first-contributions 这个项目为例,进行提交。
1. Fork(复制)远程代码仓库 #
点击图示中的按钮去 Fork 这个代码仓库。 这个操作会将代码仓库复制到你的账户名下。
2. Clone(克隆)代码仓库到本地 #
使用 git clone
命令将 fork 的代码仓库克隆到本地,
进入到本地仓库的目录。
git clone "your fork repo"
cd "your fork repo"
3. 💥💥【关于同步】(理论内容,但是很重要!)💥💥 #
首先,我们有 3 个不同的存储库:在 Github 上的公共存储库 github.com/firstcontributions/first-contributions.git
、在 GitHub 上对该存储库的 fork github.com/Your-Name/first-contributions/
以及 本地计算机存储库。这种合作对于开源项目来说是典型的,称为 Triangle Workflows。
为了使你的两个 repo 与远端的公共存储库保持同步,首先必须获取公共存储库并将其与您本地计算机的存储库合并。我们的第二步是将您的本地存储库推送到您的 GitHub fork。之后,从你的 fork 请求 “pull request”。
在操作中注意以下几个原则:
- 对别人的项目贡献PR,要用自己的 feature-branch。
- 每次准备 coding 之前保证自己的本地的 main-branch 是已经同步上游仓库的(目的是使新建的 feature-branch 是最新的)。
- 自己的 fork repo 的 main-branch 不一定要是最新的,一般都是落后上游并从不更新(因为每次更新和 push 都是用 feature-branch)。
- 每次修改完 feature-branch,要再次同步上游仓库,保证之后的 pr 没有冲突(降低冲突概率,也可能会有)。
所以可以看出为了避免 conflict(将 conflict 处理于本地),整个提交 pr 的过程中会涉及两次同步。
- 第一次是准备 coding 之前(新建 featur-branch 之前),保证 main/feature branch 同步(这次可以采用
git reset --hard origin/master
,强制同步,下文会讲)。 - 第二次是准备 push 之前, 保证 feature-branch 同步(这次采用
git merge
, 处理conflict)。
所以一直在保持同步上游仓库的分支,理论上只有 featur-branch,而 main-branch 只有在下次要提交新的 pr 之前再同步(当然,你也可以在对方接受了 pr 之后,找个时间同步一下 main-branch,什么时候都好。)
如果想了解同步的更多方式,可以查阅 :
4. 在本地的仓库配置”上游”为远端仓库 #
执行命令 git remote
查看你的远程仓库的路径:
git remote -v
你可以查看当前本地仓库中已经配置的远程仓库地址。通常,你会看到 origin 对应的是你 fork 的仓库。
如果只有上面2行,说明你未设置 upstream (中文叫:上游代码库)。一般情况下,设置好一次 upstream 后就无需重复设置。
此时你应该是在你的 main-branch,如果不放心可以使用 git branch
, 查看当前命令。
执行命令 git remote add upstream
把远端的仓库设置为你的 upstream 。这个命令执行后,没有任何返回信息;所以再次执行命令 git remote -v 检查是否成功。
$ git remote add upstream https://github.com/firstcontributions/first-contributions
执行后显示:
5. 同步本地的仓库与上游仓库(第一次同步) #
切记,这步一定要在本地的 main-branch 分支执行,如果不确定,就使用
git branch
查看当前分支, 使用git checkout main
切换到 main-branch。
- 获取上游仓库的最新更改:
git fetch upstream
该命令从上游仓库(upstream)获取所有分支和最新的提交,但不会自动合并或修改本地分支。
- 重置(强制同步)本地 main-branch:
git reset --hard upstream/main
Q:上游的主分支是
upstream/main
还是upstream/master
?A:由于历史原因,2020年,为了消除术语中的潜在歧视性含义,Git 项目和许多开源社区决定将默认主分支名称从 master 改为 main。
所以在使用git reset --hard
之前可以先使用git branch -r
查看上游所有分支,查看 upstream 的默认主分支是 main 还是 master。
5. 新建分支 #
新建一个新的分支,在新的分支上进行开发,确保 main 分支保持同步且不受干扰。这使得 main 分支可以随时用于同步最新的上游代码。
新建分支并且切换到新分支:
git branch add-myname
git checkout add-myname
或者直接使用:
git checkout -b add-myname
新建分支名字时,确保清晰、易于理解,区分 issue 和 feature。例如:
feature/add-user-authentication
fix/issue-1234-bug-fix
update/readme-improvements
hotfix/production-bug-fix
6. 对代码进行修改,然后 Commit (提交) 修改 #
在本文的例子中,
打开 Contributors.md
这个文件,更新文件内容,将你的名字加上去,保存修改。git status
这命令会列出被改动的文件。接着 git add
这命令则可以添加你的改动。
现在就可以使用 git commit
命令 commit 你的修改了。
git commit -m "Add <你的名字> to Contributors list"
将 <你的名字>
替换成你的名字
之后就可以使用 git push
命令, 将新分支推送到 fork 仓库:
git push origin add-myname
现在你的 fork repo 应该就会有你已经提交的新分支和内容。
你可以重复此步,来不断修改代码、推动代码到自己的 fork 仓库,根据不同情况,这个过程可能会持续很久,或者一次就好。
如果你已经完成了修改,准备好进行 pr 了,那么往下看。
(加油!就快完事了😀)
7. pr 之前,再次同步本地的分支与上游仓库(第二次同步) #
因为你在修改代码的过程中,可能远程仓库已经有所更改。
这步就是为了避免 pr 之后再解决 conflict 的问题,而是在提交之前,讲 conflict 解决在本地。
- 在 feature 分支上直接从上游仓库获取最新的更新:
git fetch upstream
- 将上游仓库的最新更改合并到 feature 分支:
git merge upstream/main
- 解决冲突(如果有):
如果在合并过程中遇到冲突,手动解决冲突。
- 继续 merge:
git merge --continue
8. 再次 Commit (提交) && Push(推送) #
类似 第6步, 将分支代码 push 到 fork repo。
git add .
git commit -m "new feature"
git push origin add-myname
9. 提出 Pull Request 将你的修改供他人审阅 #
前往你的 Github 代码仓库,你会看到一个 Contribute
的按钮。点击该按钮,之后点击 OPen pull request
。
接着可以填写 Pull Request 表单,描述你的 pr,接着再点击 Create pull request
按钮,正式提交 pull request。
之后便可以在远程仓库中看到你的 PR。
而且能在里面看到你之前的 commit。
当你提交了之后会发生什么 #
在你提交了贡献之后,下面几种情形是可能发生的:
😭 没有人响应你。 #
即使在一个活跃的项目中,你的贡献也有可能得不到响应。
如果过去了一周,依旧没有人响应,请心平气和的在后面跟帖,询求他人帮助你审核。如果你熟悉某个人可以审核你的贡献,你可以使用@+名字,直接提醒他一下。
如果你做了所有该做的事情,还是没有人理你,那就是真的没有人对你的贡献做出响应。这可能令人难受,但是千万不要灰心,每个人都会遇到这样的情况。你没有得到回复的原因有很多,包括你无法控制的个人情况。再接再厉,试着寻找另一个项目或方式来做出贡献。
🚧 有人要求你对自己的提交做出变更。 #
被要求修改你的提交是很常见的,无论是对你的想法的反馈,还是对你代码的改动。
当有人提出变更时,请及时响应。他们花时间审核了你的提交,要尊重他们。开启 PR 然后一走了之是一种恶习。如果你不知道如何修改,请花时间深入研究,并在需要时寻求他人帮助。
如果你没有时间继续处理这个 issue(举例来说,如果对话持续了几个月,而你情况有变),那么请告知维护者你无法再及时响应了。或许有其他人乐意接手你的工作
👎 你的贡献没有被接受。 #
你的贡献最终可能被接受,也可能不被接受。真心希望你没有为此花费太多力气。如果你不确定为什么它不被接受,请维护者提供反馈和说明是完全合理的。但最终,无论如何,你都要对他们的决定表示尊重。不要去无谓的争论或者显露敌意。如果你坚持自己,你仍可以 fork 项目,按照自己的思路来发展分支。
🎉 你的贡献被采纳。 #
太棒了!你已经成功地完成了一次开源贡献!
PR 九步: #
# Step 1: Fork(复制)远程代码仓库
# Step 2: Clone(克隆)代码仓库到本地
git clone https://github.com/your-name/fork-repo.git
cd fork-repo
# Step 3: 查看远程仓库路径确认添加成功
git remote -v
# Step 4: 添加上游仓库作为 upstream
git remote add upstream https://github.com/upstream-owner/original-repo.git
git remote -v
# Step 5: 同步本地主分支与上游主分支
git fetch upstream
git reset --hard upstream/main # 或者 upstream/master
# Step 6: 新建一个特性分支进行开发
git checkout -b feature-branch
# 在 feature-branch 上做一些更改和提交
# Step 7: 再次同步本地分支与上游仓库的主分支
git checkout feature-branch
git fetch upstream
git merge upstream/main # 或者 upstream/master
# Step 8: 将特性分支推送到你的 Fork 仓库
git add .
git commit -m "new feature"
git push origin feature-branch
# Step 9: 在 GitHub 上创建 Pull Request
# - 导航到你的 Fork 仓库页面,选择 feature-branch 分支
# - 点击 "Pull Request" 按钮,创建 PR 到 upstream 的主分支
# - 填写 PR 标题、描述,提交 PR
# 请确保在每个步骤执行前理解并确认操作的正确性,特别是在涉及重置和合并的步骤中。
参考资料 #
how-to-contribute-to-open-source
How To Get Started In Open Source