blob: f16155bbd1251126e1dc48bf4beea3a2f138ea63 [file] [log] [blame]
:linkattrs:
= Basic Gerrit Walkthrough -- For GitHub Users
[NOTE]
====
This document aims to provide a concise description of the core principles of
code review in Gerrit for people that were previously using Pull Requests on
Github or similar concepts. Nothing in this document is meant to state that
one or the other might be better, but only aims to help new users understand
Gerrit more readily. We use Github as the point of comparison since it seems
to be the most popular service.
====
To illustrate the differences in a meaningful order, we will walk you through
the process of cloning a repo, making a change, asking for code review,
iterating on the code and finally having it submitted to the code base. This
document also does not aim to describe all features of Gerrit. Please refer to
the link:intro-gerrit-walkthrough.html[Basic Gerrit Walkthrough] or
link:index.html[the rest of the documentation] for a more complete overview and additional pointers.
[[tldr]]
== tl;dr
Here’s how getting code reviewed and submitted with Gerrit is different from
doing the same with GitHub:
* You need the add a commit-msg hook script when you clone a repo for the first
time using a snippet you can find e.g. https://gerrit-review.googlesource.com/admin/repos/gerrit[here,role=external,window=_blank];
* Your review will be on a single commit instead of a branch. You use
`git commit --amend` to modify a code change.
* Instead of using the Web UI to create a pull request, you use
`git push origin HEAD:refs/for/master` to upload new local commits that are
ready for review to Gerrit. You will find the URL to the review in the output of
the push command.
* As a reviewer, Gerrit offers a number of so-called labels to vote on, one of
which is Code-Review. You indicate a negative, neutral or positive review using
a -1, 0 or +1 vote.
* To be able to submit (== merge) a change, you usually need a +2 Code-Review
vote and possibly additional positive votes, depending on the configuration of
the project you are contributing to.
[[clone]]
== 1. Cloning a Repository
[NOTE]
====
Both GitHub and Gerrit provide simple Git repository hosting (of course both can
do much more). In the simplest setup, you could just use both as such without
any code review to push code. We will assume that this is not what you want to
do and focus on the use case where your change requires a review.
====
The first step to working with the code is to clone the repo. For both, Gerrit
and GitHub, you can simply use the `git clone` command.
For Gerrit, there is an additional step before you can start making changes. For
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
append the Gerrit Change-Id to every commit message such that Gerrit can track
commits through the review process. To make this process a little easier in
Gerrit, you can find a command snippet for cloning and adding the commit-msg
hook on the repository page (e.g. https://gerrit-review.googlesource.com/admin/repos/gerrit[here,role=external,window=_blank]).
[[create-change]]
== 2. Making a Change
*Branches*
Now that you have the code in the git repo on your machine, you can start making
changes. With GitHub, you would usually create a new branch and then start
committing to it. This branch would then contain all the changes you share with
your code reviewers in the next step. Your local branch will usually also be
pushed to the remote server. This can be handy to back up your work or hand-off
work to another device or developer.
With Gerrit, you can also create a new local branch to develop in. While not
required, it can be considered a best practice to sandbox this change from other
changes you might be making. In contrast to the GitHub model, your local branch
will not have to be pushed to the remote in Gerrit, at least not for the
purposes of code review.
*Commits*
In Gerrit, a single commit is the unit of code that will be reviewed. With
GitHub, you can commit to your branch as much as you like and the sum of all
your commits on that branch will get reviewed. As a single commit gets reviewed
in Gerrit, you need to `git commit --amend` when you iterate on the same change as
opposed to only using `git commit` with GitHub (see Section 5 for more). You can,
however, also add another commit on top of your existing commit in Gerrit, which
will create a second change (and thus another review) that is based on your
first change. Gerrit will show the relationship between these two changes as a
so-called relation chain. This also means that your second change can only be
submitted after the first was successfully merged. In many basic use cases, this
situation is however not what you want.
image::images/user-review-ui-change-relation-chain.png[Relation chain display on the change page.]
With GitHub, you may be pushing your branch to the remote for non-code-review
purposes, as mentioned above. You usually do not do this with Gerrit, as
Gerrit-managed repos often only have one or a few branches on the server that
can only be merged into via code review.
[[request-review]]
== 3. Asking for Code Review
After you are satisfied with the changes you made, you’ll usually want/need to
get your code reviewed. In GitHub, you would push your branch to the remote, go
to the Web UI and create a pull request. In Gerrit, you need to push your commit
(or the series of changes/commits) to the remote first, since you usually
develop in a local branch only. While you can often just use git push with
GitHub, you need to do a slightly different thing for Gerrit. Gerrit uses a
“magic” branch that tells the server that this code is supposed to be reviewed.
To send the changes you made on your local branch to review and being eventually
merged into the remote’s master branch, you use
`git push origin HEAD:refs/for/master`. There are also link:user-upload.html#_git_push[a number of Gerrit change
options] you can trigger from the CLI this way.
After successfully pushing your change to Gerrit, you will already find the URL
for viewing your change in Gerrit’s Web UI in the response you get from the
server. The description of the Gerrit code review that was just created is equal
to the commit message of that one commit the change is based on. In GitHub, you
might have described your change in the message you can create when creating the
pull request in the GitHub Web UI.
Next, you would go and visit your Gerrit change in the Web UI to get your change
ready for review (choose reviewers, cc people, check for failing CI builds or
tests, etc.), very similar to what you do on Github. Reviewers will be notified
via email once you add them. By default, anyone can add reviewers to a Gerrit
change. In GitHub, this ability is reserved for certain users, so you may have
relied on others adding reviewers for you before. This can be the case in a
Gerrit project, but it is also often expected that the change owner (usually the
creator of the change) adds reviewers to get the review process started.
[[reviewing]]
== 4. Reviewing a Change
Switching perspectives briefly, reviewing a change is fairly similar between
GitHub and Gerrit. You, as a reviewer, will be notified of a change you have
been added to via email or see an “incoming” change on your Gerrit dashboard.
The dashboard is the central overview of changes going on within a Gerrit
instance. By default, the dashboard shows changes that you are involved in, in
any way. You can also see all changes on a Gerrit server by using the top menu
(“Changes” -> “Open”). This view is more similar to what you see on Github, when
you navigate to the Pull Requests tab of the project/repository you are working
on. Note, however, that a single Gerrit instance can host multiple projects
(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
dashboard and other lists of changes will show all changes across the
projects/repositories by default.
Back to your dashboard, you can click on the change you want to review. You can
also access this from the email you received. You will see the same view that
you saw as an author. In the middle of the change page, you can find the list of
files that have been modified, just like what you find in the “Files changed”
tab of GitHub. Also similarly, you can leave comments by highlighting a piece of
the code and pressing ‘c’. All comments you make are in a draft state and thus
only visible to you, like on GitHub. When you are done with your review, you
need to click the “Reply” button at the top of the change page to send your
assessment to the change owner alongside a “change message” summarizing your
findings and/or adding higher level comments. Replying to a change makes your
draft comments and the change message visible on the change page for everyone
that has view access to this change. This again is fairly similar to GitHub,
except for Gerrit’s voting labels.
image::images/user-review-ui-change-reply-dialogue.png[Reply dialogue for a Gerrit change.]
As you can see in the screenshot of the reply dialogue, the voting labels are in
the bottom part of the dialogue. They can be fairly simple as in this case, but
there can also be a larger number of labels you might be able to vote on. Labels
can be used to distinguish different aspects of a review (e.g. whether or not
the licensing of included libraries is okay), outcome of CI systems (e.g.
whether or not a format checker passed, a build completed successfully, etc.) or
as a flag that is read by bots to do something with a change. An example of a
more complex label setup can be seen in this screenshot from the Android Gerrit
instance.
image::images/user-review-ui-change-complex-reply-dialogue.png[Reply dialogue for a change on the Android project.]
In the simplest case shown above, voting -1 on the Code-Review label equals
requesting changes on a GitHub pull request, 0 equals just having comments and
+1 means that you think this change looks good. Usually, Gerrit changes require
a +2 vote on the Code-Review label to be submitted (merged in GitHub terms, see
Section 6 below). Being able to vote +2 on Code-Review is often restricted to
maintainers of a given project, so they can have a final say on a change. These
practices can however vary between projects, as labels and voting permissions
are configurable.
[[iterate]]
== 5. Iterating on the Change
After your reviewers got back to you as a change owner, you realize that you
need to make a few updates to the code in your change. As mentioned in Section 2
(Making a Change), you’ll have to amend the commit that this review was based
on. To do that, you might have to checkout the respective commit first if it is
not at the tip of your local branch, for example if you stacked multiple changes
on top of each other. Another common use case is to not have a local branch but
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
“Download” button on the files tab to copy a command that fetches and checks out
the commit underlying your change. Make sure to select the latest patchset,
though!
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.]
After checking out the commit, you then make the changes as usual. When you
think you are done, you can commit with the `--amend` flag to change the commit
you currently have checked out.
When you `git commit --amend` to iterate on your change, you might be worried that
you are changing your previous commit and may thus lose that state of your work.
However, here the Change-Id appended to your commit message comes into play.
While the SHA1 hash of your change (the commit ID used by Git) might change, the
Change-Id stays the same (in fact it is the SHA1 hash of the very first version
of that commit). When this amended commit is uploaded to the Gerrit server,
Gerrit knows that this commit is really an iteration of that previous commit
(and the associated review) and will preserve both, the old and the new state.
All previous states of your commit will be visible in the Gerrit UI as so-called
patchsets (and link:intro-user.html#change-ref[from the Git repo]).
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.]
After iterating as much as needed, your reviewers will finally be satisfied.
With GitHub, you would have a string of additional commits in the branch you
used for opening the pull request. In Gerrit, you still only have that one
commit in your local branch. All the iterations are available as patchsets in
the Web UI as well as from the special branch mentioned above.
[[submit]]
== 6. Submitting a Change
Finally, it is time to submit your change. As mentioned above, the precondition
for this in Gerrit is usually at least a +2 vote on the Code-Review label. With
GitHub, an authorized person must have given an “Approve” vote. Once this
precondition has been met, anyone with submit permission can submit the change
in Gerrit. To do that, you click the “Submit” button in the Gerrit Web UI just
as you would click the “Merge Pull Request” button in GitHub. Both, Gerrit and
GitHub, allow different merge strategies, that can be enabled by project
administrators. In Gerrit, a merge strategy is configured for each project and
cannot be changed at submit time while this may be possible with GitHub,
depending on project configuration.
A merge can fail due to conflicts with competing edits on the target branch.
With GitHub, you may be able to resolve some simple conflicts directly from the
Web UI. In Gerrit, you can attempt to rebase a change from the Web UI. If there
are no conflicts, a new patchset will automatically appear. Otherwise, similar
to GitHub, you need to resolve conflicts on the command line with your local
clone of the repository. While you resolve conflicts that arise from a
`git merge` for GitHub, you will need to link:intro-user.html#rebase[use `git rebase` with your change] on
Gerrit.
After resolving locally, with GitHub, you end up with another commit on your
pull request branch and push it to the server, which should then allow you to
finish merging the change. With Gerrit, resolving the conflict through rebasing
your commit/change results in another amended version of that same commit and
you upload it to Gerrit, resulting in a new patchset just like your previous
iterations addressing reviewer comments. This new patchset will usually require
another round of reviewer votes, as Gerrit will not copy votes from a previous
patchset by default.
GERRIT
------
Part of link:index.html[Gerrit Code Review]
SEARCHBOX
---------