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