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).