At Linaro we want to get some metrics for the patches we submit upstream, so we've built a system based on Patchwork that parses email messages to extract patches and categorize them by project/author. This works fine for projects that use mailing lists to keep track of patches (e.g. the kernel, qemu, etc), but it doesn't work for one project to which Linaro has already contributed and expect to contribute a lot more: the Android Open Source Project, which uses Gerrit to track changes.

For that reason we decided to pull that data directly from AOSP's Gerrit instance into our system. Unfortunately, the only public API provided by Gerrit is this one over SSH, which doesn't give a piece of data that is very important to us: the date a change was proposed.

Luckily, James pointed me to this discussion where a neat trick is suggested: watch the requests your browser sends when rendering http://review.source.android.com to figure out how to use Gerrit's internal JSON-RPC API. Yes, it is not a public API (so we should not expect it to be stable), and having to watch your browser requests to learn how to use it is not the kind of documentation I'd like, but that was all we had (ok, I could check Gerrit's source, but since that's Java I'd rather watch the requests sent by the browser) so it had to do.

After experimenting a bit I was able to get a list of changes proposed by a given person as well as all the details of a given change. Here are the methods one can use for that:

Retrieving a list of changes


  endpoint: /gerrit/rpc/ChangeListService
    method: allQueryNext(query, pos, page_size)

  Return up to page_size items that match the given query whose changeSortKey is lower than pos.

  # This will get the list of changes authored by jserv@0xlab.org
  curl -i -X POST -H "Accept: application/json,application/jsonrequest" \
       -H "Content-Type: application/json; charset=UTF-8" \
       --data '{"jsonrpc":"2.0","method":"allQueryNext","params":["owner: jserv@0xlab.org","z",10],"id":1}'\
       https://review.source.android.com/gerrit/rpc/ChangeListService


Getting the details of a change


  endpoint: gerrit/rpc/ChangeDetailService
    method: changeDetail(id)

  Return the details of the change with the given ID.

  # This will get all details of change 16615
  curl -i -X POST -H "Accept: application/json,application/jsonrequest" \
       -H "Content-Type: application/json; charset=UTF-8" \
       --data '{"jsonrpc":"2.0","method":"changeDetail","params":[{"id":16615}],"id":1}'\
       https://review.source.android.com/gerrit/rpc/ChangeDetailService


Pretty simple, right? Just note that you need to specify your charset in the Content-Type header or else you'll get a server error from Gerrit, and the
JSON-RPC requires the 'id' param to correlate a response with its request, but you don't need to worry about that if you're doing things synchronously.

That was all I needed to know in order to write the code that keeps the changes authored by Linaro engineers in sync between our system and AOSP's Gerrit instance, and it should be enough for you to get started if you ever need to get data out of a Gerrit instance (assuming the API hasn't changed in the meantime ;).

Read more