This is a Gerrit guide that is dedicated to Gerrit end-users. It explains the standard Gerrit workflows and how a user can adapt Gerrit to personal preferences.
It is expected that readers know about Git and that they are familiar with basic git commands and workflows.
What is Gerrit?
Gerrit speaks the git protocol. This means in order to work with Gerrit you do not need to install any Gerrit client, but having a regular git client, such as the git command line or EGit in Eclipse, is sufficient.
Still there are some client-side tools for Gerrit, which can be used optionally:
Clone Gerrit Project
Cloning a Gerrit project is done the same way as cloning any other git
repository by using the
git clone command.
$ git clone ssh://gerrithost:29418/RecipeBook.git RecipeBook Cloning into RecipeBook...
The URL for cloning the project can be found in the Gerrit web UI
List > <project-name> >
|To use SSH you must generate an SSH key pair and upload the public SSH key to Gerrit.|
Code Review Workflow
With Gerrit Code Review means to review every commit before it is accepted into the code base. The author of a code modification uploads a commit as a change to Gerrit. In Gerrit each change is stored in a staging area where it can be checked and reviewed. Only when it is approved and submitted it gets applied to the code base. If there is feedback on a change, the author can improve the code modification by amending the commit and uploading the new commit as a new patch set. This way a change is improved iteratively and it is applied to the code base only when is ready.
Upload a Change
Uploading a change to Gerrit is done by pushing a commit to Gerrit. The
commit must be pushed to a ref in the
refs/for/ namespace which
defines the target branch:
refs/for/ prefix allows Gerrit to differentiate commits
that are pushed for review from commits that are pushed directly into
the repository, bypassing code review. For the target branch it is
sufficient to specify the short name, e.g.
master, but you can also
specify the fully qualified branch name, e.g.
$ git commit $ git push origin HEAD:refs/for/master // this is the same as: $ git commit $ git push origin HEAD:refs/for/refs/heads/master
$ git commit $ git push origin HEAD:master // this is the same as: $ git commit $ git push origin HEAD:refs/heads/master
|If pushing to Gerrit fails consult the Gerrit documentation that explains the error messages.|
When a commit is pushed for review, Gerrit stores it in a staging area
which is a branch in the special
refs/changes/ namespace. A change
ref has the format
YYYY is the
numeric change number,
ZZ is the patch set number and
XX is the
last two digits of the numeric change number, e.g.
refs/changes/20/884120/1. Understanding the format of this ref is not
required for working with Gerrit.
Using the change ref git clients can fetch the corresponding commit, e.g. for local verification.
$ git fetch https://gerrithost/myProject refs/changes/74/67374/2 && git checkout FETCH_HEAD
|The fetch command can be copied from the download commands in the change screen.|
refs/for/ prefix is used to map the Gerrit concept of
"Pushing for Review" to the git protocol. For the git client it looks
like every push goes to the same branch, e.g.
refs/for/master but in
fact for each commit that is pushed to this ref Gerrit creates a new
branch under the
refs/changes/ namespace. In addition Gerrit creates
an open change.
A change consists of a Change-Id, meta data (owner, project, target branch etc.), one or more patch sets, comments and votes. A patch set is a git commit. Each patch set in a change represents a new version of the change and replaces the previous patch set. Only the latest patch set is relevant. This means all failed iterations of a change will never be applied to the target branch, but only the last patch set that is approved is integrated.
The Change-Id is important for Gerrit to know whether a commit that is pushed for code review should create a new change or whether it should create a new patch set for an existing change.
The Change-Id is a SHA-1 that is prefixed with an uppercase
I. It is
specified as footer in the commit message (last paragraph):
Improve foo widget by attaching a bar. We want a bar, because it improves the foo by providing more wizbangery to the dowhatimeanery. Bug: #42 Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b Signed-off-by: A. U. Thor <firstname.lastname@example.org>
If a commit that has a Change-Id in its commit message is pushed for review, Gerrit checks if a change with this Change-Id already exists for this project and target branch, and if yes, Gerrit creates a new patch set for this change. If not, a new change with the given Change-Id is created.
If a commit without Change-Id is pushed for review, Gerrit creates a
new change and generates a Change-Id for it. Since in this case the
Change-Id is not included in the commit message, it must be manually
inserted when a new patch set should be uploaded. Most projects already
require a Change-Id
when pushing the very first patch set. This reduces the risk of
accidentally creating a new change instead of uploading a new patch
set. Any push without Change-Id then fails with
missing Change-Id in commit message
footer. New patch sets can always be uploaded to a specific change
(even without any Change-Id) by pushing to the change ref, e.g.
Amending and rebasing a commit preserves the Change-Id so that the new commit automatically becomes a new patch set of the existing change, when it is pushed for review.
$ git commit --amend $ git push origin HEAD:refs/for/master
Change-Ids are unique for a branch of a project. E.g. commits that fix the same issue in different branches should have the same Change-Id, which happens automatically if a commit is cherry-picked to another branch. This way you can search by the Change-Id in the Gerrit web UI to find a fix in all branches.
Change-Ids can be created automatically by installing the
hook as described in the Change-Id
Instead of manually installing the
commit-msg hook for each git
repository, you can copy it into the
directory. Then it is automatically copied to every newly cloned
After uploading a change for review reviewers can inspect it via the Gerrit web UI. Reviewers can see the code delta and comment directly in the code on code blocks or lines. They can also post summary comments and vote on review labels. The documentation of the review UI explains the screens and controls for doing code reviews.
There are several options to control how patch diffs should be rendered. Users can configure their preferences in the diff preferences.
Upload a new Patch Set
If there is feedback from code review and a change should be improved a new patch set with the reworked code should be uploaded.
This is done by amending the commit of the last patch set. If needed this commit can be fetched from Gerrit by using the fetch command from the download commands in the change screen.
It is important that the commit message contains the Change-Id of the change that should be updated as a footer (last paragraph). Normally the commit message already contains the correct Change-Id and the Change-Id is preserved when the commit is amended.
// fetch and checkout the change // (checkout command copied from change screen) $ git fetch https://gerrithost/myProject refs/changes/74/67374/2 && git checkout FETCH_HEAD // rework the change $ git add <path-of-reworked-file> ... // amend commit $ git commit --amend // push patch set $ git push origin HEAD:refs/for/master
|Never amend a commit that is already part of a central branch.|
Pushing a new patch set triggers email notification to the reviewers.
Developing multiple Features in parallel
Code review takes time, which can be used by the change author to implement other features. Each feature should be implemented in its own local feature branch that is based on the current HEAD of the target branch. This way there is no dependency to open changes and new features can be reviewed and applied independently. If wanted, it is also possible to base a new feature on an open change. This will create a dependency between the changes in Gerrit and each change can only be applied if all its predecessor are applied as well. Dependencies between changes can be seen from the Related Changes tab on the change screen.
To get to know about new changes you can watch the projects that you are interested in. For watched projects Gerrit sends you email notifications when a change is uploaded or modified. You can decide on which events you want to be notified and you can filter the notifications by using change search expressions. For example 'branch:master file:^.*\.txt$' would send you email notifications only for changes in the master branch that touch a 'txt' file.
It is common that the members of a project team watch their own projects and then pick the changes that are interesting to them for review.
Project owners may also configure notifications on project-level.
In the change screen reviewers can be added explicitly to a change. The added reviewer will then be notified by email about the review request.
Mainly this functionality is used to request the review of specific person who is known to be an expert in the modified code or who is a stakeholder of the implemented feature. Normally it is not needed to explicitly add reviewers on every change, but you rather rely on the project team to watch their project and to process the incoming changes by importance, interest, time etc.
There are also plugins which can add reviewers automatically (e.g. by configuration or based on git blame annotations). If this functionality is required it should be discussed with the project owners and the Gerrit administrators.
Gerrit supports a wide range of query operators to search for changes by different criteria, e.g. by status, change owner, votes etc.
The page that shows the results of a change query has the change query contained in its URL. This means you can bookmark this URL in your browser to save the change query. This way it can be easily re-executed later.
Several change queries can be also combined into a dashboard. A dashboard is a screen in Gerrit that presents the results of several change queries in different sections, each section having a descriptive title.
A default dashboard is available under
Changes. It has
sections to list outgoing reviews, incoming reviews and recently closed
Users can also define custom dashboards. Dashboards can be bookmarked in a browser so that they can be re-executed later.
It is also possible to customize the My menu and add menu entries for custom queries or dashboards to it.
Dashboards are very useful to define own views on changes, e.g. you can have different dashboards for own contributions, for doing reviews or for different sets of projects.
You can use the limit and
age query operators to limit the result set
in a dashboard section. Clicking on the section title executes the
change query without the
Project owners can also define shared
project-level. The project dashboards can be seen in the web UI under
List > <project-name> >
Submit a Change
Submitting a change means that the code modifications of the current patch set are applied to the target branch. Submit requires the Submit access right and is done on the change screen by clicking on the Submit button.
In order to be submittable changes must first be approved by voting on the review labels. By default a change can only be submitted if it has a vote with the highest value on each review label and no vote with the lowest value (veto vote). Projects can configure custom labels and custom submit rules to control when a change becomes submittable.
Submitting a change may fail with conflicts. In this case you need to rebase the change locally, resolve the conflicts and upload the commit with the conflict resolution as new patch set.
If a change cannot be merged due to path conflicts this is highlighted
on the change screen by a bold red
Cannot Merge label.
Rebase a Change
While a change is in review the HEAD of the target branch can evolve. In this case the change can be rebased onto the new HEAD of the target branch. When there are no conflicts the rebase can be done directly from the change screen, otherwise it must be done locally.
// update the remote tracking branches $ git fetch // fetch and checkout the change // (checkout command copied from change screen) $ git fetch https://gerrithost/myProject refs/changes/74/67374/2 && git checkout FETCH_HEAD // do the rebase $ git rebase origin/master // resolve conflicts if needed and stage the conflict resolution ... $ git add <path-of-file-with-conflicts-resolved> // continue the rebase $ git rebase --continue // push the commit with the conflict resolution as new patch set $ git push origin HEAD:refs/for/master
Doing a manual rebase is only necessary when there are conflicts that cannot be resolved by Gerrit. If manual conflict resolution is needed also depends on the submit type that is configured for the project.
Generally changes shouldn’t be rebased without reason as it increases the number of patch sets and creates noise with notifications. However if a change is in review for a long time it may make sense to rebase it from time to time, so that reviewers can see the delta against the current HEAD of the target branch. It also shows that there is still an interest in this change.
|Never rebase commits that are already part of a central branch.|
Abandon/Restore a Change
Changes can be grouped by topics. This is useful because it allows you to easily find related changes by using the topic search operator. Also on the change screen changes with the same topic are displayed so that you can easily navigate between them.
Often changes that together implement a feature or a user story are group by a topic.
Assigning a topic to a change can be done in the change screen.
It is also possible to set a topic on push.
$ git push origin HEAD:refs/for/master%topic=multi-master
Working with Drafts
Changes can be uploaded as drafts. By default draft changes are only visible to the change owner. This gives you the possibility to have some staging before making your changes visible to the reviewers. Draft changes can also be used to backup unfinished changes.
A draft change is created by pushing to the magic
$ git commit $ git push origin HEAD:refs/drafts/master
By adding reviewers to a draft change the change is made visible to these users. This way you can collaborate with other users in privacy.
By pushing to
refs/drafts/<target-branch> you can also upload draft
patch sets to non-draft changes. Draft patch sets are immediately
visible to all reviewers of the change, but other users cannot see the
draft patch set. A draft patch set can be published and deleted in the
same way as a draft change.
Working without Code Review
Doing code reviews with Gerrit is optional and you can use Gerrit without code review as a pure Git server.
$ git commit $ git push origin HEAD:master // this is the same as: $ git commit $ git push origin HEAD:refs/heads/master
Bypassing code review must be enabled in the project access rights. The
project owner must allow it by assigning the
Push access right on the
target branch (
|If you bypass code review you always need to merge/rebase manually if the tip of the destination branch has moved. Please keep this in mind if you choose to not work with code review because you think it’s easier to avoid the additional complexity of the review workflow; it might actually not be easier.|
|The project owner may enable auto-merge on push to benefit from the automatic merge/rebase on server side while pushing directly into the repository.|
User configuration data such as preferences is
stored in the
All-Users project under a per-user ref. The user’s
ref is based on the user’s account id which is an integer. The user
refs are sharded by the last two digits (
nn) in the refname,
leading to refs of the format
There are several options to control the rendering in the Gerrit web UI.
Users can configure their preferences under
The user’s preferences are stored in a
git config style file named
preferences.config under the user’s ref in the
The following preferences can be configured:
This setting controls how the values of the review labels in change lists and dashboards are visualized.
For each review label only the voting value is shown. Approvals are rendered as a green check mark icon, vetoes as a red X icon.
For each review label the voting value is shown together with the full name of the voting user.
For each review label the voting value is shown together with the email address of the voting user.
For each review label the voting value is shown together with the username of the voting user.
Show Abbreviated Name:
For each review label the voting value is shown together with the initials of the full name of the voting user.
The maximum number of entries that are shown on one page, e.g. used when paging through changes, projects, branches or groups.
The format that should be used to render dates and timestamps.
This setting controls the email notifications.
Whether the Side-by-Side diff view or the Unified diff view should be shown when clicking on a file path in the change screen.
Whether the site header and footer should be shown.
Whether timestamps in change lists and dashboards should be shown as relative timestamps, e.g. '12 days ago' instead of absolute timestamps such as 'Apr 15'.
Whether change sizes should be visualized as colored bars. If disabled the numbers of added and deleted lines are shown as text, e.g. '+297, -63'.
Whether in change lists and dashboards an
IDcolumn with the numeric change IDs should be shown.
Whether common path prefixes in the file list on the change screen should be grayed out.
Signed-off-byfooter should be automatically inserted into changes that are created from the web UI (e.g. by the
Edit Configbuttons on the project screen, and the
Follow-Upbutton on the change screen).
Part of Gerrit Code Review