Learn how to use a simple CLI to automate your Gerrit commands with this tutorial from OpenStack Trove PTL Amrith Kumar.

Every OpenStack developer has to interact with the Gerrit code review system. Reviewers and core reviewers have to do this even more and project team leads do this a lot.

The web-based interface is not conducive to many of the more common things that one has to do while managing a project, so early on, I used the Gerrit query CLI.

Along the way, I started writing a simple CLI that I could use to automate more things, and recently, a few people asked about these tools and whether I’d share them.

I’m not claiming that this is unique, or that this hasn’t been done before; it evolved slowly and there may be a better set of tools out there that does all of this (and more). However, I don’t know about them, so, if you have similar tools, please do share (comment below).

I’ve cleaned up this tool a bit (removed things like my private key, username and password) and made them available here.

Full disclosure: they are kind of rough at the edges and you could cause yourself some grief if you aren’t quite sure of what you’re doing.

Here’s a quick introduction:


It should be nothing more than cloning the repository “[email protected]/amrith/gerrit-cli” and running the install command. Note, I use python 2.7 as my default Python on Ubuntu 16.04. If you use python 3.x, your mileage may vary.

Simple Commands

The simplest command is ls to list reviews

gerrit-cli ls owner:self

As you can see, the search here is a standard Gerrit query search.

You don’t have to type complex queries every time; you can store and reuse queries. A very simple configuration file is used for this (a sample configuration file is also provided and gets installed by default).

[email protected]:~$ cat .gerrit-cli/gerrit-cli.json
    # global options
    "host": "review.openstack.org",
    "port": 29418,

    # "dry-run": true,

    # user defined queries
    "queries": {
        # each query is necessarily a list, even if it is a single string
        "trove-filter": ["(project:openstack/trove-specs OR project:openstack/trove OR project:openstack/trove-dashboard OR project:openstack/python-troveclient OR project:openstack/trove-integration)"],

        # the simple filter uses the trove-filter and appends status:open and is therefore a list

        "simple": ["trove-filter", "status:open"],

        "review-list": ["trove-filter", "status:open", "NOT label:Code-Review>=-2,self"],

        "commitids": ["simple"],

        "older-than-two-weeks": ["simple", "age:2w"]

    # user defined results
    "results": {
        # each result is necessarily a list, even if it is a single column
        "default": ["number:r", "project:l", "owner:l", "subject:l:80", "state", "age:r"],
        "simple": ["number:r", "project:l", "owner:l", "subject:l:80", "state", "age:r"],
        "commitids": [ "number:r", "subject:l:60", "owner:l", "commitid:l", "patchset:r" ],
        "review-list": [ "number:r", "project:l", "branch:c", "subject:l:80", "owner:l", "state", "age:r" ]

The file is a simple JSON and you can comment lines just as you would in python (#…).

Don’t do anything, just – – dry-run

The best way to see what’s going on is to use the –dry-run command (or, to be sure, uncomment the line in your configuration file).

[email protected]:~$ gerrit-cli --dry-run ls owner:self
ssh review.openstack.org -p 29418 gerrit query --format=JSON --current-patch-set --patch-sets --all-approvals owner:self
| Number | Project | Owner | Subject | State | Age |

So the owner:self  prompt makes a Gerrit query and formats and displays the output as shown above.

So, what columns are displayed? The configuration contains a section called “results” and a default result is defined there.

"default": ["number:r", "project:l", "owner:l", "subject:l:80", "state", "age:r"],

You can override the default and cause a different set of columns to be shown. If a default is not found, the code has a hard coded default as well.

Similarly, you could run the query

[email protected]:~$ gerrit-cli --dry-run ls
ssh review.openstack.org -p 29418 gerrit query --format=JSON --current-patch-set --patch-sets --all-approvals owner:self status:open
| Number | Project | Owner | Subject | State | Age |

and a default query will be generated for you, that query is owner:self status:open.

You can nest these definitions as shown in the default configuration.

[email protected]:~$ gerrit-cli --dry-run ls commitids
ssh review.openstack.org -p 29418 gerrit query --format=JSON --current-patch-set --patch-sets --all-approvals (project:openstack/trove-specs OR project:openstack/trove OR project:openstack/trove-dashboard OR project:openstack/python-troveclient OR project:openstack/trove-integration) status:open
| Number | Project | Owner | Subject | State | Age |

The query commitids is expanded as follows.

commitids -> simplesimple -> trove-filter, statusopentrove-filter -> (...)

What else can I do?

You can do a lot more than just list reviews:

[email protected]:~$ gerrit-cli --help
usage: gerrit [-h] [--host HOST] [--port PORT] [--dry-run]
              [--config-file CONFIG_FILE] [-v]
              {ls,show,update,abandon,restore,recheck} ...

A simple gerrit command line interface

positional arguments:
    ls                  list reviews
    show                show review(s)
    update              update review(s)
    abandon             abandon review(s)
    restore             restore review(s)
    recheck             abandon review(s)

optional arguments:
  -h, --help            show this help message and exit
  --host HOST           The gerrit host. Default: review.openstack.org
  --port PORT           The gerrit port. Default: 29418
  --dry-run             Whether or not to actually execute commands that
                        modify a review.
  --config-file CONFIG_FILE
                        The path to the gerrit-cli configuration file to use
                        for this session. (Default: ~/.gerrit-cli/gerrit-
  -v, --verbose         Provide additional (verbose) debug output.

Other things that I do quite often (and like to automate) are update, abandon, restore and recheck.

A word of caution: when you aren’t sure what the command will do, use –dry-run. Otherwise, you could end up in a world of hurt.

Like, when you accidentally abandon 100 reviews 🙂

And even if you know what your query should do, remember I’ve hidden some choice bugs in the code. You may hit those, too.


Amrith Kumar, a frequent contributor to Superuser, is CTO and co-founder of Trove, has served as a project team lead (PTL) for Trove almost too many times to count and is co-author of  “Trove.”  This post first appeared on his Hype Cycles blog.

Superuser is always interested in community content, email: editorATsuperuser.org.