2015-06-04

Git aliases for better Gerrit usage

What is Gerrit?

Gerrit is a web application for code review and git project management. You push commit to specific ref in Gerrit and your collaborators could comment your code, give you a score (-2, -1, 0, 1, 2) or merge it with specific branch. Gerrit generates also events, so yout CI server (for example Jenkins) could start build based on this commit and give the positive score if build is green or negative if it fails.

Pushing commits to gerrit

If you want to push commit to gerrit, then commit has to have generated Change-Id, which is uniq review identifier. You do not need to generate Change-Id on your own, because you could install pre-commit hook from Gerrit:

gitdir=$(git rev-parse --git-dir); scp -p -P <GERRIT_PORT> <GERRIT_SSH>:hooks/commit-msg ${gitdir}/hooks/

Of course, you have to set GERRIT_PORT and GERRIT_SSH to point to yout Gerrit.

To push a commit for review you should use command:

git push origin HEAD:refs/for/<BRANCH_NAME>

It means that your current HEAD should be pushed to remote reference on origin (if Gerrit remote repository is named as origin). BRANCH_NAME is the remote branch with which your code will be compared and to which your commit should be merged (if it pass review).

You often push to master so there is alias to push as review for master in alias section in ~/.gitconfig (globally) or .git/config (only in current repository):

[alias]
  ...
  push-for-review = push origin HEAD:refs/for/master
  ...

To execute it just type:

git push-for-review

If I want to push as review to another branch then I use another alias:

[alias]
  ...
  push-for-review-branch = !git push origin HEAD:refs/for/$1
  ...

and branch name could be pass as argument from command line:

git push-for-review-branch <BRANCH_NAME>

Pushing drafts

If you think that your commit is not ready to merge with remote branch, but you want to share it or just have it in remote repository, you could push it to draft reference. Draft on gerrit is available only for you and other users which are invited by you. Draft could be pushed via command:

git push origin HEAD:refs/drafts/<BRANCH_NAME>

Branch name must be given, because draft could be published and then merged, so branch have to be known before.

There also are simple aliases, which could be used in the same way as during push for review:

[alias]
  ...
  push-as-draft = push origin HEAD:refs/drafts/master
  push-as-draft-branch = !git push origin HEAD:refs/drafts/$1
  ...

Invite for review

After pushing for review or draft you could invite user or group, then they will be notified by Gerrit about new change. To invite from command line there should be added four aliases:

[alias]
  ...
  gerrit-remote = "!sh -c \"git remote -v | grep push | grep ssh | grep gerrit | head -1 | awk '{print $2}' | cut -d'/' -f3\""
  gerrit-host = "!sh -c \"git gerrit-remote | cut -d':' -f1\""
  gerrit-port = "!sh -c \"git gerrit-remote | cut -d':' -f2\""
  gerrit-invite = "!sh -c \"ssh -p `git gerrit-port` `git gerrit-host` 'gerrit set-reviewers --add' $1 `git log | grep Change-Id | head -1 | tr -d ' ' | cut -d':' -f2`\""
  ...

First alias selects remote repository which contains gerrit in name or url, could be used to push via ssh and extracts url to this repository.

Second and third alias uses the first to extract host and port from repository url. It is necessary for executing remote command via ssh.

The last alias extract Change-Id from HEAD and add user or group given form command line. Example usage:

git gerrit-invite <USER_OR_GROUP> 

Summary

Gerrit is a great tool for git management and code reviewing, but it is difficult to type all references by memory. Git aliases described here are great support and simplify Gerrit usage.