github twitter linkedin email
Using git-review

git-review is a Python wrapper for many of the common Git commands used in conjunction with Gerrit. It encapsulates many of the most common commands used, in order to speed things up.

It’s possible to use Gerrit without using the git-review tool. All the commands we use below have their plain git equivalents. However, the question remains: why would you want to? The git-review tool speeds things up, and is used by a number of teams outside Intel (including MediaWiki and OpenStack).

This guide is borrows heavily from the original Openstack guide, found here:

https://wiki.openstack.org/wiki/Gerrit_Workflow

A word on workflows

Gerrit, like Git, is extremely flexible. There is no one true way to work with it. However, Git has two predominant “workflows”: the merge workflow, and the rebase workflow. Each of these have their pros and cons, but both work equally well with standard Git. This is not the case with Gerrit. While the former workflow is possible, it’s very awkward (Gerrit doesn’t handle merge commits very well). Hence, despite the issues that can occur from “rewriting history” in the rebase workflow, it’s the best option.

Initial steps

First, install the tool. On Fedora 16 and up:

$ dnf install git-review

Navigate to the project you wish to use, and ensure you can connect to the Gerrit server:

$ cd <repo>
$ git review -s

You may get a warning like so:

No '.gitreview' file found in this repository.
We don't know where your gerrit is. Please manually create
a remote named gerrit and try again.

If so, you likely have your Gerrit review server’s “remote” called origin or something similar. You can check this like so:

$ git remote -v

You’ll likely get something like so, where the url points to a Gerrit project:

origin  <url> (fetch)
origin  <url> (push)

Assuming this is the case, just rename the remote:

$ git remote rename origin gerrit

If this isn’t (i.e. you have more than one remote), you may want to rename the relevant remote or add a new one for Gerrit:

$ git remote add gerrit [url]

Making and uploading changesets

Checkout a feature branch using your teams naming conventions:

$ git checkout -b <topic_branch>

NOTE: You should always work on feature branches when working with Gerrit. If you work on master or development, you’re going to get merge conflicts when you pull in the latest changes from Gerrit/upstream.

Now make some changes: add some new files, delete old ones, do what you have to do. Following this, save the changes:

$ git commit -as  # this is the same as `git add -u` and `git commit -as`

This should create a new commit. You can upload this changeset like so:

$ git remote update  # to get latest changes
$ git review <upstream_branch>

NOTE: This will automatically rebase the change against the upstream master.

If you now go to Gerrit, you’ll see a new changeset there. Its “Branch” will correspond with the value of <upstream_branch>, while the “Topic” will correspond with the value of <topic_branch> (i.e. your local branch).

NOTE: In Gerrit, the “Branch” means the Git branch that the commit is meant for. However, the “Topic” has no bearing on the actual underlying repo. Instead it is merely used to gather similar changes together.

Reworking a changeset

No one’s perfect, and neither is your code. When you need to rework some, you do so using the rebase and commit --amend tools. For example:

[make changes...]
$ git commit -a --amend
$ git review <upstream_branch>

Alternatively

$ git rebase -i <ancestor>
[make changes...]
$ git review <upstream_branch>

NOTE: If you delete a commit using rebase, you will need to manually abandon it. Unfortunately there doesn’t seem to be any way to avoid this.

Collaboration

If you want to review/rework someone else’s changes, it’s very easy to do. This is great for collaboration/pair-programming.

To check out someone else’s code, you’ll want the “change id”. When you have this, just use the following change:

$ git review -d <change_id>

This will checkout the change, and all changes that it depends on (i.e. the branch).