xref: /aosp_15_r20/external/openscreen/docs/advanced_gerrit.md (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1# Advanced Gerrit Usage
2
3This file gives some examples of Gerrit workflows.  This includes uploading
4patches with Gerrit, using Gerrit dependency chains, and managing local git
5history.
6
7## Managing patches with Gerrit
8
9The instructions in [README.md](README.md) using `git cl upload` are preferred
10for patch management.  However, you can interact manually with the Gerrit code
11review system via `git` if you prefer as follows.
12
13### Preliminaries
14
15You should install the
16[Change-Id commit-msg hook](https://gerrit-documentation.storage.googleapis.com/Documentation/2.14.7/cmd-hook-commit-msg.html).
17This adds a `Change-Id` line to each commit message locally, which Gerrit uses
18to track changes.  Once installed, this can be toggled with `git config
19gerrit.createChangeId <true|false>`.
20
21To download the commit-msg hook for the Open Screen repository, use the
22following command:
23
24```bash
25  curl -Lo .git/hooks/commit-msg https://chromium-review.googlesource.com/tools/hooks/commit-msg
26  chmod a+x .git/hooks/commit-msg
27```
28
29### Uploading a new patch for review
30
31You should run `git cl presubmit --upload` in the root of the repository before pushing for
32review (which primarily checks formatting).
33
34After verifying that presubmission works correctly, you can then execute:
35`git cl upload`, which will prompt you to verify the commit message and check
36for owners.
37
38The first time you upload an issue, the issue number is associated with the
39current branch. If you upload again, it uploads on the same issue (which is tied
40to the branch, not the commit). See the [git-cl](https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/HEAD/README.git-cl.md) documentation for more information.
41
42## Uploading a new dependent change
43
44If you wish to work on multiple related changes without waiting for them to
45land, you can do so in Gerrit using dependent changes.  There doesn't appear to
46be any official documentation for this, but the rule seems to be: if the parent
47of the commit you are pushing has a Change-Id line, that change will also be the
48current change's parent.  This is useful so you can look at only the relative
49diff between changes instead of looking at all of them relative to master.
50
51To put this into an example, let's say you have a commit for feature A with
52Change-Id: aaa and this is in the process of being reviewed on Gerrit.  Now
53let's say you want to start more work based on it before it lands on master.
54
55``` bash
56  git checkout featureA
57  git checkout -b featureB
58  git branch --set-upstream-to featureA
59  # ... edit some files
60  # ... git add ...
61  git commit
62```
63
64The git history then looks something like this:
65
66```
67  ... ----  master
68          \
69           A
70            \
71             B <- HEAD
72```
73
74and `git log` might show:
75
76```
77commit 47525d663586ba09f40e29fb5da1d23e496e0798 (HEAD -> featureB)
78Author: btolsch <[email protected]>
79Date:   Fri Mar 23 10:18:01 2018 -0700
80
81    Add some better things
82
83commit 167a541e0a2bd3de4710965193213aa1d912f050 (featureA)
84Author: btolsch <[email protected]>
85Date:   Thu Mar 22 13:18:09 2018 -0700
86
87    Add some good things
88
89    Change-Id: aaa
90```
91
92Now you can push B to create a new change for it in Gerrit:
93
94``` bash
95git push origin HEAD:refs/for/master
96```
97
98In Gerrit, there would then be a "relation chain" shown where the feature A
99change is the parent of the feature B change.  If A introduces a new file which
100B changes, the review for B will only show the diff from A.
101
102## Examples for maintaining local git history
103
104```
105                  D-E --- feature B
106                 /  ^N
107            A-B-C-F-G-H --- feature A
108           /    ^M  ^O
109          /
110  ... ----  master
111        /|
112       M O
113       |
114       N
115```
116
117Consider a local repo with a master branch and two feature branches.  Commits M,
118N, and O are squash commits that were pushed to Gerrit.  The arrow/caret (`^`)
119indicates whence those were created.  M, N, and O should all have Change-Id
120lines in them (this can be done with the [commit-msg
121hook](https://gerrit-documentation.storage.googleapis.com/Documentation/2.14.7/cmd-hook-commit-msg.html)).
122M and O are separate patchsets in one review (M containing A, B, C and O
123containing A, B, C, F, G) and N is the first patchset in a new review that is
124dependent on the first patchset of the first review.
125
126Starting without M, N, or O, the commands to create them are as follows:
127
128``` bash
129git checkout C
130git checkout -b M
131git rebase -i origin/master # squash commits
132# Note: make sure a Change-Id line exists on M at this point since N will need
133# it.  You can git commit --amend with the commit-msg hook active or add it via
134# git commit --amend after pushing.  Don't git commit --amend after creating N
135# though.
136git push origin HEAD:refs/for/master
137git checkout E
138git checkout -b N
139git rebase -i C --onto M # squash commits
140git push origin HEAD:refs/for/master
141git checkout G
142git checkout -b O
143git rebase -i origin/master # squash commits and copy the Change-Id line from M
144git push origin HEAD:refs/for/master
145```
146
147```
148                        D-E --- feature B
149                       /  ^Q
150            A-B-C-F-G-H --- feature A
151           /          ^P
152          /
153  ... ----  master
154         /|\
155        M O P
156        |   |
157        N   Q
158```
159
160The next example shows an additional patchset being uploaded for feature A
161(commit P) and feature B being rebased onto A, then uploaded to Gerrit as commit
162Q.
163
164Starting from the endpoint of the previous commands, this point can be reached
165as follows:
166
167``` bash
168git checkout H
169git checkout -b P
170git rebase -i origin/master # squash commits, same note as M about Change-Id
171git push origin HEAD:refs/for/master
172git checkout featureB # E
173git rebase # assume featureA is set as featureB's upstream branch
174git checkout -b Q
175git rebase -i H --onto P
176git push origin HEAD:refs/for/master
177```
178