本文作者:Daniel Hu
个人主页:https://www.danielhu.cn/
一、概述
明天我筹备和你具体介绍如何开始参加开源我的项目,帮忙你在 GitHub 上实现第一个 PR 的合入。
当然,除了失常的 PR 合入流程之外,我还筹备具体介绍一下如果一个 PR 提交后遇到了抵触、须要追加 commits、须要合并 commits 等等绝对简单问题该如何解决。
总的来说,本文打算分为 4 个局部:
- 谈谈为什么要参加开源我的项目以及我为什么要介绍如何 PR
- 谈谈怎么开始参加开源我的项目,也就是如何寻找适合的开源我的项目、如何寻找奉献点
- 介绍怎么上手 PR 流程,即从 fork 到 push 全流程
- 介绍提交了 PR 之后遇到各种常见问题如何解决
Ok, let’s get started!
二、为什么要参加开源我的项目
本文我不打算简明扼要“为什么要参加开源”,具体介绍参加开源我的项目的播种,我想仅从“晋升编码能力”角度谈一谈“为什么要参加开源我的项目”。
在面试的时候我有个习惯,如果候选人在本人的简历里说到本人相熟某一门语言,我就会习惯性问他一个问题:
你有没有浏览过某个开源我的项目的源码?或者更进一步,有没有参加过某个开源社区,或者说给开源我的项目提过 PR?
如果答案是必定的,比方候选人说本人读过局部 Kubernetes 模块的源码,再进一步我确认他真的读过并且读懂了或者说真的提交过 bugfix/feature 类型的 PR,那我就不再问编程语言层面的问题了,因为我置信能看懂一个成熟的开源我的项目局部模块源码或者可能提交 bugfix/feature 类型的 PR 曾经阐明了所有。
我本人在学习 Golang 的时候,大抵分为两个阶段:
- 学习根底语法,开始写我的项目,直到可能纯熟实现各种业务性能的开发;
- 看了一些开源我的项目的源码,深感受害颇多,编码程度再上一个台阶。
差不多也就是在看 Kubernetes 我的项目源码的时候,我粗浅意识到个别的企业外部我的项目和会集全世界最优良的程序员智慧结晶的开源我的项目之间的微小差距,也意识到学习优良开源我的项目源码对于一个程序员编码程度晋升的重要性(当然,你能够说 Google 外部也存在非开源的十分优良的代码,这毫无疑问,然而我想明天咱们没有必要探讨特例)。
认真浏览开源我的项目源码,你总会发现一些小瑕疵,这时候提一个 PR(Pull Request),让你的代码合入开源我的项目,运行在“世界每一个角落”,那是如许乏味的事件!而胜利合入第一个 PR 往往就像关上潘多拉魔盒一样,你会进入到另外一个世界,开始接触到开源社区,感触开源的魅力!
三、为什么我想介绍如何 PR
我司开源了 2 个我的项目,别离是:
- CNCF Project DevStream
- Apache DevLake
DevStream 我的项目和 DevLake 我的项目隔三差五就会有新贡献者提交 PR 过去,然而少数贡献者在提交第一个 PR 时往往会遇到一个或多个问题,比方产生抵触、commits 记录过多或者凌乱、commit 没有签名、commit message 不标准、各种 ci 流程查看报错等等。
在看到新贡献者提交 PR 时,咱们天然是十分开心且激情地对他示意欢送并且告知如何修复各种问题,然而随着贡献者的增多,咱们的开源社区简直每天都须要答复一个问题:“如何正确地提交一个 PR”。可能此时你会开始狐疑咱们是不是没有提供相应的文档?其实不然,咱们有具体的文档,然而人总是有惰性的,少数的新贡献者并没有足够的志愿去认真看翻看文档而后再提交 PR,甚至很多新贡献者因为刚开始接触开源我的项目,对于我的项目构造和文档组织构造比拟生疏,甚至不会想到有这些文档的存在,总之各种各样的理由让少数的新贡献者会抉择“先提了 PR 再说”。
那么明天我想尝试彻底讲明确“如何正确地提交一个 PR”,尝试细说 GitHub 上的 PR 全过程,以及这外面可能会遇到的各种艰难和解决办法。一方面心愿对第一次参加开源我的项目的新人有所帮忙,另一方面心愿可能进一步升高 DevStream 社区和 DevLake 社区的参加门槛。
四、我想参加开源我的项目,怎么开始?
不论你为什么决定开始参加开源我的项目,不论出发点是出于学习、趣味、成就感等等,还是为了让某个本人须要的个性合入某个开源我的项目,总之明天你下定决心,要给某个开源我的项目提交一个 PR 了,好,咱们开始吧!
4.1、寻找一个适合的开源我的项目
如果你曾经决定参加某个开源社区了,那么请间接跳过本大节。
如果你就只是想开始参加开源,临时还不晓得该参加哪个社区,那么我有几个小倡议:
- 不要从特地成熟的我的项目开始。比方当初去参加 Kubernetes 社区,一方面因为贡献者太多,很难抢到一个入门级的 issue 来开始第一个 PR;另外一方面也因为贡献者太多,你的声音会被吞没,社区维护者并不在意多你一个或者少你一个(当然可能没有人会抵赖,然而你不得不信),如果你提个 PR 都遇到了各种问题还不能自己独立解决,那么很可能你的 PR 会间接超时敞开,没有人在意你是不是有一个好的参加体验;
- 不要从特地小的我的项目开始。这就不须要我解释了吧?很晚期的开源我的项目可能面临着十分多的问题,比方代码不标准、合作流程不标准、重构频繁且不是 issue 驱动的,让内部参与者莫衷一是……
- 抉择出名开源软件基金会的孵化我的项目,这类我的项目一方面不是特地成熟,所以对新贡献者敌对;另一方面也不会特地不成熟,不至于给人很差的参加体验,比方 Apache 基金会、Linux 基金会、CNCF 等。
比方能够从这些中央寻找本人感兴趣的开源我的项目:
- CNCF 沙箱我的项目
- CNCF 孵化我的项目(列表包含毕业我的项目)
- Apache 我的项目(孵化期我的项目名字中带 Incubating)
当然,你也能够间接抉择从 CNCF 沙箱我的项目 DevStream 或者 Apache 孵化我的项目 Apache DevLake,以此敲开开源世界的大门。
4.2、寻找奉献点
开源我的项目的参加形式很多,最典型的形式是提交一个个性开发或者 bug 修复相干的 PR,然而其实文档欠缺、测试用例欠缺、bug 反馈等等也都是十分有价值的奉献。不过本文还是从须要提 PR 的奉献点开始上手,以 DevStream 我的项目为例(其余我的项目也一样),在我的项目 GitHub 代码库首页都会有一个 Issues 入口,这里会记录我的项目目前已知的 bug、proposal(能够了解成新需要)、打算补充的文档、亟需欠缺的 UT 等等,如下图:
在 Issues 里咱们个别能够找到一个“good first issue”标签标记的 issues,点击这个标签能够进一步间接筛选出所有的 good first issues,这是社区专门留给新贡献者的绝对简略的入门级 issues:
没错,从这里开始,浏览一下这些 good first issues,看下有没有你感兴趣的而且还没被调配的 issue,而后在上面留言,期待我的项目管理员分配任务后就能够开始编码了,就像这样:
如图所示,如果一个 issue 还没有被认领,这时候你上去留个言,期待管理员会将这个任务分配给你,接着你就能够开始开发了。
五、我要提交 PR,怎么上手?
个别开源我的项目代码库根目录都会有一个 CONTRIBUTING.md 或者其余相似名字的文档来介绍如何开始奉献,像这样:
在 DevStream 的 Contributing 文档里咱们放了一个 Development Workflow,其实就是 PR 工作流的介绍,不过明天,我要更具体地聊聊 PR 工作流。
5.1、第一步:Fork 我的项目仓库
GitHub 上的我的项目都有一个 Fork 按钮,咱们须要先将开源我的项目 fork 到本人的账号下,以 DevStream 为例:
点一下 Fork 按钮,而后回到本人账号下,能够找到 fork 到的我的项目了:
这个我的项目在你本人的账号下,也就意味着你有任意批改的权限了。咱们前面要做的事件,就是将代码变更提到本人 fork 进去的代码库里,而后再通过 Pull Request 的形式将 commits 合入上游我的项目。
5.2、第二步:克隆我的项目仓库到本地
对于任意一个开源我的项目,流程简直都是一样的。我间接写了一些命令,大家能够复制粘贴间接执行。当然,命令里的一些变量还是须要依据你本人的理论需要批改,比方对于 DevStream 我的项目,咱们能够先这样配置几个环境变量:
- 环境变量
export WORKING_PATH="~/gocode"
export USER="daniel-hutao"
export PROJECT="devstream"
export ORG="devstream-io"
同理对于 DevLake,这里的命令就变成了这样:
export WORKING_PATH="~/gocode"
export USER="daniel-hutao"
export PROJECT="incubator-devlake"
export ORG="apache"
记得 USER 改成你的 GitHub 用户名,WORKING_PATH 当然也能够灵便配置,你想把代码放到哪里,就写对应门路。
接着就是几行通用的命令来实现 clone 等操作了:
- clone 等
mkdir -p ${WORKING_PATH}
cd ${WORKING_PATH}
# You can also use the url: git@github.com:${USER}/${PROJECT}.git
# if your ssh configuration is proper
git clone https://github.com/${USER}/${PROJECT}.git
cd ${PROJECT}
git remote add upstream https://github.com/${ORG}/${PROJECT}.git
# Never push to upstream locally
git remote set-url --push upstream no_push
如果你配置好了 ssh 形式来 clone 代码,当然,git clone 命令用的 url 能够改成git@github.com:${USER}/${PROJECT}.git
。
实现这一步后,咱们在本地看到的 remote 信息应该是这样的:
git remote -v
origin git@github.com:daniel-hutao/devstream.git (fetch)
origin git@github.com:daniel-hutao/devstream.git (push)
upstream https://github.com/devstream-io/devstream (fetch)
upstream no_push (push)
记住啰,你本地的代码变更永远只提交到 origin,而后通过 origin 提交 Pull Request 到 upstream。
5.3、第三步:更新本地分支代码
如果你刚刚实现 fork 和 clone 操作,那么你本地的代码必定是新的。然而“刚刚”只存在一次,接着每一次筹备开始写代码之前,你都须要确认本地分支的代码是新的,因为基于老代码开发你会陷入有限的抵触窘境之中。
- 更新本地 main 分支代码:
git fetch upstream
git checkout main
git rebase upstream/main
当然,我不倡议你间接在 main 分支写代码,尽管你的第一个 PR 从 main 提交齐全没有问题,然而如果你须要同时提交 2 个 PR 呢?总之激励新增一个 feat-xxx 或者 fix-xxx 等更可读的分支来实现开发工作。
- 创立分支
git checkout -b feat-xxx
这样,咱们就失去了一个和上游 main 分支代码一样的个性分支 feat-xxx 了,接着能够开始欢快地写代码啦!
5.4、第四步:写代码
没啥好说的,写就是了,写!
5.5、第五步:Commit 和 Push
- 通用的流程:
git add <file>
git commit -s -m "some description here"
git push origin feat-xxx
当然,这里大家须要了解这几个命令和参数的含意,灵便调整。比方你也能够用 git add --all
实现 add 步骤,在 push 的时候也能够加 -f
参数,用来强制笼罩近程分支(如果曾经存在,然而 commits 记录不合你意)。然而请记得 git commit
的-s
参数肯定要加哦!
如果你习惯用 IDE 来 commit,当然也没有任何问题,像这样:
这里要留神 commit message 的标准,可能每个开源我的项目的要求不尽相同,比方 DevStream 的标准是相似这样的格局:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
举几个例子:
feat: some description here
docs: some description here
fix: some description here
fix(core): some description here
chore: some description here
- …
commit 和 push 两个步骤能够在 IDE 里一步到位,也能够离开,我习惯离开操作,给本人多一些余地。另外,我更习惯命令行操作:
git push origin feat-1
Counting objects: 80, done.
Delta compression using up to 10 threads.
Compressing objects: 100% (74/74), done.
Writing objects: 100% (80/80), 13.78 KiB | 4.59 MiB/s, done.
Total 80 (delta 55), reused 0 (delta 0)
remote: Resolving deltas: 100% (55/55), completed with 31 local objects.
remote:
remote: Create a pull request for 'feat-1' on GitHub by visiting:
remote: https://github.com/daniel-hutao/devstream/pull/new/feat-1
remote:
To github.com:daniel-hutao/devstream.git
* [new branch] feat-1 -> feat-1
到这里,本地 commits 就推送到近程了。
5.6、第六步:开一个 PR
在实现 push 操作后,咱们关上 GitHub,能够看到一个黄色的提示框,通知咱们能够开一个 Pull Request 了:
如果你没有看到这个框,也能够间接切换到 feat-1 分支,而后点击下方的“Contribute”按钮来开启一个 PR,或者间接点 Issues 边上的 Pull requests 进入对应页面。
- Pull Request 格局默认是这样的:
这里咱们须要填写一个适合的题目(默认和 commit message 一样),而后依照模板填写 PR 形容。PR 模板其实在每个开源我的项目里都不太一样,咱们须要仔细阅读下面的内容,防止犯低级谬误。
比方 DevStream 的模板里目前分为 4 个局部:
- Pre-Checklist:这里列了 3 个前置查看项,揭示 PR 提交者要先浏览 Contributing 文档,而后代码要有欠缺的正文或者文档,尽可能增加测试用例等;
- Description:这里填写的是 PR 的形容信息,也就是介绍你的 PR 内容的,你能够在这里形容这个 PR 解决了什么问题等;
- Related Issues:记得吗?咱们在开始写代码之前其实是须要认领 issue 的,这里要填写的也就是对应 issue 的 id,如果你领的 issue 链接是 https://github.com/devstream-…,并且这个 issue 通过你这个 PR 的批改后就实现了,能够敞开了,这时候能够在 Related Issues 上面写“close #796”;
- New Behavior:代码批改后绝大多数状况下是须要进行测试的,这时候咱们能够在这里粘贴测试后果截图,这样 reviewers 就可能晓得你的代码曾经通过测试,性能合乎预期,这样能够缩小 review 工作量,疾速合入。
这个模板并不简单,咱们间接对着填写就行。
- 比方:
而后点击右下角“Create pull request”就实现了一个 PR 的创立了。不过我这里不能去点这个按钮,我用来演示的批改内容没有意义,不能合入上游代码库。不过我还是想给你看下 PR 创立进去后的成果,咱们以 pr655 为例吧:
这是上个月我提的一个 PR,根本和模板格局统一。除了模板的内容,可能你曾经留神到这里多了一个 Test 大节,没错,模板不是死的,模板只是为了升高沟通老本,你齐全能够适当调整,只有后果是“往更清晰的方向走”的。我这里通过 Test 局部增加了本地具体测试后果记录,通知 reviewers 我曾经在本地充沛测试了,请释怀合入。
提交了 PR 之后,咱们就能够在 PR 列表里找到本人的 PR 了,这时候还须要留神 ci 查看是不是全副可能通过,如果失败了,须要及时修复。以 DevStream 为例,ci 查看项大抵如下:
5.7、第七步:PR 合入
如果你的 PR 很完满,毫无争议,那么过不了太长时间,我的项目管理员会间接合入你的 PR,那么你这个 PR 的生命周期也就到此结束了。
然而,没错,这里有个“然而”,然而往往第一次 PR 不会那么顺利,咱们接下来就具体介绍一下可能常常遇到的一些问题和对应的解决办法。
六、我提交了一个 PR,而后遇到了问题 A,B,C,D,E,F,G,…😭
少数状况下,提交一个 PR 后是不会被马上合入的,reviewers 可能会提出各种修改意见,或者咱们的 PR 自身存在一些规范性问题,或者 ci 查看就间接报错了,怎么解决呢?持续往下看吧。
6.1、Reviewers 提了一些修改意见,我如何更新 PR?
很多时候,咱们提交了一个 PR 后,还须要持续追加 commit,比方提交后发现代码还有点问题,想再改改,或者 reviewers 提了一些修改意见,咱们须要更新代码。
个别咱们恪守一个约定:在 review 开始之前,更新代码尽量不引入新的 commits 记录,也就是能合并就合并,保障 commits 记录清晰且有意义;在 review 开始之后,针对 reviewers 的修改意见所产生的新 commit,能够不向前合并,这样可能让二次 review 工作更有针对性。
不过不同社区要求不一样,可能有的开源我的项目会要求一个 PR 里只能蕴含一个 commit,大家依据理论场景灵便判断即可。
说回如何更新 PR,咱们只须要在本地持续批改代码,而后通过和第一个 commit 一样的步骤,执行这几个命令:
git add <file>
git commit -s -m "some description here"
git push origin feat-xxx
这时候别看 push 的是 origin 的 feat-xxx 分支,其实 GitHub 会帮你把新增的 commits 全副追加到一个未合入 PR 里去。没错,你只管一直 push,PR 会自动更新。
至于如何合并 commits,咱们下一大节具体介绍。
6.2、Commits 太多或者记录凌乱,如何合并 Commits?
很多状况下咱们须要去合并 commits,比方你的第一个 commit 里改了 100 行代码,而后发现少改了 1 行,这时候又提交了一个 commit,那么第二个 commit 就太“没意思”了,咱们须要合并一下。
6.2.1、Git 命令行形式合并 Commits
比方我这里有 2 个同名的 commits,第二个 commit 其实只改了一个标点:
这时候咱们能够通过 rebase 命令来实现 2 个 commits 的合并:
git rebase -i HEAD~2
执行这个命令会进入一个编辑页面,默认是 vim 编辑模式,内容大抵如下:
pick 3114c0f docs: just for test
pick 9b7d63b docs: just for test
# Rebase d640931..9b7d63b onto d640931 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
咱们须要把第二个 pick 改成 s,而后保留退出(vim 的 wq 命令):
pick 3114c0f docs: just for test
s 9b7d63b docs: just for test
接着会进入第二个编辑页面:
# This is a combination of 2 commits.
# This is the 1st commit message:
docs: just for test
Signed-off-by: Daniel Hu <tao.hu@merico.dev>
# This is the commit message #2:
docs: just for test
Signed-off-by: Daniel Hu <tao.hu@merico.dev>
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# ...
这里是用来编辑合并后的 commit message 的,咱们间接删掉多余局部,只保留这样几行:
docs: just for test
Signed-off-by: Daniel Hu <tao.hu@merico.dev>
接着同样是 vim 的保留退出操作,这时候能够看到日志:
[detached HEAD 80f5e57] docs: just for test
Date: Wed Jul 6 10:28:37 2022 +0800
1 file changed, 2 insertions(+)
Successfully rebased and updated refs/heads/feat-1.
这时候能够通过 git log
命令查看下 commits 记录是不是合乎预期:
好,咱们在本地确认 commits 曾经实现合并,这时候就能够持续推送到近程,让 PR 也更新掉:
git push -f origin feat-xxx
这里须要有一个 -f
参数来强制更新,合并了 commits 实质也是一种抵触,须要冲掉近程旧的 commits 记录。
6.2.2 IDE 里合并 Commits
图形化形式当然也能够实现 Commits 的合并。
- 截图走起
- 点击右下角的 Git
- 抉择想要合并的 commits
- 右键,而后点击 Squash Commits,记得嘴里默念一句:走你!
接着就能够看到这个页面了:
这是图形化形式批改 commit message 的页面,行吧,改成你喜爱的样子,而后点击右下角的 OK 按钮,事件就算完结了。
看,2 个 commits,它们“交融”了,变成了一个“面目全非”的新 commit 了。
6.3、PR 产生了抵触,如何解决?
抵触能够在线解决,也可能本地解决,咱们一一来看。
6.3.1、在线解决抵触
咱们要尽可能防止抵触,养成每次写代码前更新本地代码的习惯。不过,抵触不可能完全避免,有时候你的 PR 被阻塞了几天,可能他人改了同一行代码,还领先被合入了,这时候你的 PR 就呈现抵触了,相似这样(同样,此刻我不能真的去上游我的项目结构抵触,所以上面用于演示的抵触在我在本人的 repo 里):
每次看到这个页面都会让人感觉心头一紧。咱们点击“Resolve conflicts”按钮,就能够看到具体抵触的内容了:
能够看到具体抵触的行了,接下来要做的就是解决抵触。咱们须要删掉所有的 <<<<<<<
、>>>>>>>
和 =======
标记,只保留最终想要的内容,如下:
接着点击右上角的“Mark as Resolved”:
最初点击“Commit merge”:
这样就实现抵触解决了,能够看到产生了一个新的 commit:
到这里,抵触就解决掉了。
6.3.2、本地解决抵触
更多时候,咱们须要在本地解决抵触,尤其是抵触太多,太简单的时候。
同样,咱们结构一个抵触,这次尝试在本地解决抵触。
- 先在线看一下抵触的内容:
- 接着咱们在本地执行:
# 先切回到 main 分支
git checkout main
# 拉取上游代码(理论场景必定是和上游抵触,咱们这里的演示环境其实是 origin)git fetch upstream
# 更新本地 main(这里也能够用 rebase,然而 reset 不论有没有抵触总是会胜利)git reset --hard upstream/main
到这里,本地 main 分支就和近程(或者上游) main 分支代码完全一致了,而后咱们要做的是将 main 分支的代码合入本人的个性分支,同时解决抵触。
git checkout feat-1
git rebase main
- 这时候会看到这样的日志:
First, rewinding head to replay your work on top of it...
Applying: docs: conflict test 1
Using index info to reconstruct a base tree...
M README.md
Falling back to patching base and 3-way merge...
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: Failed to merge in the changes.
Patch failed at 0001 docs: conflict test 1
The copy of the patch that failed is found in: .git/rebase-apply/patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
咱们须要解决抵触,间接关上 README.md,找到抵触的中央,间接批改。这里的改法和上一大节介绍的在线解决抵触没有任何区别,我就不赘述了。
代码里同样只保留最终内容,而后持续 git 命令走起来:
可能此时你并不释怀,那就通过 git log
命令看一下 commits 历史记录吧:
这里的“conflict test 2”是我提交到 main 分支的记录,能够看到这个工夫比“conflict test 1”还要晚了一些,然而它先合入了。咱们在 rebase 操作后,这个记录在前,咱们个性分支的“conflict test 1”在后,看起来很谐和,咱们持续将这个变更推送到近程,这个命令曾经呈现很屡次了:
git push -f origin feat-xxx
这时候咱们再回到 GitHub 看 PR 的话,能够发现抵触曾经解决了,并且没有产生多余的 commit 记录,也就是说这个 PR 的 commit 记录十分洁净,好似抵触素来没有呈现过:
至于什么时候能够在线解决抵触,什么时候适宜本地解决抵触,就看大家如何对待“需不需要保留解决抵触的记录”了,不同社区的了解不一样,可能特地成熟的开源社区会心愿应用本地解决抵触形式,因为在线解决抵触产生的这条 merge 记录其实“没养分”。至于 DevStream 社区和 DevLake 社区,咱们举荐应用后一种,然而不做强制要求。
6.4、CI 查看不过:commit message 相干问题如何修复?
后面咱们提到过 commit message 的标准,然而第一次提交 PR 的时候还是很容易出错,比方 feat: xxx
其实能通过 ci 查看,然而 feat: Xxx
就不行了。假如当初咱们不小心提交了一个 PR,然而外面 commit 的 message 不标准,这时候怎么批改呢?
- 太简略了,间接执行:
git commit --amend
这条命令执行后就能进入编辑页面,随便更新 commit message 了。改完之后,持续 push:
git push -f origin feat-xxx
这样就能更新 PR 里的 commit message 了。
6.5、CI 查看不过:DCO(sign) 问题如何修复?
相当多的开源我的项目会要求所有合入的 commits 都蕴含一行相似这样的记录:
Daniel Hu <tao.hu@merico.dev>
所以 commit message 看起来会像这样:
feat: some description here
Signed-off-by: Daniel Hu <tao.hu@merico.dev>
这行信息相当于是对应 commit 的作者签名。要增加这样一行签名当然很简略,咱们间接在 git commit
命令前面加一个 -s
参数就能够了,比方 git commit -s -m "some description here"
提交的 commit 就会带上你的签名。
然而如果如果你第一次提交的 PR 里遗记了在 commits 中增加 Signed-off-by 呢?这时候,如果对应开源我的项目配置了 DCO 查看,那么你的 PR 就会在 ci 查看中被“揪出来”没有正确签名。
同样先结构一个没有加签名的 commit:
我不能间接推到 DevStream 我的项目代码库里演示如何让 DCO 报错,然而如果提 PR,看到的成果是这样的:
咱们看下如何解决:
git commit --amend -s
这样一个简略的命令,就能间接在最近一个 commit 里加上 Signed-off-by 信息。执行这行命令后会间接进入 commit message 编辑页面,默认如下图:
docs: dco test
Signed-off-by: Daniel Hu <tao.hu@merico.dev>
这时候咱们能够同时批改 commit message,如果不须要,那就间接保留退出好了,签名信息是会主动加上的。
实现签名后呢?当然是来一个强制 push 了:
git push -f origin feat-xxx
这样,你 PR 中的 DCO 报错就天然修复了。
七、最初
一个不小心这篇文章写的有点长了。行,打完出工!
- 欢送到我的集体网站或者微信公众号“胡说云原生”浏览更多我的文章;
- 欢送关注 Apache DevLake (https://github.com/apache/inc…),和咱们一起玩开源;
-
欢送到 Apache DevLake 官网博客 (https://devlake.apache.org/blog) 浏览更多 Apache DevLake 团队公布的文章。
理解更多最新动静
官网:https://devlake.incubator.apa…
GitHub:https://github.com/apache/inc…
Slack:通过 Slack 分割咱们