本文作者:Daniel Hu

个人主页:www.danielhu.cn/

一、概述

今日我预备和你具体介绍怎样开端参加开源项目,协助你在 GitHub 上完结第一个 PR 的合入

当然,除了正常的 PR 合入流程之外,我还预备具体介绍一下假如一个 PR 提交后遇到了抵触、需求追加 commits、需求兼并 commits 等等相对杂乱问题该怎样处理。

总的来说,本文方案分为4个部分:

  1. 谈谈为什么要参加开源项目以及我为什么要介绍怎样 PR
  2. 谈谈怎样开端参加开源项目,也便是怎样寻觅适宜的开源项目、怎样寻觅奉献点
  3. 介绍怎样上手 PR 流程,即从 fork 到 push 全流程
  4. 介绍提交了 PR 之后遇到各种常见问题怎样处理

Ok, let’s get started!

二、为什么要参加开源项目

本文我不打算长篇大论“为什么要参加开源”,具体介绍参加开源项目的收成,我想仅从“提高编码才能”角度谈一谈“为什么要参加开源项目”。

在面试的时分我有个习气,假如提名人在自己的简历里说到自己熟悉某一门言语,我就会习气性问他一个问题:

你有没有阅览过某个开源项目的源码?或许更进一步,有没有参加过某个开源社区,或许说给开源项目提过 PR

假如答案是必定的,比方提名人说自己读过部分 Kubernetes 模块的源码,再进一步我承认他真的读过而且读懂了或许说真的提交过 bugfix/feature 类型的 PR,那我就不再问编程言语层面的问题了,因为我相信能看懂一个老练的开源项目部分模块源码或许能够提交 bugfix/feature 类型的 PR 现已说明了一切。

我自己在学习 Golang 的时分,大致分为两个阶段:

  1. 学习基础语法,开端写项目,直到能够熟练完结各种业务功用的开发;
  2. 看了一些开源项目的源码,深感获益颇多,编码水平再上一个台阶。

差不多也便是在看 Kubernetes 项目源码的时分,我深刻认识到一般的企业内部项目和汇集全国际最优异的程序员智慧结晶的开源项目之间的巨大距离,也意识到学习优异开源项目源码关于一个程序员编码水平提高的重要性(当然,你能够说 Google 内部也存在非开源的十分优异的代码,这毫无疑问,可是我想今日咱们没有必要讨论特例)。

仔细阅览开源项目源码,你总会发现一些小瑕疵,这时分提一个 PR(Pull Request),让你的代码合入开源项目,运行在“国际每一个角落”,那是多么风趣的作业!而成功合入第一个 PR 往往就像翻开潘多拉魔盒相同,你会进入到别的一个国际,开端接触到开源社区,感受开源的魅力!

三、为什么我想介绍怎样 PR

我司开源了 2 个项目,分别是:

  1. CNCF Project DevStream

  1. Apache DevLake

DevStream 项目和 DevLake 项目隔三差五就会有新奉献者提交 PR 过来,可是大都奉献者在提交第一个 PR 时往往会遇到一个或多个问题,比方发生抵触、commits 记载过多或许紊乱、commit 没有签名、commit message 不标准、各种 ci 流程查看报错等等。

在看到新奉献者提交 PR 时,咱们天然是十分高兴且热情地对他表示欢迎而且奉告怎样修正各种问题,可是跟着奉献者的增多,咱们的开源社区简直每天都需求答复一个问题:“怎样正确地提交一个 PR”。或许此刻你会开端怀疑咱们是不是没有供给相应的文档?其实不然,咱们有具体的文档,可是人总是有慵懒的,大都的新奉献者并没有满足的意愿去仔细看翻看文档然后再提交 PR,乃至许多新奉献者因为刚开端接触开源项目,关于项目结构和文档组织结构比较陌生,乃至不会想到有这些文档的存在,总归各种各样的理由让大都的新奉献者会挑选“先提了 PR 再说”。

那么今日我想测验彻底讲了解“怎样正确地提交一个 PR”,测验细说 GitHub 上的 PR 全过程,以及这儿边或许会遇到的各种困难和处理办法。一方面期望对第一次参加开源项目的新人有所协助,另一方面期望能够进一步降低 DevStream 社区和 DevLake 社区的参加门槛

四、我想参加开源项目,怎样开端?

不论你为什么决定开端参加开源项目,不论起点是出于学习、爱好、成就感等等,仍是为了让某个自己需求的特性合入某个开源项目,总归今日你下定决心,要给某个开源项目提交一个 PR 了,好,咱们开端吧!

4.1、寻觅一个适宜的开源项目

假如你现已决定参加某个开源社区了,那么请直接越过本末节。

假如你就仅仅想开端参加开源,暂时还不知道该参加哪个社区,那么我有几个小主张:

  1. 不要从特别老练的项目开端。比方现在去参加 Kubernetes 社区,一方面因为奉献者太多,很难抢到一个入门级的 issue 来开端第一个 PR;别的一方面也因为奉献者太多,你的声音会被淹没,社区维护者并不介意多你一个或许少你一个(当然或许没有人会承认,可是你不得不信),假如你提个 PR 都遇到了各种问题还不能自己独立处理,那么很或许你的 PR 会直接超时封闭,没有人介意你是不是有一个好的参加体验;
  2. 不要从特别小的项目开端。这就不需求我解释了吧?很前期的开源项目或许面临着十分多的问题,比方代码不标准、协作流程不标准、重构频繁且不是 issue 驱动的,让外部参加者莫衷一是……
  3. 挑选闻名开源软件基金会的孵化项目,这类项目一方面不是特别老练,所以对新奉献者友爱;另一方面也不会特别不老练,不至于给人很差的参加体验,比方 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 个部分:

  1. Pre-Checklist:这儿列了 3 个前置查看项,提示 PR 提交者要先阅览 Contributing 文档,然后代码要有完善的注释或许文档,尽或许添加测验用例等;
  2. Description:这儿填写的是 PR 的描绘信息,也便是介绍你的 PR 内容的,你能够在这儿描绘这个 PR 处理了什么问题等;
  3. Related Issues:记住吗?咱们在开端写代码之前其实是需求招领 issue 的,这儿要填写的也便是对应 issue 的 id,假如你领的 issue 链接是 github.com/devstream-i… issue 经过你这个 PR 的修正后就完结了,能够封闭了,这时分能够在 Related Issues 下面写“close #796”;
  4. 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 的兼并。

  • 截图走起

  1. 点击右下角的 Git
  2. 挑选想要兼并的 commits
  3. 右键,然后点击 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 (github.com/apache/incu…) ,和咱们一同玩开源;
  • 欢迎到 Apache DevLake 官方博客 (devlake.apache.org/blog) 浏览更多 Apache DevLake 团队发布的文章。

了解更多最新动态

官网:devlake.incubator.apache.org/

GitHub:github.com/apache/incu…

Slack:经过 Slack 联系咱们