Gerrit 代码审查:从"这啥玩意儿"到"真香"
最近团队里有人提议:“咱们上 Gerrit 吧。” 我第一反应是:“GitLab 不是用得好好的吗,又整啥新花样?” 结果用了两个月之后,我只想说两个字——真香。
一、问题来了:代码 review 怎么总是流于形式?
先说说咱们大多数人熟悉的代码审查流程:
- 本地写代码
git push到远程分支- 提个 Merge Request / Pull Request
- 同事点进去看看,评论几句
- 改完再 push,合并进主分支
这流程本身没问题,但实际操作中,你懂的——很多 MR 就是走个过场。要么 review 的人草草扫两眼就点了 “LGTM”(Looks Good To Me),要么等发现问题的时候,代码早就合进去了,只能再补一个 “修复 XX 问题” 的提交。
更头疼的是,有些团队为了 “规范”,要求每个人必须 review 通过才能合并。结果开发者为了省事,直接 push 到主分支,或者找个人 “秒过”,审查制度形同虚设。
说白了,我们需要一个机制,让代码审查真正成为合并前的 “硬门槛”,而不是一个可跳过的 checkbox。
这时候,Gerrit 登场了。
二、Gerrit 到底是啥?跟 GitLab 有啥不一样?
Gerrit 是 Google 开源的一款基于 Git 的代码审查工具。它长得像个代码托管平台,但核心定位只有一个:代码审查。
它和 GitLab/GitHub 最大的区别
| 特性 | GitLab/GitHub | Gerrit |
|---|---|---|
| 代码托管 | ✅ 完整支持 | ⚠️ 基础支持,偏 review 导向 |
| CI/CD | ✅ 内置 | ❌ 需配合 Jenkins 等 |
| Issue 管理 | ✅ 内置 | ❌ 没有 |
| 代码审查粒度 | 文件级评论 | 行级精准评论 |
| 合并前审查 | 可选(可绕过) | 强制,无法绕过 |
| 提交历史 | 可能很乱(fix-1, fix-2…) | 通过 ammend 保持整洁 |
Gerrit 的设计理念很 “硬核”:没有 review 通过的代码,绝不允许进入代码库。
三、Gerrit 的核心概念:Change、Patch Set、Label
刚接触 Gerrit 的时候,界面和术语确实让人有点懵。别急,咱们用三分钟搞清楚三个核心概念。
1. Change(变更)
你的一次代码提交,在 Gerrit 里叫做一个Change。每个 Change 有一个唯一的 Change-Id,类似于 “这次改动的身份证”。
2. Patch Set(补丁集)
你根据 review 意见修改后再次提交,不会生成新的 Change,而是生成一个新的Patch Set。也就是说,一个 Change 可以包含多个 Patch Set,记录了你 “改了多少版”。
# 第一次提交 → Gerrit 上生成 Change #1234,Patch Set 1# 根据意见修改后,再次 push → Change #1234,Patch Set 2# 再改一次 → Change #1234,Patch Set 3这有什么好处?整个 review 过程都在一个 Change 里完成,提交历史不会被一堆 “fix review comments” 的 commit 污染。
3. Label(评分标签)
Review 的人不是简单地点个 “通过”,而是要打分。最常见的两个 Label:
- Code-Review:代码质量评分,通常是
+2(通过)、+1(看起来还行,但没把握)、-1(有问题)、-2(否决,不能合) - Verified:CI 构建/测试结果,通常是
+1(通过)、-1(失败)
只有当所有必需的 Label 都达到指定分数时,这个 Change 才能被合并。这就把代码审查从 “软约束” 变成了 “硬规则”。
四、上手实战:从第一次 push 到合并
好了,概念讲完,咱们来走一遍实际流程。
第一步:配置本地 Git
Gerrit 不用普通的git push origin feature-branch,而是通过一个特殊的refs/for/目标分支来提交代码。
# 配置 push 到 Gerrit 的快捷方式gitremoteaddgerrit ssh://yourname@gerrit.example.com:29418/your-project.git# 安装 commit-msg hook,自动生成 Change-Idscp-p-P29418yourname@gerrit.example.com:hooks/commit-msg .git/hooks/注意:这个
commit-msghook 很关键,没有它,Gerrit 就认不出你的 Change,每次 push 都会生成一个新的 Change,review 记录全丢了。
第二步:提交代码
# 正常写代码、提交gitadd.gitcommit-m"feat: 新增库存校验逻辑"# push 到 Gerrit 进行 reviewgitpush gerrit HEAD:refs/for/main如果一切正常,你会看到类似这样的输出:
remote: Processing changes: new: 1, done remote: remote: New Changes: remote: https://gerrit.example.com/c/your-project/+/1234 feat: 新增库存校验逻辑第三步:根据 review 意见修改
同事在 Gerrit 上给你提了几条 comment,你改完之后,不要新建 commit,而是 amend 当前 commit:
# 修改代码...gitadd.gitcommit--amend--no-edit# 保持 commit message 不变,保留 Change-Id# 再次 pushgitpush gerrit HEAD:refs/for/main这时候 Gerrit 上 Change #1234 就会新增一个 Patch Set 2,之前的 review 评论和打分记录都还在,同事可以方便地看到 “你改了哪些地方”。
第四步:通过审查,合并代码
当 Change 拿到足够的Code-Review +2和Verified +1后,你就可以点击Submit按钮合并了。
合并后的提交历史干干净净,只有一个 commit:
feat: 新增库存校验逻辑而不是:
feat: 新增库存校验逻辑 fix: 修复 review 意见 1 fix: 再修一个小问题 fix: 修 CI 报错五、Gerrit 的一些 “坑” 和注意事项
用了这段时间,我也踩过几个坑,分享出来帮你避避雷。
坑 1:Change-Id 冲突
如果你 cherry-pick 了一个已经存在于 Gerrit 的 commit 到另一个分支,Change-Id 是一样的,Gerrit 会认为这是同一个 Change 的不同分支版本。如果你不想这样,需要手动删掉 commit message 里的 Change-Id,让 hook 重新生成一个。
坑 2:git commit --amend用不习惯
很多同学习惯了 “改一点就 commit 一点”,到了 Gerrit 这里要忍住。一个 Change 对应一个 commit,所有修改都通过 amend 和 force push(Gerrit 允许针对 refs/for/* 的 force push)来完成。刚开始会觉得别扭,但习惯了之后,你会发现提交历史真的清爽很多。
坑 3:权限配置比较复杂
Gerrit 的权限系统非常细粒度,可以精确控制谁能 review、谁能 submit、谁能 bypass review。但这也意味着,初次配置的时候比较烧脑,建议参考官方文档或者找个配过的同事带一带。
六、什么场景适合用 Gerrit?
说了这么多,Gerrit 并不是银弹。根据我的观察,下面这几类团队特别适合:
- 对代码质量要求高的团队:比如基础架构组、核心中台组,代码审查必须严格执行。
- 需要保持干净提交历史的项目:Gerrit 天然鼓励使用
git commit --amend,历史非常整洁。 - 已经有独立 CI/CD 工具链的团队:Gerrit 本身不做 CI/CD,配合 Jenkins、GitHub Actions 等使用很合适。
- 习惯 “先 review 后合并” 工作流的团队:如果你本来就认同这个理念,Gerrit 会让流程更顺畅。
反之,如果你是个小团队,追求 “一站式” 平台(代码托管 + CI/CD + 项目管理),GitLab 可能更省心。
七、总结
Gerrit 给我的最大感受是:它把代码审查从 “建议” 变成了 “规则”,从 “事后检查” 变成了 “事前把关”。
当然,工具只是辅助,最终代码质量还是取决于 review 的人是否认真。但至少,Gerrit 提供了一个不容易被绕过的机制,让 “认真 review” 成为可能。
如果你也正在为团队的代码审查流于形式而头疼,不妨试试 Gerrit。刚开始可能会有点不适应,但用上一段时间,你可能也会跟我一样——真香。
你们团队是怎么做代码审查的?用过 Gerrit 吗,体验如何?欢迎在评论区交流!