Working with Gerrit
The Gerrit-based workflow prefers small commits that get reviewed individually,
as "changelists" (CLs). jj
is well suited for this workflow: each jj
change
can be a single CL which you can update over time.
Change IDs
Similar to jj
's change IDs, Gerrit associates commits with a common "change"
using a Change-Id
header in the commits. Gerrit repositories typically use a
Git commit hook to add change IDs to commits, you can configure jj
to do the
same with this configuration:
[templates]
commit_trailers = '''
if(self.author().email() == "YOUR_EMAIL_HERE" &&
!trailers.contains_key("Change-Id"),
format_gerrit_change_id_trailer(self)
)
Push workflow
In a traditional Gerrit workflow, you push commits to the review server using
git push origin <rev>:refs/for/main
.
Repositories using depot_tools
will likely teach you about the git cl upload
workflow instead: which by default will only push from a named, checked-out
branch, and will squash all commits into a single change upstream
(overrideable with --no-squash
).
If working with jj
, it is convenient for a single jj
change to be a single
Gerrit change. jj
also likes to keep the repository in "detached HEAD" mode,
so git cl upload
needs a git checkout <branchname>
first to work. As such,
git cl upload
is not the best way to interact with a jj
repository.
Regardless of whether or not you are using depot_tools
, jj
works best with
Gerrit when you build on top of the refs/for/main
primitive.
The following alias makes uploading to Gerrit with jj
convenient:
[aliases]
cl-up = ["util", "exec", "--", "bash", "-c", """
set -euo pipefail
INPUT=${1:-"@-"}
HASH=$(jj log -r "${INPUT}" -T commit_id --no-graph)
HASHINFO=$(git log -n 1 ${HASH} --oneline --color=always)
echo "Pushing from commit ${HASHINFO}"
git push origin "${HASH}":refs/for/main
""", ""]
jj cl-up <rev>
will push <rev>
(@-
if not specified) and its ancestors to
origin
, creating new CLs if necessary, updating existing ones otherwise.
Its output will look something like this:
$ jj
@ wtzvnrmz manishearth@google.com 2025-06-18 18:29:08 f694f9f1
│ (empty) (no description set)
○ zqlxpsus manishearth@google.com 2025-06-18 18:29:08 git_head() 556b213a
│ [temporal] Add Add/Subtract to all Temporal types
│ ○ rnnrzqpt manishearth@google.com 2025-06-18 18:29:08 8d16e5e5
├─╯ [temporal] Add remaining .with() methods
○ slwvqnrr manishearth@google.com 2025-06-18 18:28:52 e68229d4
│ [temporal] Add `wrapped_rust()` helper for writing generic code
│ ○ vtszmlsx manishearth@google.com 2025-06-18 18:25:38 c14b9e56
├─╯ [temporal] Add PlainTime.{compare, with}
○ xrvwxply manishearth@google.com 2025-06-18 18:24:28 f4ac4ff7
│ [temporal] Add IsPartialTemporalObject
│ ○ tlmqwnpn manishearth@google.com 2025-06-18 17:02:40 df3c2fa5
├─╯ Fix comment about enable_rust
◆ ytnpqlum manishearth@google.com 2025-06-18 16:38:37 main@origin 1f5d17d2
│ [temporal] Add GetTemporalRelativeToOption, use it
~
$ jj cl-up
Pushing from commit 556b213a122 [temporal] Add Add/Subtract to all Temporal types
Enumerating objects: 16, done.
Counting objects: 100% (16/16), done.
Delta compression using up to 14 threads
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 2.77 KiB | 61.00 KiB/s, done.
Total 11 (delta 9), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (9/9)
remote: Waiting for private key checker: 3/3 objects left
remote: Processing changes: refs: 1, new: 1, updated: 1, done
remote:
remote: SUCCESS
remote:
remote: https://chromium-review.googlesource.com/c/v8/v8/+/6654560 [temporal] Add `wrapped_rust()` helper for writing generic code [NEW]
remote: https://chromium-review.googlesource.com/c/v8/v8/+/6653151 [temporal] Add Add/Subtract to all Temporal types
remote:
To sso://chromium/v8/v8.git
* [new reference] 556b213a122d5a0dad5bdd5dd0a1485a303e9ea1 -> refs/for/main
Here, it pushed commits zqlxpsus
and slwvqnrr
, creating/updating changes for
them. Change xrvwxply
was also in the history but not pushed since it was
already up to date upstream. Other changes were not pushed since they were not ancestors of @
.