Gerrit 常用 CLI 与 SSH 命令详解(核心篇)
Gerrit 3.14.4 SSH 命令面与 REST API 实战:gerrit version/ls-projects/create-project/query/review/set-reviewers/create-account/show-caches 全家桶实测回显,REST 评审闭环与 capabilities 权限自检,CI 门禁轮询脚本示例与 2.x→3.x 命令差异排障。
Gerrit 常用 CLI 与 SSH 命令详解(核心篇)
目标:系统梳理 Gerrit 的两大自动化接口——SSH 命令行(
ssh -p 29418 <admin>@<gerrit> gerrit <command>全家桶)与 REST API(curl 实测),覆盖项目、账户、群组、评审、查询、运维维护六类命令,并给出评审流水线自动化示例与排障实录。全部命令在 Gerrit 3.14.4 站点实测(2026-10-27),回显逐行照抄。
一、环境信息
- Gerrit 版本:3.14.4(部署与站点结构见《Gerrit 3.14 Docker Compose 部署实战》)
- 接入地址:SSH 命令端口
8148(Gerrit 内部标准端口 29418,示例宿主映射为 8148,下文命令统一写 8148);REST/Web 入口http://localhost:8141 - 管理账号:
admin(HTTP 凭据q1w2e3r4,SSH 公钥已注册,接入步骤见部署篇第十二节) - 实测项目:
demo-project(含 Change 1(已合入)、Change 2) - 命令回显均为主机实测输出,REST 响应首行
)]}'为 Gerrit 防跨站 JSON 劫持魔法前缀(解析 JSON 时剥离该行)
二、SSH 命令行接入
Gerrit 的 SSH 通道是双用途:Git 推拉协议 + 管理命令面。管理命令的通用形态:
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost gerrit <command> [options]
基础验证(三条实测):
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost gerrit version
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost gerrit ls-projects
实测回显:
gerrit version 3.14.4
All-Projects
All-Users
demo-project
💡 技术拓展:Gerrit 的 SSH 命令面与 Git 协议共用 29418 一个端口,客户端首次连接同样走 SSH host-key 握手(主机密钥在站点
etc/ssh_host_*),自动化脚本建议固定-o StrictHostKeyChecking=yes并预分发 known_hosts。管理命令权限由全局能力(capabilities)控制——admin 账号的administrateServer: true等能力清单可通过 REST 查(见 4.5)。
三、gerrit 命令族详解
3.1 项目管理:ls-projects / create-project
gerrit create-project demo-project # 建项目(实测静默成功)
gerrit ls-projects # 列全部项目
ls-projects 常用过滤(官方命令文档):
gerrit ls-projects --description # 含描述
gerrit ls-projects -p demo # 限定树分支(前缀过滤)
gerrit ls-projects --all # 含隐藏项目
3.2 变更查询:query(评审流水线的核心读命令)
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost "gerrit query 'project:demo-project status:open'"
实测回显(输出节选,实测首尾):
change 2 (Open)
project: demo-project
branch: master
Change-Id: I2222222222222222222222222222222222222222
subject: Add second line
owner: admin
email: admin@demo.com
created: 2026-10-27 13:24:03.000000000
updated: 2026-10-27 13:24:53.000000000
submitted: --
approvals:
submit records:
1 change
查询语法即 Web UI 搜索框语法(status:open、is:merged、owner:、label:Code-Review=+2、project: 等可任意组合),管道接 -- 分隔符后可附加格式化字段:
gerrit query 'status:open' --format=JSON -- current_patch_set
--format=JSON 输出 JSONL(每行一个 Change 对象),是 CI 轮询拉取待验证 Change 的标准姿势(自动化示例见第五节)。
3.3 评审操作:review(打分/评论/合入)
3.x 的评审命令是 gerrit review,参数格式为 CHANGE,PATCHSET(实测:裸写 change 号报 is not a valid patch set,排障见第七节 7.2):
# 打 Code-Review +2 并留言
gerrit review --code-review +2 -m "LGTM via ssh" 2,1
# 合入
gerrit review --submit 2,1
实测:两条命令均静默成功,效果经 REST 复核——/changes/2/detail 显示 "labels":{"Code-Review":{"approved":{"name":"Gerrit Admin",...}}},/changes/2 显示 "status":"MERGED"。
常用变体:
gerrit review --abandon 3,1 # 废弃 Change
gerrit review --restore 3,1 # 恢复废弃
gerrit review --verified +1 4,1 # 打 Verified 分(装了对应标签的项目)
3.4 评审人管理:set-reviewers
gerrit set-reviewers -a admin 2 --project demo-project # 添加评审人(实测静默成功)
gerrit set-reviewers -r <group> 3 --project demo-project # 按组添加
gerrit set-reviewers -d <user> 3 --project demo-project # -d 移除
3.5 账户与群组管理:create-account / set-account / ls-groups
# 建服务账户并归入 Service Users 组(实测静默成功)
gerrit create-account reviewbot --group "Service Users" --full-name "Review Bot"
# 改账户属性(实测静默成功)
gerrit set-account admin --full-name "Gerrit Admin"
# 列群组
gerrit ls-groups
实测回显:
Administrators
Anonymous Users
Change Owner
Non-Interactive Users
Registered Users
Service Users
SSH 公钥的增删走 REST(/accounts/<user>/sshkeys,见 4.3),SSH 命令面不直接管理密钥。
3.6 运维维护:show-caches / flush-caches / 判定命令集
ssh -i ~/.ssh/gerrit_demo -p 8148 admin@localhost 'gerrit show-caches --width 80'
实测回显(输出节选,实测首尾):
Gerrit Code Review 3.14.4 now 13:25:08 UTC
uptime 3 min 16 sec
Name |Entries | AvgGet |Hit Ratio|
| Mem Disk Space| |Mem Disk|
--------------------------------+---------------------+---------+---------+
adv_bases | | | |
change_notes | 6 | 5.0ms | 91% |
changeid_project | 2 | | 87% |
default_preferences | | | |
external_ids_map | 2 | | 97% |
groups | | 4.7ms | 0% |
配套命令:
gerrit flush-caches --cache groups # 定向清缓存(改群组后立即生效的补救)
gerrit flush-caches --all # 全清(谨慎,热缓存全冷)
命令集版本差异(重要):2.x 时代的 gerrit approve、gerrit set-review、gerrit ls-users 在 3.14 实测均为 not found(排障实录 7.1),3.x 的替代命令分别是 gerrit review、gerrit review、REST /accounts/ 查询。
四、REST API 实测(curl 全流程)
REST 是评审流水线集成的主通道(Web UI 与 CI 都走它)。认证:读/写均可用 HTTP Basic(账户 http password),本节统一 -u admin:q1w2e3r4。
4.1 服务与项目
curl -s -u admin:q1w2e3r4 http://localhost:8141/config/server/version
curl -s -u admin:q1w2e3r4 'http://localhost:8141/a/projects/?d'
实测回显(projects 输出节选):
)]}'
"3.14.4"
)]}'
{"All-Projects":{"id":"All-Projects","description":"Access inherited by all other projects.","state":"ACTIVE","web_links":[{"name":"browse","url":"/plugins/gitiles/All-Projects"}]},"All-Users":{"id":"All-Users","description":"Individual user settings and preferences.","state":"ACTIVE","web_links":[{"name":"browse","url":"/plugins/gitiles/All-Users"}]},"demo-project":{"id":"demo-project","state":"ACTIVE","web_links":[{"name":"browse","url":"/plugins/gitiles/demo-project"}]}}
4.2 账户与凭据
# 当前身份
curl -s -u admin:q1w2e3r4 http://localhost:8141/a/accounts/self
# 账户详情
curl -s -u admin:q1w2e3r4 http://localhost:8141/a/accounts/admin/detail
# 设置 HTTP 凭据
curl -s -u admin:q1w2e3r4 -X PUT -H 'Content-Type: application/json' \
-d '{"http_password":"q1w2e3r4"}' \
'http://localhost:8141/a/accounts/self/password.http'
实测回显(detail 节选):
)]}'
{"registered_on":"2026-10-27 13:16:06.000000000","_account_id":1000000,"name":"admin","secondary_emails":[],"username":"admin","avatars":[...]}
4.3 SSH 公钥注册(REST 承载)
curl -s -u admin:q1w2e3r4 -X POST -H 'Content-Type: text/plain' \
--data-binary @~/.ssh/gerrit_demo.pub \
'http://localhost:8141/a/accounts/self/sshkeys'
实测回显(201 Created):
)]}'
{"seq":1,"ssh_public_key":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAeP...","algorithm":"ssh-ed25519","comment":"admin@demo","valid":true}
4.4 变更查询与评审闭环
# 查询(Web 搜索语法直通 REST)
curl -s -u admin:q1w2e3r4 'http://localhost:8141/a/changes/?q=status:merged&n=1'
实测回显(节选):
)]}'
[{"id":"demo-project~2","triplet_id":"demo-project~master~I2222222222222222222222222222222222222222","project":"demo-project","branch":"master","full_branch":"refs/heads/master","hashtags":[],"change_id":"I2222222222222222222222222222222222222222","subject":"Add second line","status":"MERGED",...,"submitted":"2026-10-27 13:24:53.000000000","submitter":{"_account_id":1000000},"insertions":1,"deletions":0,...,"_number":2,...}]
评审闭环三步(实测):
# 1. 打 Code-Review +2(POST,写 review 用 PUT 会 405 Method Not Allowed)
curl -s -u admin:q1w2e3r4 -X POST -H 'Content-Type: application/json' \
-d '{"labels":{"Code-Review":2},"message":"LGTM"}' \
'http://localhost:8141/a/changes/1/revisions/current/review'
# 2. 提交合入
curl -s -u admin:q1w2e3r4 -X POST -H 'Content-Type: application/json' -d '{}' \
'http://localhost:8141/a/changes/1/submit' | grep -oE '"status":"[A-Z]+"'
# 3. 复核状态
curl -s -u admin:q1w2e3r4 http://localhost:8141/a/changes/1 | grep -oE '"status":"[A-Z]+"'
第 2/3 步实测回显:
"status":"MERGED"
"status":"MERGED"
Change 的 REST 定位符三种形态实测均有效:数字(
/changes/1,最常用)、project~change_id(/changes/demo-project~1)、三段式project~branch~change_id(/changes/demo-project~master~1)。改动 Change 主体后注意revisions/current语义会随新 patchset 漂移。
4.5 能力清单(权限自检)
curl -s -u admin:q1w2e3r4 http://localhost:8141/a/accounts/self/capabilities
实测回显(节选):
)]}'
{"readAs":true,"viewAllAccounts":true,"replication-startReplication":true,"viewAccess":true,"delete-project-deleteOwnProject":true,"delete-project-deleteProject":true,"maintainServer":true,"viewQueue":true,"flushCaches":true,"runGC":true,"createAccount":true,"createGroup":true,"administrateServer":true,"emailReviewers":true,"createProject":true,"streamEvents":true,"viewPlugins":true,"deleteGroup":true,"killTask":true,"modifyAccount":true,"viewCaches":true,"viewConnections":true,"viewSecondaryEmails":true,"queryLimit":{"min":0,"max":500}}
服务账户授权时按需裁剪(CI 机器人只需 createProject/streamEvents/queryLimit 等少量能力)。
五、评审流水线自动化示例
组合 query + review 实现最小 CI 门禁轮询(shell 形态,生产可换成 Jenkins/Zuul 的 Gerrit 插件驱动):
#!/usr/bin/env bash
# gerrit-ci-poll.sh:轮询 open 变更,跑校验后回写 Verified 分
GERRIT_HOST=localhost; GERRIT_PORT=8148; GERRIT_USER=reviewbot
ssh -i /etc/gerrit-ci/id_ed25519 -p $GERRIT_PORT $GERRIT_USER@$GERRIT_HOST \
"gerrit query --format=JSON 'status:open project:demo-project verified:-1..+1'" \
| python3 -c 'import sys,json;[print(json.loads(l)["number"]) for l in sys.stdin if l.startswith("{")]'
| while read change; do
git fetch "ssh://$GERRIT_USER@$GERRIT_HOST:$GERRIT_PORT/demo-project" "$change" || continue
if make lint && make test; then
ssh -i /etc/gerrit-ci/id_ed25519 -p $GERRIT_PORT $GERRIT_USER@$GERRIT_HOST \
"gerrit review --verified +1 -m 'CI passed' $change,current"
else
ssh -i /etc/gerrit-ci/id_ed25519 -p $GERRIT_PORT $GERRIT_USER@$GERRIT_HOST \
"gerrit review --verified -1 -m 'CI failed' $change,current"
fi
done
要点:
git fetch <gerrit> <change号>可直接拉取任意 Change 的当前 patchset(Gerrit 对 Change 引用的原生支持,评审即代码);- 服务账户建户与归组见 3.5(
create-account reviewbot --group "Service Users"); - 更正式的门禁用 Submit Requirements 声明(配置篇 3.11 体系):「Verified +1 必须存在且 Code-Review +2 两人(其一非提交者)」。
六、常用命令速查表
| 场景 | SSH 命令 / REST | 备注 |
|---|---|---|
| 版本确认 | gerrit version | 值如 gerrit version 3.14.4 |
| 列/建项目 | gerrit ls-projects / gerrit create-project <n> | 建项目静默成功 |
| 查变更 | gerrit query '<表达式>' [--format=JSON] | 语法同 Web 搜索框 |
| 打分/留言 | gerrit review --code-review +2 -m "..." <c>,<p> | change,patchset 格式 |
| 合入/废弃 | gerrit review --submit <c>,<p> / --abandon | 同上格式 |
| 评审人 | gerrit set-reviewers -a <u> <c> --project <p> | -d 移除 |
| 建服务账户 | gerrit create-account <n> --group "<g>" | 归 Service Users 组 |
| 改账户 | gerrit set-account <n> --full-name "<f>" | 静默成功 |
| 群组清单 | gerrit ls-groups | 含系统组 |
| 缓存观测/清理 | gerrit show-caches / gerrit flush-caches | --width 80 控表宽 |
| REST 版本 | GET /config/server/version | 剥 )]}' 前缀 |
| REST 查询 | GET /a/changes/?q=<expr> | JSON 数组 |
| REST 打分 | POST /a/changes/<c>/revisions/current/review | 必须是 POST |
| REST 合入 | POST /a/changes/<c>/submit | 返回 MERGED |
七、排障实录
7.1 2.x 老命令 3.x 报 not found
现象(实测):
ssh -p 8148 admin@localhost gerrit approve --code-review +2 2
# ssh: remote command failed: exit status 1(命令不存在)
结论:gerrit approve / gerrit set-review / gerrit ls-users 在 3.x 已移除;替代分别是 gerrit review(打分/合入/废弃)、gerrit review、REST GET /accounts/?q=(查用户)。网上大量旧资料仍教 2.x 命令,照抄即报错。
7.2 review 命令报 is not a valid patch set
现象(实测):
gerrit review --code-review +2 2
# fatal: 2 is not a valid patch set
根因:3.x 的 review 参数是 CHANGE,PATCHSET 逗号组合。解决:写 gerrit review --code-review +2 2,1(实测成功,REST 复核 approved 生效)。
7.3 REST 打分端点 405 Method Not Allowed
现象:PUT /a/changes/1/revisions/current/review 返回 405。结论:review 动作只支持 POST。解决:改用 POST(回显见 4.4),提交合入 /submit 同为 POST。
7.4 Change 已合入后同 Change-Id 重推被拒
现象(实测回显,部署篇同步沉淀):
! [remote rejected] HEAD -> refs/for/master (change http://localhost:8141/c/demo-project/+/1 closed)
根因:closed(MERGED/ABANDONED)状态不能追加 patchset。解决:git commit --amend 换新 Change-Id(或新提交)后重推产生新 Change。
7.5 写操作 401:会话 cookie 与 Basic 混用
现象:用登录页 cookie 做写操作报 Authentication required。根因:cookie 会话的写请求必须带 X-Gerrit-Auth: <XSRF_TOKEN> 头(浏览器自动处理,curl 要手工加);而 Basic(http password)认证的写请求不需要。解决:自动化一律走 Basic + http password(4.2 设置凭据),避免 cookie/XSRF 组合。
八、参考链接
- SSH 命令总览:https://gerrit-review.googlesource.com/Documentation/cmd-index.html
- gerrit query:https://gerrit-review.googlesource.com/Documentation/cmd-query.html
- gerrit review:https://gerrit-review.googlesource.com/Documentation/cmd-review.html
- REST API 总览:https://gerrit-review.googlesource.com/Documentation/rest-api.html
- REST changes API:https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html
- 用户搜索语法:https://gerrit-review.googlesource.com/Documentation/user-search.html
- 站内《Gerrit 3.14 Docker Compose 部署实战》:https://www.quzuo.net/document/ypUmjOG83Lt8
- 站内《Gerrit 配置参数详解》:https://www.quzuo.net/document/uzY1P2tFxQvE
- 站内《Gerrit 介绍与选型指南》:https://www.quzuo.net/document/jBzSHXoP3n0J