一、幕后故事

时光荏苒,岁月如梭…… (太文绉绉了,这不是我的风格)

今天我准备聊聊在 GitHub 上如何玩 Code Review。

突发奇想?心血来潮?不是。

咋回事呢?(对八卦不感兴趣的可以直接跳到下一节,但是我猜你会感兴趣。)


首先我是 DevStream 开源社区成员。

在五月份,又有3位活跃的优秀的牛X的 Contributors 正式加入 DevStream 开源社区,正式成为了社区 Member!

(看下面的红框框)

于是乎,加上三月份的4个“老 Member”,DevStream 社区就有7个“社区 Member”了(社区 Member 区分于像我这种在思码逸上班的内部 Member)!

7个疯狂输出的 Members,外加接近20个 Contributors,我和铁心两个人基本就只能看着 pr 笑笑,一边表示欣喜,一边表示 review 不过来了,“应接不暇”,废了废了……

也就是说,是时候组织一个 reviewer 组,拉着大家一起玩 Code Review 流程了!

说到 Code Review 流程,流程是啥?规范是啥?规则是啥?技巧是啥?xxxx?我能预想到 reviewers team 这个事情落地之日会有一堆问题砸到我头上。好吧,我需要写一篇文章来聊聊这些事。

二、踏上旅途

下面我们开始一次 Code Review 之旅。

1. 抢票阶段:认领一个 Review 任务

开始一次 review 之前,首先咱得“认领”一个 review 任务。

怎样算成功认领?如下图,Reviewers 里有你的头像,这时当前 pr 你就是 reviewers 之一,同时可以看到黄色 bar 里的一行字“This pull request is waiting on your review.”以及绿色的按钮“Add your review”。你可以点击这个“Add your review”开始一次 Code Review 之旅。

那么怎么认领呢?” 可能你还想问我。

这个问题有答案,也没有答案。

因为你是 reviewer 之一,那么你就有权限自己点击 Reviewers 右边的⚙️齿轮按钮,然后指定自己是一个 Reviewer。如果你不是一个“合法”的 reviewer,那么你得先成为 reviewer (If you want)。

2. 持票上船:开始 Review 流程

点击 Add your review 按钮后,咱就进入到了网页版 Code Review 页面,大致如下:

这里有很多值得“探索”的特性,比如:左边的“文件树”、文件树上方过滤“commits”的下拉框、右边的“文件过滤”、每个文件右上角的 Viewed 选择框、…… 每发现一个新功能,你的 review 过程就会多简化一分。

关于这个页面,没有比官方文档更权威和详细的介绍了,我想我没有理由“搬一次砖”,大家点击链接进一步探索吧。

对于简单的修改,或许网页直接查看代码 diff 就足够了,类似这种变更级别的 pr:

我们可以轻松判断这个修改是不是“正确”,然后选择进一步的操作,比如 Approve:

3. 下船休整:下载一个 pr 到本地 Review

对于一个不能“一眼看穿”的 pr,比如对方没有附上详细的测试结果等信息来证明他的修改已经“充分测试”(充分测试的例子),这时候靠肉眼我们很难判断这个 pr 合入后会怎样,或者不借助 IDE 的能力我们甚至很难看懂一些复杂的修改,这时候就需要下载这个 pr 对应的代码到本地,然后用 IDE 来帮助 review 了。

pr #641为例,我们需要下载这个 pr,这时只需要执行这样两条命令:

git fetch upstream pull/641/head:pr641
git checkout pr641

效果如下:

然后在 IDE 里打开项目,就能看到 pr 对应的代码了:

代码在手,天下我有!

这会你可以在本地仔细查看每一处代码细节,可以在本地跑一下 make buid -j8go test ./... 之类的命令来逐步“打消自己内心的疑虑”。当然,pr 本身会触发 GitHub actions workflows,这些基础的 build/ut 流程其实本地不跑也能知道是不是有错误,我们可以直接在页面上看到(每个项目具体的 ci 逻辑不一样):

到这里,你就基本能够完全看懂一个 pr 对应的所有修改了,是放他过?还是拦下马?他的“命运”掌握在你的手里!

三、移花接木:提交一个 commit 到别人的 pr

可能有时候,你需要修改别人的 pr。哥们,我建议你抽根烟冷静一下,再问自己一句:我真的必须去修改他的 pr 吗?这样做会不会被打?

一般情况下,我不建议你去修改别人的 pr,尤其是不能保证你的修改一定正确的情况下。因为你别人的 pr 本身就是容易冒犯到别人的事情,其次万一你改了之后发现还需要别人自己补一个 commit,他会在复杂的 git 操作中骂你一万遍。

什么时候需要去动别人的 pr 呢?举个例子,比如这个 pr

首先这是一个 new contributor 提交的 first pr,所以我不希望他的 first pr 之旅太艰辛。然后这个 feature 其实并不简单,虽然技术上看并不难,但是要做到“不重不漏”就需要对 dtm 命令的所有子命令都“了然于胸”才行。显然,这对一个 new contributor 来说要求太高了。所以在他提交了一个 commit 之后,我直接在这个 commit 的基础上又加了一个 commit,完成了剩下的工作,并且在认可他的工作后告知其为什么我要修改这个 pr,并附上了测试结果等。

具体怎么操作呢?步骤如下:

  1. 修改代码,本地 commit

前面我们已经下载了一个别人的 pr 到本地,接着自然是继续修改,然后提交 commit(git add xxx & git commit -s -m "xxx"),到这里都没啥技术含量,不赘述了。

  1. 找到 pr 对应的源分支

在 pr 页面可以看到具体 pr 是从哪里提交的,比如:

我们点进去,就可以找到 fork 项目的地址信息,像这样:

于是,我们可以这样来加一个 remote:

git remote add himku git@github.com:himku/devstream.git

此时这个 pr 对应的 fork 项目的地址是 himku(git@github.com:himku/devstream.git),对应分支是 fix-issue-559,于是我们可以这样将自己新增的 commit(s) 提交到这个 pr 里(本地 commit 后执行):

git push himku HEAD:fix-issue-559

是不是很酷?

三、乱七八糟的规则:目的是啥?规范是啥?要求是啥?啥是啥?

再聊聊剩下的一些零零碎碎的问题,比如可能你想问 review 的目的啊,规范啊,要求啊,啊啊啊……

1. 目的是啥?

可能你会问我为什么要 code review ?我希望你别问。因为我不想总结。(这个问题可以 Google 到一堆答案)

我相信你心中有答案,code review 对应的是一堆的“褒义词”,比如:发现错误、保证质量、互相学习……

你想的都是对的,总之这个事情值得做就对了,不需要去总结为什么。

啥?

你还是想听我谈谈?

谈谈就谈谈。

  • 软件质量:首先大多数的错误可以在 code review 阶段被暴露出来,这些错误留到日后“爆雷”再被修复,代价会大很多,不管是造成的业务负面影响,还是额外付出的修复时间。所以 code review 看似多花了时间,其实整体看是提升交付效率的;
  • 代码质量:严格执行 code review 流程一方面可以互相督促对方:你别随便提交“垃圾”代码上来,会有人 review;一方面假如有“垃圾”代码被提交上来了,可以有人站出来及时制止。完善的 code review 流程可以避免代码可读性日益变差,维护成本日益增大,逐步变成“屎山”;
  • 传播经验:如果我写的代码很漂亮,我希望你来 review,这时候一方面我想“秀”,无需避讳;另外一方面我希望你能够学着点,这是为你好;如果我的代码写的很烂,我希望你来 review,这时候我希望你可以给我指出问题,帮助我提升编码水平,这是为我好;总之互相 review,互相学习,你好我好大家好;

2. 规范与要求是啥?

当我们解决了所有“流程”或“技巧”层面的问题后,下一个“非技术性”问题是:怎样的代码需要“返工”?怎样的代码可以被合入?

我相信你心中会有这样的疑问。

对于有“错误”的代码,毫无疑问,不能合入,这不在我们的讨论范围。

那么正常运行,没有逻辑错误的代码呢?比如“代码风格有点混乱”,比如“缺乏必要的一些注释”,比如“可读性差”……

我们分三个层次来思考:

  • 严格:我们完全可以指出任何是“问题”的问题,因为一份 WTF 的代码被合入后,所有对 coder 的骂声都包含一句潜台词“reviewer 干啥吃的?”所以很简单,你觉得有问题的地方都可以提出来,包括:

    • “代码太复杂,看起来费力,我觉得可读性不好。”
    • “我看了十分钟还是看不懂,说明可读性不够好。”
    • “这个函数太长了,我鼠标滚了好几下才看完,你应该拆分一下。”
    • “这个函数从名字我看不出来功能,但是我懒得看具体逻辑,为什么没有更多的注释?”
    • “你这个源文件都五百行了,你要不拆分一下?”
    • “这个包的逻辑很关键,你应该加点 UT?”
    • ……

  • 一般:如果一份代码功能完全正确,可读性也勉强还行,或许没有很好的面向对象来组织,或者注释不太详细,或者存在其他一些小小的不完美。这时候你也可以选择通过,避免太严格的 review 规则把一个 pr 的合入周期拖的太长,一方面影响交付效率,一方面打击开发者信心。很多时候我们可以对自己,或者对核心开发者要求更严格一些;但是对于社区贡献者,往往需要更多的“宽容”与认可。

  • 温柔:如果是一个 new contributor 提交的一个 first pr,这时你可以放下各种能放下的要求,只要这份代码还过得去,就能合入,没有啥比给新人一些信心更重要的。如果 pr 存在一些小问题,你觉得对他来说改起来不会太困难,你可以留言友好的告诉他哪里需要改,怎么改;如果你觉得对他来说进一步做到“完美”有难度,你也可以直接提一个 fix 的 commit 到这个 pr 里,直接帮他修复问题,然后留个言告知他没有考虑到的问题是什么。

终点站到了,下船!

今天就聊到这里。

意犹未尽?

再去看看 Google 的 Code Review Developer Guide 吧!


  • 你可以收藏我的个人网站 https://www.danielhu.cn,阅读更多我写的博客文章;
  • 你也可以关注我的个人微信公众号“胡说云原生”,第一时间接收新文章推送;
  • 当然,你也可以收藏 DevStream 的博客网站 https://blog.devstream.io 或者官网 https://www.devstream.io,里面不止有我这种“不严肃”的人发的“主要用来搞笑”的文章,还有 DevStream 团队其他成员发的“严肃讲知识”的“科普文”。

在 GitHub 上玩转开源项目的 Code Review的更多相关文章

  1. 28款GitHub最流行的开源机器学习项目,推荐GitHub上10 个开源深度学习框架

    20 个顶尖的 Python 机器学习开源项目 机器学习 2015-06-08 22:44:30 发布 您的评价: 0.0 收藏 1收藏 我们在Github上的贡献者和提交者之中检查了用Python语 ...

  2. 推荐GitHub上10 个开源深度学习框架

    推荐GitHub上10 个开源深度学习框架   日前,Google 开源了 TensorFlow(GitHub),此举在深度学习领域影响巨大,因为 Google 在人工智能领域的研发成绩斐然,有着雄厚 ...

  3. GitHub 上优秀的开源SLAM repo (更新中)

    GitHub 上优秀的开源SLAM repo (更新中) 欢迎 watch/star/fork 我们的 GitHub 仓库: Awesome-SLAM, 或者follow 项目的主页:Awesome- ...

  4. Github上的andoird开源组件整理

    http://blog.csdn.net/findsafety/article/details/50623627 第一部分 个性化控件(View) 主要介绍那些不错个性化的View,包括ListVie ...

  5. GitHub上优秀的开源项目(转载)

    转载出处:https://github.com/Trinea/android-open-project 第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.A ...

  6. 搜刮一些开源项目的APP

    iOS完整App资源收集 <iOS完整app资源收集>  <GitHub 上有哪些完整的 iOS-App 源码值得参考?> <GitHub 上有哪些完整的 iOS-App ...

  7. Github上的python开源项目

    Python开源项目,期待大家和我们一起共同维护 github排名榜单 https://github.com/trending github搜索榜单:https://github.com/search ...

  8. github上有android开源项目

    下面是一些比较好的开源项目,总共分为5大类,也许对某一些人有用,有些项目也许将来某一天对自己也有用,所以整理到此,希望对大家有帮助.首先声明非原创,这篇blog的目的是分享给那些可能需要的人. htt ...

  9. GitHub上优秀Android 开源项目

    GitHub在中国的火爆程度无需多言,越来越多的开源项目迁移到GitHub平台上.更何况,基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要.利用这些项目,有时能够让你 ...

随机推荐

  1. 【uniapp 开发】手绘签名组件

    代码如下: <template> <view class="content"> <button type="primary" @t ...

  2. 《头号玩家》AI电影调研报告(四)

    五. 现实中对于技术的实现 1.自由变身 电影中,主人公借助"魔幻眼镜"让自己快速变成另一个人的模样,现实中我们一样也能做到! 在今年游戏开发者大会(GDC)上,一个名为" ...

  3. sqli-labs环境搭建

    1 下载phpStudy 下载地址:https://www.xp.cn/download.html 由于sqli-lib最后一次提交代码的时候是2014年,所以高版本的phpStudy可能不兼容了,推 ...

  4. 设计模式学习笔记(十六)迭代器模式及其在Java 容器中的应用

    迭代器(Iterator)模式,也叫做游标(Cursor)模式.我们知道,在Java 容器中,为了提高容器遍历的方便性,把遍历逻辑从不同类型的集合类中抽取出来,避免向外部暴露集合容器的内部结构. 一. ...

  5. 牛客网 第十八届浙大城市学院程序设计竞赛(同步赛)J--万万没想到 啦啦啦啦啦

    我觉得我可以继续wa下去(手动魔鬼笑)--------------------------------------------   原题链接:https://ac.nowcoder.com/acm/c ...

  6. Java语言学习day15--7月21日

    今日内容介绍1.Eclipse开发工具2.超市库存管理系统 ###01Eclipse的下载安装 * A: Eclipse的下载安装  * a: 下载 * http://www.eclipse.org ...

  7. 2021.11.11 EXKMP

    2021.11.11 EXKMP https://www.luogu.com.cn/problem/P5410 下标以1开头: #include<cstdio> #include<i ...

  8. 2021.08.05 P1738 洛谷的文件夹(树形结构)

    2021.08.05 P1738 洛谷的文件夹(树形结构) P1738 洛谷的文件夹 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.树!! 题意: 给出n个网页路径,求 ...

  9. Msf路由转发

    Msf路由转发 前言 在内网渗透中,我们拿下了一台机器A的权限,再通过A做一个跳板来做横向渗透,这时我们对于内网中的其他机器是无法连接的.我们在A上做横向渗透是很困难的,因为在这台机器一般为web服务 ...

  10. JavaWeb和WebGIS学习笔记(五)——使用OpenLayers显示地图

    系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...