File: gerrit.md

package info (click to toggle)
jujutsu 0.37.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 11,728 kB
  • sloc: sh: 283; makefile: 32
file content (147 lines) | stat: -rw-r--r-- 5,609 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# Using Jujutsu with Gerrit Code Review

JJ and Gerrit share the same mental model, which makes Gerrit feel like a
natural collaboration tool for JJ. JJ tracks a "change identity" across
rewrites, and Gerrit’s `Change-Id` tracks the same logical change across patch
sets. JJ and Gerrit's `Change-Id`s aren’t natively compatible yet, but they’re
philosophically aligned. `jj gerrit upload` bridges the gap today by adding a
Gerrit-style `Change-Id` while JJ keeps its own notion of change identity on the
client. In practice, that means small, clean commits that evolve over
time, exactly how Gerrit wants you to work.

This guide assumes a basic understanding of Git, Gerrit, and Jujutsu.

## Set up a Gerrit remote

Jujutsu communicates with Gerrit by pushing commits to a Git remote. If you're
starting from an existing Git repository with Gerrit remotes already configured,
you can use `jj git init --colocate` to start using JJ in that repo. Otherwise,
set up your Gerrit remote.

```shell
# Option 1: Start JJ in an existing Git repo with Gerrit remotes
$ jj git init --colocate

# Option 2: Add a Gerrit remote to a JJ repo
$ jj git remote add gerrit https://review.gerrithub.io/yourname/yourproject

# Option 3: Clone the repo via jj
$ jj git clone https://review.gerrithub.io/your/project
```

If you used option 2 You can configure default values in your repository config
by appending the below to `.jj/repo/config.toml`, like so:

```toml
[gerrit]
default-remote = "gerrit"       # name of the Git remote to push to
default-remote-branch = "main"  # target branch in Gerrit
```

## Basic workflow

`jj gerrit upload` takes one or more revsets, and uploads the stack of commits
ending in them to Gerrit. Each JJ change will map to a single Gerrit change
based on the JJ change ID. This should be what you want most of the time, but if
you want to associate a JJ change with a specific change already uploaded to
Gerrit, you can copy the Change-Id footer from Gerrit to the bottom of the
commit description in JJ.

> Note: Gerrit identifies and updates changes by the `Change-Id` trailer. When
> you re-upload a commit with the same `Change-Id`, Gerrit creates a new patch
> set.

### Upload a single change

```shell
# upload the previous commit (@-) for review to main
$ jj gerrit upload -r @-
```

## Selecting revisions (revsets)

`jj gerrit upload` accepts one or more `-r/--revisions` arguments. Each argument
may expand to multiple commits. Common patterns:

- `-r @-`: the commit previous to the one you're currently working on
- `-r A..B`: commits that are ancestors of B but not of A

See the [revsets](revsets.md) guide for more information.

### Preview without pushing

Use `--dry-run` to see which commits would be modified and pushed, and where,
without changing anything or contacting the remote.

```shell
$ jj gerrit upload -r '@-' --remote-branch main --dry-run
```

## Target branch and remote selection

There are a few way of specifying the target remote for your projects:

- Please run `jj config set --user gerrit.default-remote-branch <branch name>` to set your
  default branch across all repos
- Please run `jj config set --repo gerrit.default-remote-branch <branch name>` to set your
  default branch for this specific repo.
- Use `--remote-branch <branch name>` to override this for one specific occasion.

The remote used to push is determined as follows:

- If you have more than one origin, or the origin isn't called gerrit, run
  `jj config set --repo gerrit.default_remote <gerrit remote name>` to set-up a
  default remote.
- To upload to a specific remote as a one-off thing, use `--remote <remote name>`

## Updating changes after review

To address review feedback, update your revisions, then run `jj gerrit
upload` again with the same revsets. Gerrit will add new patch sets to the
existing changes instead of creating new ones.

Examples:

```shell
# Edit an earlier commit in the stack
$ jj edit xcv  # position on the stack to edit
 --- Apply needed edits ---
$ jj gerrit upload -r xcv
```

## `Change-Id` management

When uploading, `jj gerrit upload` adds a `Change-Id` footer based on the JJ
change id. That means that any changes made to a JJ change will become a new
patch set on the Gerrit change during the next upload.

Keep this association in mind when splitting or squashing changes. For example,
when splitting a change, the portion that you want associated with the
original Gerrit change should remain in the original JJ change (the first half
of the split). Similarly, when squashing new changes, you typically want to
squash into the change that was previously uploaded to Gerrit.

If your JJ changes no longer align with the desired mapping to Gerrit changes,
you can manually copy a Gerrit `Change-Id` footer into your JJ change
description to directly assign a JJ change to an exist Gerrit change.

As an alternative to `jj gerrit upload`'s automatic `Change-Id` mapping, you
can configure JJ to automatically add `Change-Id` footers to all change
descriptions:

```toml
[templates]
commit_trailers = '''
if(
  !trailers.contains_key("Change-Id"),
  format_gerrit_change_id_trailer(self)
)
'''
```

In this case, the Gerrit change mapping is defined entirely by the `Change-Id`
footers. When splitting or squashing changes, be sure to keep the `Change-Id`
footers associated with the desired changes. Be sure not to duplicate the same
`Change-Id` across different changes. Gerrit will reject pushes that contain
duplicate `Change-Id`s, but if the uploads are done separately, you may
unintentionally overwrite an existing change.