Rewrite introduction to Gerrit

This rewrite has three major changes:

1. The "life of a change" section is now a fictional scenario. This
should help ensure that users don't try to run any of the commands.
2. The What is Gerrit section is shorter and more targeted.
3. Added more links to help users navigate to topics of interest.

Change-Id: I18dd6fcbd2c5c6d0f7555c64a70ce3cdd829e4e3
This commit is contained in:
David Shevitz 2017-06-29 14:01:05 -07:00
parent a1ab168d2c
commit 54196d382b

View File

@ -1,126 +1,99 @@
= Gerrit Code Review - A Quick Introduction
Gerrit is a web-based code review tool built on top of the git version
control system. The purpose of this introduction is to
allow you to answer the question, is Gerrit the right tool for me?
Will it fit in my work flow and in my organization?
Gerrit is a web-based code review tool built on top of the
https://git-scm.com/[git version control system]. This introduction provides
an overview of Gerrit and describes how Gerrit integrates into a typical
development workflow. It also provides a brief tutorial that shows how to manage
a change using Gerrit.
== What is Gerrit?
It is assumed that if you're reading this then you're already convinced
of the benefits of code review in general but want some technical support
to make it easy.
Gerrit makes code review easy by providing a lightweight framework for reviewing
commits before they are accepted by the codebase. Gerrit works equally well for
projects where approving changes is restricted to selected users, as is typical
for Open Source software development, as well as projects where all contributors
are trusted.
Code reviews mean different things to different people. To some it's a
formal meeting with a projector and an entire team going through the code
line by line. To others it's getting someone to glance over the code before
it is committed.
== Gerrit and the developer workflow
Gerrit is intended to provide a lightweight framework for reviewing
every commit before it is accepted into the code base. Changes are
uploaded to Gerrit but don't actually become a part of the project
until they've been reviewed and accepted. In many ways this is simply
tooling to support the standard open source process of submitting
patches which are then reviewed by the project members before being
applied to the code base. However Gerrit goes a step further making it
simple for all committers on a project to ensure that changes are
checked over before they're actually applied. Because of this Gerrit
is equally useful where all users are trusted committers such as may
be the case with closed-source commercial development. Either way it's
still desirable to have code reviewed to improve the quality and
maintainability of the code. After all, if only one person has seen
the code it may be a little difficult to maintain when that person
leaves.
Gerrit is firstly a staging area where changes can be checked over
before becoming a part of the code base. It is also an enabler for
this review process, capturing notes and comments about the changes to
enable discussion of the change. This is particularly useful with
distributed teams where this conversation can't happen face to face.
Even with a co-located team having a review tool as an option is
beneficial because reviews can be done at a time that is convenient
for the reviewer. This allows the developer to create the review and
explain the change while it is fresh in their mind. Without such a
tool they either need to interrupt someone to review the code or
switch context to explain the change when they've already moved on to
the next task.
This also creates a lasting record of the conversation which can be
useful for answering the inevitable "I know we changed this for a
reason" questions.
== Where does Gerrit fit in?
Any team with more than one member has a central source repository of
some kind (or they should). Git can theoretically work without such a
central location but in practice there is usually a central
repository. This serves as the authoritative copy of what is actually in
the project. This is what everyone fetches from and pushes to and is
generally where build servers and other such tools get the source
from.
To understand how Gerrit fits into and enhances the developer workflow, consider
a typical project. This project has a central source repository, which serves as
the authoritative copy of the project's contents.
.Central Source Repository
image::images/intro-quick-central-repo.png[Authoritative Source Repository]
Gerrit is deployed in place of this central repository and adds an
additional concept, a store of pending changes. Everyone still fetches
from the authoritative repository but instead of pushing back to it,
they push to this pending changes location. A change can only be submitted
into the authoritative repository and become an accepted part of the project
once the change has been reviewed and approved.
Gerrit takes the place of this central repository and adds an additional
concept: a _store of pending changes_.
.Gerrit in place of Central Repository
image::images/intro-quick-central-gerrit.png[Gerrit in place of Central Repository]
With Gerrit, when a developer makes a change, it is sent to this store of
pending changes, where other developers can review, discuss and approve the
change. After enough reviewers grant their approval, the change becomes an
official part of the codebase.
In addition to this store of pending changes, Gerrit captures notes
and comments about each change. These features allow developers to review
changes at their convenience, or when conversations about a change can't
happen face to face. They also help to create a record of the conversation
around a given change, which can provide a history of when a change was made and
why.
Like any repository hosting solution, Gerrit has a powerful
link:access-control.html[access control model.]
Users can even be granted access to push directly into the central
repository, bypassing code review entirely. Gerrit can even be used
without code review, used simply to host the repositories and
controlling access. But generally it's just simpler and safer to go
through the review process even for users who are allowed to directly
push.
link:access-control.html[access control model.] This model allows you to
fine-tune access to your repository.
== The Life and Times of a Change
== Working with Gerrit: An example
The easiest way to get a feel for how Gerrit works is to follow a
change through its entire life cycle. For the purpose of this example
we'll assume that the Gerrit Server is running on a server called
+gerrithost+ with the HTTP interface on port +8080+ and the SSH
interface on port +29418+. The project we'll be working on is called
+RecipeBook+ and we'll be developing a change for the +master+ branch.
To understand how Gerrit works, let's follow a change through its entire
life cycle. This example uses a Gerrit server configured as follows:
=== Cloning the Repository
* *Hostname*: gerrithost
* *HTTP interface port*: 8080
* *SSH interface port*: 29418
Obviously the first thing we need to do is get the source that we're
going to be modifying. As with any git project you do this by cloning
the central repository that Gerrit is hosting. e.g.
In this walkthrough, we'll follow two developers, Max and Hannah, as they make
and review a change to a +RecipeBook+ project. We'll follow the change through
these stages:
. Making the change.
. Creating the review.
. Reviewing the change.
. Reworking the change.
. Verifying the change.
. Submitting the change.
NOTE: The project and commands used in this section are for demonstration
purposes only.
=== Making the Change
Our first developer, Max, has decided to make a change to the +RecipeBook+
project he works on. His first step is to get the source code that he wants to
modify. To get this code, he runs the following `git clone` command:
----
$ git clone ssh://gerrithost:29418/RecipeBook.git RecipeBook
Cloning into RecipeBook...
----
Then we need to make our actual change and commit it locally. Gerrit
doesn't really change anything here, this is just the standard editing
and git. While not strictly required, it's best to include a Change-Id
in your commit message so that Gerrit can link together different
versions of the same change being reviewed. Gerrit contains a standard
link:user-changeid.html[Change-Id commit-msg hook]
that will generate a unique Change-Id when you commit. If you don't do
this then Gerrit will generate a Change-Id when you push your change
for review. But because you don't have the Change-Id in your commit
message you'll need to manually copy it in if you need to upload
another version of your change. Because of this it's best to just
install the hook and forget about it.
After he clones the repository, he makes a change to the file and commits it
locally.
NOTE: At this point, the workflow is exactly the same as it would be if Max was
not using Gerrit.
Max is ready to create a commit message for his change. When he does, he
includes a link:user-changeid.html[Change-Id]. This ID allows Gerrit to link
together different versions of the same change being reviewed.
=== Creating the Review
Once you've made your change and committed it locally it's time to
push it to Gerrit so that it can be reviewed. This is done with a git
push to the Gerrit server. Since we cloned our local repository
directly from Gerrit it is the origin so we don't have to redefine the
remote.
Max's next step is to push his change to Gerrit so other contributors can review
it. He does this using the `git push origin HEAD:refs/for/master` command, as
follows:
----
$ <work>
@ -141,118 +114,125 @@ To ssh://gerrithost:29418/RecipeBook.git
* [new branch] HEAD -> refs/for/master
----
The only different thing about this is the +refs/for/master+ branch.
This is a magic branch that creates reviews that target the master
branch. For every branch Gerrit tracks there is a magic
+refs/for/<branch_name>+ that you push to to create reviews.
The `refs/for/master` branch is a symbolic branch that Gerrit uses to create
reviews for the master branch. If Max opted to push to a different branch, he
would have modified his command to
`git push origin HEAD:refs/for/<branch_name>`. Gerrit automatically creates a
`refs/for/<branch_name>` for every branch that it tracks.
In the output of this command you'll notice that there is a link to
the HTTP interface of the Gerrit server we just pushed to. This is the
web interface where we will review this commit. Let's follow that link
and see what we get.
The output of this command also contains a link to a web page Max can use to
review this commit. Clicking on that link takes him to a screen similar to
the following.
.Gerrit Code Review Screen
image::images/intro-quick-new-review.jpg[Gerrit Review Screen]
This is the Gerrit code review screen where someone will come to
review the change. There isn't too much to see here yet, you can look
at the diff of your change, add some comments explaining what you did
and why, you may even add a list of people that should review the change.
This is the Gerrit code review screen, where other contributors can review
his change. Max can also perform tasks such as:
Reviewers can find changes that they want to review in any number of
ways. Gerrit has a capable link:user-search.html[search]
that allows project leaders (or anyone else) to find changes that need
to be reviewed. Users can also setup watches on Gerrit projects with a
search expression, this causes Gerrit to notify them of matching
changes. So adding a reviewer when creating a review is just a
recommendation.
* Looking at the link:user-review-ui.html#diff-preferences[diff] of his change
* Writing link:user-review-ui.html#inline-comments[inline] or
link:user-review-ui.html#reply[summary] comments to explain what he did and
why
* link:intro-user.html#adding-reviewers[Adding a list of people] that should
review the change
At this point the change is available for review and we need to switch
roles to continue following the change. Now let's pretend we're the
reviewer.
In this case, Max opts to manually add the senior developer on his team, Hannah,
to review his change.
=== Reviewing the Change
The reviewer's life starts at the code review screen shown above. He
can get here in a number of ways, but for some reason they've decided
to review this change. Of particular note on this screen are the two
"Need" lines:
Let's now switch to Hannah, the senior developer who will review Max's change.
As mentioned previously, Max chose to manually add Hannah as a reviewer. Gerrit
offers other ways for reviewers to find changes, including:
* Using the link:user-search.html[search] feature that to find changes
* Setting up link:user-notify.html[email notifications] to stay informed of
changes even if you are not added as a reviewer
Because Max added Hannah as a reviewer, she receives an email telling her about
his change. She opens up the Gerrit code review screen and selects Max's change.
.Gerrit Code Review Screen
image::images/intro-quick-new-review.jpg[Gerrit Review Screen]
Notice the two "Need" lines:
----
* Need Verified
* Need Code-Review
----
Gerrit's default work-flow requires two checks before a change is
accepted. Code-Review is someone looking at the code, ensuring it
meets the project guidelines, intent etc. Verifying is checking that
the code actually compiles, unit tests pass etc. Verification is
usually done by an automated build server rather than a person. There
is even a
link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[Gerrit Trigger Jenkins Plugin]
that will automatically build each uploaded change and update the
verified score accordingly.
These two lines indicate what checks must be completed before the change is
accepted. The default Gerrit workflow requires two checks:
It is important to note that Code-Review and Verification are
different permissions in Gerrit, allowing these tasks to be separated.
For example, an automated process would have rights to verify but not
to code-review.
* *Code-Review*. This check requires that someone look at the code and ensures
that it meets project guidelines, styles, and other criteria.
* *Verified*. This check means that the code actually compiles, passes any unit
tests, and performs as expected.
Since we are the code reviewer, we're going to review the code. To do
this we can view it within the Gerrit web interface as either a
unified or side-by-side diff by selecting the appropriate option. In
the example below we've selected the side-by-side view. In either of
these views you can add inline comments by double clicking on the line
(or single click the line number) that you want to comment on. Also you
can add file comment by double clicking anywhere (not just on the
"Patch Set" words) in the table header or single clicking on the icon
in the line-number column header. Once published these comments are
visible to all, allowing discussion of the change to take place.
In general, the *Code-Review* check requires an individual to look at the code,
while the *Verified* check is done by an automated build server, through a
mechanism such as the
link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[Gerrit Trigger
Jenkins Plugin].
IMPORTANT: The Code-Review and Verified checks require different permissions
in Gerrit. This requirement allows teams to separate these tasks. For example,
an automated process can have the rights to verify a change, but not perform a
code review.
With the code review screen open, Hannah can begin to review Max's change. She
can choose one of two ways to review the change: unified or side-by-side.
Both views allow her to perform tasks such as add
link:user-review-ui.html#inline-comments[inline] or
link:user-review-ui.html#reply[summary] comments.
Hannah opts to view the change using Gerrit's side-by-side view:
.Side By Side Patch View
image::images/intro-quick-review-line-comment.jpg[Adding a Comment]
Code reviewers end up spending a lot of time navigating these screens,
looking at and commenting on these changes. To make this as efficient
as possible Gerrit has keyboard shortcuts for most operations (and
even some operations that are only accessible via the hot-keys). At
any time you can hit the +?+ key to see the keyboard shortcuts.
.Gerrit Hot Key Help
image::images/intro-quick-hot-key-help.jpg[Hot Key Help]
Once we've looked over the changes we need to complete reviewing the
submission. To do this we click the _Review_ button on the change
screen where we started. This allows us to enter a Code Review label
and message.
Hannah reviews the change and is ready to provide her feedback. She clicks the
*Review* button on the change screen. This allows her to vote on the change.
.Reviewing the Change
image::images/intro-quick-reviewing-the-change.jpg[Reviewing the Change]
The label that the reviewer selects determines what can happen next.
The +1 and -1 level are just an opinion where as the +2 and -2 levels
are allowing or blocking the change. In order for a change to be
accepted it must have at least one +2 and no -2 votes.
Although these are numeric values, they in no way accumulate;
two +1s do not equate to a +2.
A code review vote is essentially a numerical score between -2 and 2. The
possible options are:
Regardless of what label is selected, once the _Publish Comments_
button has been clicked, the cover message and any comments on the
files become visible to all users.
* `+2 Looks good to me, approved`
* `+1 Looks good to me, but someone else must approve`
* `0 No score`
* `-1 I would prefer that you didn't submit this`
* `-2 Do not submit`
In this case the change was not accepted so the creator needs to
rework it. So let's switch roles back to the creator where we
started.
By default, a change must have at least one `+2` vote and no `-2` votes before
it can be submitted.
IMPORTANT: Although votes use numerical values, they do not accumulate. Two
`+1` votes do not equate to a `+2`.
Hannah notices a possible issue with Max's change, so she selects a `-1` vote.
She uses the *Cover Message* text box to provide Max with some additional
feedback. When she is satisfied with her review, Hannah clicks the
*Published Comments* button. At this point, her vote and cover message become
visible to to all users.
=== Reworking the Change
As long as we set up the
link:user-changeid.html[Change-Id commit-msg hook]
before we uploaded the change, re-working it is easy. All we need
to do to upload a re-worked change is to push another commit that has
the same Change-Id in the message. Since the hook added a Change-Id in
our initial commit we can simply checkout and then amend that commit.
Then push it to Gerrit in the same way as we did to create the review. E.g.
Later in the day, Max decides to check on his change and notices Hannah's
feedback. He opens up the source file and incorporates her feedback. Because
Max set up the link:user-changeid.html[Change-Id commit-msg hook]
before he uploaded the change, all he has to do to upload the re-worked change
is push another commit with the same Change-Id in the message. To accomplish
this, Max needs only perform the following tasks:
* Check out the commit
* Amend the commit
* Push the commit to Gerrit
----
$ <checkout first commit>
@ -273,115 +253,79 @@ To ssh://gerrithost:29418/RecipeBook.git
* [new branch] HEAD -> refs/for/master
----
Note that the output is slightly different this time around. Since
we're adding to an existing review it tells us that the change was
updated.
Notice that the output of this command is slightly different from Max's first
commit. This time, the output verifies that the change was updated.
Having uploaded the reworked commit we can go back into the Gerrit web
interface and look at our change.
Having uploaded the reworked commit, Max can go back to the Gerrit web
interface and look at his change.
.Reviewing the Rework
image::images/intro-quick-review-2-patches.jpg[Reviewing the Rework]
If you look closely you'll notice that there are now two patch sets
associated with this change, the initial submission and the rework.
Rather than repeating ourselves lets assume that this time around the
patch is given a +2 score by the code reviewer.
Notice that there are now two patch sets associated with this change: the
initial submission and the rework.
=== Trying out the Change
When Hannah next looks at Max's change, she sees that he incorporated her
feedback. The change looks good to her, so she changes her vote to a `+2`.
With Gerrit's default work-flow there are two sign-offs, code review
and verify. Verifying means checking that the change actually works.
This would typically be checking that the code compiles, unit tests
pass and similar checks. Really a project can decide how much or
little they want to do here. It's also worth noting that this is only
Gerrit's default work-flow, the verify check can actually be removed
or others added.
=== Verifying the Change
As mentioned in the code review section, verification is typically an
automated process using the
Hannah's `+2` vote means that Max's change satisfies the *Needs Review*
check. It has to pass one more check before it can be accepted: the *Needs
Verified* check.
The Verified check means that the change was confirmed to work. This type of
check typically involves tasks such as checking that the code compiles, unit
tests pass, and other actions. You can configure a Verified check to consist
of as many or as few tasks as needed.
NOTE: Remember that this walkthrough uses Gerrit's default workflow. Projects
can add custom checks or even remove the Verified check entirely.
Verification is typically an automated process using the
link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[Gerrit Trigger Jenkins Plugin]
or similar. But there are times when the code needs to be manually
verified, or the reviewer needs to check that something actually works
or how it works. Sometimes it's just nice to work through the code in a
development environment rather than the web interface. All of these
involve someone needing to get the change into their development
environment. Gerrit makes this process easy by exposing each change as
a git branch. So all the reviewers need to do is fetch and checkout that
branch from Gerrit and they will have the change.
or a similar mechanism. However, there are still times when a change requires
manual verification, or a reviewer needs to check how or if a change works.
To accommodate these and other similar circumstances, Gerrit exposes each change
as a git branch. The Gerrit UI includes a
link:user-review-us.html#download[*download*] link in the Gerrit Code Review
Screen to make it easy for reviewers to fetch a branch for a specific change.
To manually verify a change, a reviewer must have the
link:config-labels.html#label_Verified[Verified] permission. Then, the reviewer
can fetch and checkout that branch from Gerrit. Hannah has this permission, so
she is authorized to manually verify Max's change.
We don't even need to think about it that hard, if you look at the
earlier screenshots of the Gerrit Code Review Screen you'll notice a
_download_ command. All we need to do to get the change is copy
paste this command and run it in our Gerrit checkout.
----
$ git fetch http://gerrithost:8080/p/RecipeBook refs/changes/68/68/2
From http://gerrithost:8080/p/RecipeBook
* branch refs/changes/68/68/2 -> FETCH_HEAD
$ git checkout FETCH_HEAD
Note: checking out 'FETCH_HEAD'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at d5dacdb... Change to a proper, yeast based pizza dough.
----
Easy as that, we now have the change in our working copy to play with.
You might be interested in what the numbers of the refspec mean.
* The first *68* is the id of the change +mod 100+. The only reason
for this initial number is to reduce the number of files in any given
directory within the git repository.
* The second *68* is the full id of the change. You'll notice this in
the URL of the Gerrit review screen.
* The *2* is the patch-set within the change. In this example we
uploaded some fixes so we want the second patch set rather than the
initial one which the reviewer rejected.
=== Manually Verifying the Change
For simplicity we're just going to manually verify the change.
The Verifier may be the same person as the code reviewer or a
different person entirely. It really depends on the size of the
project and what works. If you have Verify permission then when you
click the _Review_ button in the Gerrit web interface you'll be
presented with a verify score.
NOTE: The Verifier can be the same person as the code reviewer or a
different person entirely.
.Verifying the Change
image::images/intro-quick-verifying.jpg[Verifying the Change]
Unlike the code review the verify check doesn't have a +2 or -2 level,
it's either a pass or fail so all we need for the change to be
submitted is a +1 score (and no -1's).
Unlike the code review check, the verify check is pass/fail. Hannah can provide
a score of either `+1` or `-1`. A change must have at least one `+1` and no
`-1`.
Hannah selects a `+1` for her verified check. Max's change is now ready to be
submitted.
=== Submitting the Change
You might have noticed that in the verify screen shot there are two
buttons for submitting the score _Publish Comments_ and _Publish
and Submit_. The publish and submit button is always visible, but will
only work if the change meets the criteria for being submitted (I.e.
has been both verified and code reviewed). So it's a convenience to be
able to post review scores as well as submitting the change by clicking
a single button. If you choose just to publish comments at this point then
the score will be stored but the change won't yet be accepted into the code
base. In this case there will be a _Submit Patch Set X_ button on the
main screen. Just as Code-Review and Verify are different operations
that can be done by different users, Submission is a third operation
that can be limited down to another group of users.
Max is now ready to submit his change. He opens up the change in the Code Review
screen and clicks the *Publish and Submit* button.
Clicking the _Publish and Submit_ or _Submit Patch Set X_ button
will merge the change into the main part of the repository so that it
becomes an accepted part of the project. After this anyone fetching
the git repository will receive this change as a part of the master
branch.
At this point, Max's change is merged into the main part of the repository and
becomes an accepted part of the project.
== Next Steps
This walkthrough provided a quick overview of how a change moves
through the default Gerrit workflow. At this point, you can:
* Read the link:intro-user.html[Users guide] to get a better sense of how to
make changes using Gerrit
* Review the link:intro-project-owner.html[Project Owners guide] to learn more
about configuring projects in Gerrit, including setting user permissions and
configuring verification checks
GERRIT
------