Gerrit
Learning materials
- https://gerrit-review.googlesource.com/Documentation/intro-user.html
- https://docs.google.com/presentation/d/1C73UgQdzZDw0gzpaEqIC6SPujZJhqamyqO1XOHjH-uk/view
Our installation
Gerrit is at https://gerrit.lix.systems
The Gerrit SSH server is running on port 2022. The repo URLs are:
-
ssh://{username}@gerrit.lix.systems:2022/lix
-
https://gerrit.lix.systems/lix
if using HTTP auth; see Gerrit settings for setting an HTTP password if desired
Hit the d key on any change to download it, which will give you the right URLs.
Basic workflow for a change
The unit of code review is a single commit (see "commit history shape" below). The commit message is what appears in the change description in Gerrit; in our experience this tends to lead to more comprehensive commit messages.
For a change to be merged, it must have the following four "votes", in Gerrit's terminology:
- Set by reviewers:
- +2 Code-Review: the committer that reviewed this thinks it can be submitted as-is (all users can vote +1/-1, expressing a weaker view on code acceptability)
- +1 Has-Release-Notes: means the reviewer thinks your commit added relevant release notes for that commit, or that it does not need any. This serves primarily as a reminder; you can set this yourself if you wish.
- +1 Has-Tests: means the reviewer thinks your commit added all the tests that commit needs, or that it does not need additional tests. Like Has-Release-Notes, this serves primarily as a reminder and can be set by change authors.
- Set automatically by CI:
- +1 Verified: means CI successfully built for all our platforms and passed all tests
When all of those labels are set, a change becomes Ready to submit, in Gerrit's termology, and Gerrit will give you a Submit button in the top right:
By convention, the change author has the final say on clicking the Submit button (note: this is the opposite of the Github convention), and there is no special permission to merge a change once it has been fully reviewed (the permissions are in the reviewer +2'ing it). This gives you a last chance to have a look at your change before merging it.
Workflow tips
Commit history shape
Gerrit is very mean to you if you don't have your commit history in a linear presentable state. Gerrit uses the commit history to get the relations of your changelists, which takes getting used to but it is very low overhead once you get used to it.
Consider not pushing for review before it is clean, or split commits up with git-revise
(good) or jj
(better) after the fact, amending as you work. If you want a backup of your changes, you can fork it on Forgejo and push to that fork.
Pushing
The correct way to push to Gerrit is (if your remote is called origin
, as it is by default):
git push origin HEAD:refs/for/main
If you get tired of doing this every time, you can automate it by setting the .git/config
as follows:
git config remote.origin.push HEAD:refs/for/main
You will have to do that in each fresh check-out. Once it's done, git push
will work without additional options.
If you wish to push a change and immediately mark it as WIP, you can push with -o wip
, or make that the default behavior by checking Set new changes to "work in progress" by default
in Gerrit's user settings, under "Preferences".
Topics
A Gerrit topic may be set on push with:
git push origin HEAD:refs/for/main%topic=foo
Which will create all pushed changes with the topic "foo". Topics are helpful for grouping long series of related changes.
Pulling
Pulling from Gerrit will work normally. It's worth keeping in mind that sometimes a CL you're working on has been edited in the web UI or by another contributor, so the commit in your repo isn't the latest. Rebasing will usually make the duplicate go away; this is part of the normal rebase semantics, not Gerrit magic. You might consider making rebase-on-pull your default.
Sandbox branches
This feature has some notable ways to shoot yourself in the foot. We still support it, since it allows for running CI builds on things before they become proper CLs. If you don't need that and don't want to worry about the footguns, consider using a branch on a Forgejo fork for sharing WIP code.
In particular, if a commit is in any branch already including a sb/
branch, it will be rejected with the error "no new changes" if it is later pushed to refs/for/main
. This can be worked around by amending all the commits so they are distinct, or by git push origin HEAD:refs/for/main%base=$(git rev-parse origin/main)
, which forces the merge-base
Use refs/heads/sb/USERNAME/*
.
CI rerun
Push the CL again with a no-changes commit amendment if you want to force CI to rerun.
Finding CLs to review
Consider bookmarking: https://gerrit.lix.systems/q/status:open+-is:wip+-author:me+label:Code-Review%3C2