Marian Harbach | ebeb154 | 2019-12-13 10:42:46 +0100 | [diff] [blame] | 1 | :linkattrs: |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 2 | = Basic Gerrit Walkthrough -- For GitHub Users |
| 3 | |
| 4 | |
| 5 | [NOTE] |
| 6 | ==== |
| 7 | This document aims to provide a concise description of the core principles of |
| 8 | code review in Gerrit for people that were previously using Pull Requests on |
| 9 | Github or similar concepts. Nothing in this document is meant to state that |
| 10 | one or the other might be better, but only aims to help new users understand |
| 11 | Gerrit more readily. We use Github as the point of comparison since it seems |
| 12 | to be the most popular service. |
| 13 | ==== |
| 14 | |
| 15 | To illustrate the differences in a meaningful order, we will walk you through |
| 16 | the process of cloning a repo, making a change, asking for code review, |
| 17 | iterating on the code and finally having it submitted to the code base. This |
| 18 | document also does not aim to describe all features of Gerrit. Please refer to |
| 19 | the link:intro-gerrit-walkthrough.html[Basic Gerrit Walkthrough] or |
| 20 | link:index.html[the rest of the documentation] for a more complete overview and additional pointers. |
| 21 | |
| 22 | [[tldr]] |
| 23 | == tl;dr |
| 24 | |
| 25 | Here’s how getting code reviewed and submitted with Gerrit is different from |
| 26 | doing the same with GitHub: |
| 27 | |
Matthias Sohn | 25f9654 | 2021-06-03 19:04:50 +0200 | [diff] [blame] | 28 | * You need to add a commit-msg hook script when you clone a repo for the first |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 29 | time using a snippet you can find e.g. https://gerrit-review.googlesource.com/admin/repos/gerrit[here,role=external,window=_blank]; |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 30 | * Your review will be on a single commit instead of a branch. You use |
| 31 | `git commit --amend` to modify a code change. |
| 32 | * Instead of using the Web UI to create a pull request, you use |
| 33 | `git push origin HEAD:refs/for/master` to upload new local commits that are |
| 34 | ready for review to Gerrit. You will find the URL to the review in the output of |
| 35 | the push command. |
| 36 | * As a reviewer, Gerrit offers a number of so-called labels to vote on, one of |
| 37 | which is Code-Review. You indicate a negative, neutral or positive review using |
| 38 | a -1, 0 or +1 vote. |
| 39 | * To be able to submit (== merge) a change, you usually need a +2 Code-Review |
| 40 | vote and possibly additional positive votes, depending on the configuration of |
| 41 | the project you are contributing to. |
| 42 | |
| 43 | [[clone]] |
| 44 | == 1. Cloning a Repository |
| 45 | |
| 46 | [NOTE] |
| 47 | ==== |
| 48 | Both GitHub and Gerrit provide simple Git repository hosting (of course both can |
| 49 | do much more). In the simplest setup, you could just use both as such without |
| 50 | any code review to push code. We will assume that this is not what you want to |
| 51 | do and focus on the use case where your change requires a review. |
| 52 | ==== |
| 53 | |
| 54 | The first step to working with the code is to clone the repo. For both, Gerrit |
| 55 | and GitHub, you can simply use the `git clone` command. |
| 56 | |
| 57 | For Gerrit, there is an additional step before you can start making changes. For |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 58 | reasons we explain below, you’ll have to add a https://gerrit-review.googlesource.com/Documentation/user-changeid.html[commit-msg hook,role=external,window=_blank] script. This will |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 59 | append the Gerrit Change-Id to every commit message such that Gerrit can track |
| 60 | commits through the review process. To make this process a little easier in |
| 61 | Gerrit, you can find a command snippet for cloning and adding the commit-msg |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 62 | hook on the repository page (e.g. https://gerrit-review.googlesource.com/admin/repos/gerrit[here,role=external,window=_blank]). |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 63 | |
| 64 | [[create-change]] |
| 65 | == 2. Making a Change |
| 66 | |
| 67 | *Branches* |
| 68 | |
| 69 | Now that you have the code in the git repo on your machine, you can start making |
| 70 | changes. With GitHub, you would usually create a new branch and then start |
| 71 | committing to it. This branch would then contain all the changes you share with |
| 72 | your code reviewers in the next step. Your local branch will usually also be |
| 73 | pushed to the remote server. This can be handy to back up your work or hand-off |
| 74 | work to another device or developer. |
| 75 | |
| 76 | With Gerrit, you can also create a new local branch to develop in. While not |
| 77 | required, it can be considered a best practice to sandbox this change from other |
| 78 | changes you might be making. In contrast to the GitHub model, your local branch |
| 79 | will not have to be pushed to the remote in Gerrit, at least not for the |
| 80 | purposes of code review. |
| 81 | |
| 82 | *Commits* |
| 83 | In Gerrit, a single commit is the unit of code that will be reviewed. With |
| 84 | GitHub, you can commit to your branch as much as you like and the sum of all |
| 85 | your commits on that branch will get reviewed. As a single commit gets reviewed |
| 86 | in Gerrit, you need to `git commit --amend` when you iterate on the same change as |
| 87 | opposed to only using `git commit` with GitHub (see Section 5 for more). You can, |
| 88 | however, also add another commit on top of your existing commit in Gerrit, which |
| 89 | will create a second change (and thus another review) that is based on your |
| 90 | first change. Gerrit will show the relationship between these two changes as a |
| 91 | so-called relation chain. This also means that your second change can only be |
| 92 | submitted after the first was successfully merged. In many basic use cases, this |
| 93 | situation is however not what you want. |
| 94 | |
| 95 | image::images/user-review-ui-change-relation-chain.png[Relation chain display on the change page.] |
| 96 | |
| 97 | With GitHub, you may be pushing your branch to the remote for non-code-review |
| 98 | purposes, as mentioned above. You usually do not do this with Gerrit, as |
| 99 | Gerrit-managed repos often only have one or a few branches on the server that |
| 100 | can only be merged into via code review. |
| 101 | |
| 102 | [[request-review]] |
| 103 | == 3. Asking for Code Review |
| 104 | |
| 105 | After you are satisfied with the changes you made, you’ll usually want/need to |
| 106 | get your code reviewed. In GitHub, you would push your branch to the remote, go |
| 107 | to the Web UI and create a pull request. In Gerrit, you need to push your commit |
| 108 | (or the series of changes/commits) to the remote first, since you usually |
| 109 | develop in a local branch only. While you can often just use git push with |
| 110 | GitHub, you need to do a slightly different thing for Gerrit. Gerrit uses a |
| 111 | “magic” branch that tells the server that this code is supposed to be reviewed. |
| 112 | To send the changes you made on your local branch to review and being eventually |
| 113 | merged into the remote’s master branch, you use |
| 114 | `git push origin HEAD:refs/for/master`. There are also link:user-upload.html#_git_push[a number of Gerrit change |
| 115 | options] you can trigger from the CLI this way. |
| 116 | |
| 117 | After successfully pushing your change to Gerrit, you will already find the URL |
| 118 | for viewing your change in Gerrit’s Web UI in the response you get from the |
| 119 | server. The description of the Gerrit code review that was just created is equal |
| 120 | to the commit message of that one commit the change is based on. In GitHub, you |
| 121 | might have described your change in the message you can create when creating the |
| 122 | pull request in the GitHub Web UI. |
| 123 | |
| 124 | Next, you would go and visit your Gerrit change in the Web UI to get your change |
| 125 | ready for review (choose reviewers, cc people, check for failing CI builds or |
| 126 | tests, etc.), very similar to what you do on Github. Reviewers will be notified |
| 127 | via email once you add them. By default, anyone can add reviewers to a Gerrit |
| 128 | change. In GitHub, this ability is reserved for certain users, so you may have |
| 129 | relied on others adding reviewers for you before. This can be the case in a |
| 130 | Gerrit project, but it is also often expected that the change owner (usually the |
| 131 | creator of the change) adds reviewers to get the review process started. |
| 132 | |
| 133 | [[reviewing]] |
| 134 | == 4. Reviewing a Change |
| 135 | |
| 136 | Switching perspectives briefly, reviewing a change is fairly similar between |
| 137 | GitHub and Gerrit. You, as a reviewer, will be notified of a change you have |
| 138 | been added to via email or see an “incoming” change on your Gerrit dashboard. |
| 139 | The dashboard is the central overview of changes going on within a Gerrit |
| 140 | instance. By default, the dashboard shows changes that you are involved in, in |
| 141 | any way. You can also see all changes on a Gerrit server by using the top menu |
| 142 | (“Changes” -> “Open”). This view is more similar to what you see on Github, when |
| 143 | you navigate to the Pull Requests tab of the project/repository you are working |
| 144 | on. Note, however, that a single Gerrit instance can host multiple projects |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 145 | (also referred to as repositories; a list can be found, for example, https://gerrit-review.googlesource.com/admin/repos[here,role=external,window=_blank]). Your |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 146 | dashboard and other lists of changes will show all changes across the |
| 147 | projects/repositories by default. |
| 148 | |
| 149 | Back to your dashboard, you can click on the change you want to review. You can |
| 150 | also access this from the email you received. You will see the same view that |
| 151 | you saw as an author. In the middle of the change page, you can find the list of |
| 152 | files that have been modified, just like what you find in the “Files changed” |
| 153 | tab of GitHub. Also similarly, you can leave comments by highlighting a piece of |
| 154 | the code and pressing ‘c’. All comments you make are in a draft state and thus |
| 155 | only visible to you, like on GitHub. When you are done with your review, you |
| 156 | need to click the “Reply” button at the top of the change page to send your |
| 157 | assessment to the change owner alongside a “change message” summarizing your |
| 158 | findings and/or adding higher level comments. Replying to a change makes your |
| 159 | draft comments and the change message visible on the change page for everyone |
| 160 | that has view access to this change. This again is fairly similar to GitHub, |
| 161 | except for Gerrit’s voting labels. |
| 162 | |
| 163 | image::images/user-review-ui-change-reply-dialogue.png[Reply dialogue for a Gerrit change.] |
| 164 | |
| 165 | As you can see in the screenshot of the reply dialogue, the voting labels are in |
| 166 | the bottom part of the dialogue. They can be fairly simple as in this case, but |
| 167 | there can also be a larger number of labels you might be able to vote on. Labels |
| 168 | can be used to distinguish different aspects of a review (e.g. whether or not |
| 169 | the licensing of included libraries is okay), outcome of CI systems (e.g. |
| 170 | whether or not a format checker passed, a build completed successfully, etc.) or |
| 171 | as a flag that is read by bots to do something with a change. An example of a |
| 172 | more complex label setup can be seen in this screenshot from the Android Gerrit |
| 173 | instance. |
| 174 | |
| 175 | image::images/user-review-ui-change-complex-reply-dialogue.png[Reply dialogue for a change on the Android project.] |
| 176 | |
| 177 | In the simplest case shown above, voting -1 on the Code-Review label equals |
| 178 | requesting changes on a GitHub pull request, 0 equals just having comments and |
| 179 | +1 means that you think this change looks good. Usually, Gerrit changes require |
| 180 | a +2 vote on the Code-Review label to be submitted (merged in GitHub terms, see |
| 181 | Section 6 below). Being able to vote +2 on Code-Review is often restricted to |
| 182 | maintainers of a given project, so they can have a final say on a change. These |
| 183 | practices can however vary between projects, as labels and voting permissions |
| 184 | are configurable. |
| 185 | |
| 186 | [[iterate]] |
| 187 | == 5. Iterating on the Change |
| 188 | |
| 189 | After your reviewers got back to you as a change owner, you realize that you |
| 190 | need to make a few updates to the code in your change. As mentioned in Section 2 |
| 191 | (Making a Change), you’ll have to amend the commit that this review was based |
| 192 | on. To do that, you might have to checkout the respective commit first if it is |
| 193 | not at the tip of your local branch, for example if you stacked multiple changes |
| 194 | on top of each other. Another common use case is to not have a local branch but |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 195 | to work in the so-called https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit["detached HEAD",role=external,window=_blank] mode. In that case you can use the |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 196 | “Download” button on the files tab to copy a command that fetches and checks out |
| 197 | the commit underlying your change. Make sure to select the latest patchset, |
| 198 | though! |
| 199 | |
| 200 | image::images/user-review-ui-change-page-download.png[Using the “Download” button to copy a command that checks out a given patchset for a change.] |
| 201 | |
| 202 | After checking out the commit, you then make the changes as usual. When you |
| 203 | think you are done, you can commit with the `--amend` flag to change the commit |
| 204 | you currently have checked out. |
| 205 | |
| 206 | When you `git commit --amend` to iterate on your change, you might be worried that |
| 207 | you are changing your previous commit and may thus lose that state of your work. |
| 208 | However, here the Change-Id appended to your commit message comes into play. |
Han-Wen Nienhuys | 37a1cab | 2021-04-01 12:46:00 +0200 | [diff] [blame] | 209 | While the SHA-1 hash of your change (the commit ID used by Git) might change, the |
| 210 | Change-Id stays the same (in fact it is the SHA-1 hash of the very first version |
Marian Harbach | cc3e015 | 2019-12-09 11:42:40 +0100 | [diff] [blame] | 211 | of that commit). When this amended commit is uploaded to the Gerrit server, |
| 212 | Gerrit knows that this commit is really an iteration of that previous commit |
| 213 | (and the associated review) and will preserve both, the old and the new state. |
| 214 | All previous states of your commit will be visible in the Gerrit UI as so-called |
| 215 | patchsets (and link:intro-user.html#change-ref[from the Git repo]). |
| 216 | |
| 217 | image::images/user-review-ui-change-page-patchset-dropdown.png[Screenshot of the patchset dropdown above the file list, showing all iterations a commit went through.] |
| 218 | |
| 219 | After iterating as much as needed, your reviewers will finally be satisfied. |
| 220 | With GitHub, you would have a string of additional commits in the branch you |
| 221 | used for opening the pull request. In Gerrit, you still only have that one |
| 222 | commit in your local branch. All the iterations are available as patchsets in |
| 223 | the Web UI as well as from the special branch mentioned above. |
| 224 | |
| 225 | [[submit]] |
| 226 | == 6. Submitting a Change |
| 227 | |
| 228 | Finally, it is time to submit your change. As mentioned above, the precondition |
| 229 | for this in Gerrit is usually at least a +2 vote on the Code-Review label. With |
| 230 | GitHub, an authorized person must have given an “Approve” vote. Once this |
| 231 | precondition has been met, anyone with submit permission can submit the change |
| 232 | in Gerrit. To do that, you click the “Submit” button in the Gerrit Web UI just |
| 233 | as you would click the “Merge Pull Request” button in GitHub. Both, Gerrit and |
| 234 | GitHub, allow different merge strategies, that can be enabled by project |
| 235 | administrators. In Gerrit, a merge strategy is configured for each project and |
| 236 | cannot be changed at submit time while this may be possible with GitHub, |
| 237 | depending on project configuration. |
| 238 | |
| 239 | A merge can fail due to conflicts with competing edits on the target branch. |
| 240 | With GitHub, you may be able to resolve some simple conflicts directly from the |
| 241 | Web UI. In Gerrit, you can attempt to rebase a change from the Web UI. If there |
| 242 | are no conflicts, a new patchset will automatically appear. Otherwise, similar |
| 243 | to GitHub, you need to resolve conflicts on the command line with your local |
| 244 | clone of the repository. While you resolve conflicts that arise from a |
| 245 | `git merge` for GitHub, you will need to link:intro-user.html#rebase[use `git rebase` with your change] on |
| 246 | Gerrit. |
| 247 | |
| 248 | After resolving locally, with GitHub, you end up with another commit on your |
| 249 | pull request branch and push it to the server, which should then allow you to |
| 250 | finish merging the change. With Gerrit, resolving the conflict through rebasing |
| 251 | your commit/change results in another amended version of that same commit and |
| 252 | you upload it to Gerrit, resulting in a new patchset just like your previous |
| 253 | iterations addressing reviewer comments. This new patchset will usually require |
| 254 | another round of reviewer votes, as Gerrit will not copy votes from a previous |
| 255 | patchset by default. |
| 256 | |
| 257 | |
| 258 | GERRIT |
| 259 | ------ |
| 260 | |
| 261 | Part of link:index.html[Gerrit Code Review] |
| 262 | |
| 263 | SEARCHBOX |
| 264 | --------- |