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

  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:

  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:

  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:

  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> 


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.

All you need is docker (and fig)


Suppose you want to run scala repl or groovy shell or any other repl-like executable. You should download executable, unpack it, set PATH environmnt variable and now you could use it. Can it be simple? Yes, dockerize everything.

Prepare containers

I expect that you have installed docker and fig on your machine.
Checkout this project from github and build containers:

$ cd docker-with-fig
$ fig build 

It could take several minutes, depends on your internet connection.

You could also build only some of available container, for example with scala and groovy:
$ fig build scala groovy

Available containers are:
  • haskell
  • scala
  • groovy
  • python27
  • python34
  • clojure

Run containers

Now you could start for example scala:
$ fig run scala
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions to have them evaluated.
Type :help for more information.


Or groovy:
$ fig run groovy
Mar 29, 2015 7:48:22 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Groovy Shell (2.4.2, JVM: 1.8.0_40)
Type ':help' or ':h' for help.

Or clojure with lein:
$ fig run clojure
nREPL server started on port 52730 on host - nrepl://
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b25
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e


Or python 3.4:
$ fig run python34
Python 3.4.2 (default, Oct  8 2014, 13:08:17) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.

Or ghci haskell:
$fig run haskell
GHCi, version 7.6.3:  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.

You could also run command on docker container with use of files from your current directory because it is mapped to /project directory on docker. Container starts with /project directory as current directory.
For example you have a simple file in your current dir:
$ cat simplePrint.scala 
println("Hello World")

You could run command with this file:

$ fig -f PATH_TO_DOCKER_WITH_FIG_PROJECT/fig.yml run scala scala simplePrint.scala
Hello World

First 'scala' in command means that you want to run scala container and 'scala simplePrint.scala' means that you want to execute this command on container.


It is simple, isn't it? All you need is docker and fig and you could use repl or run command with scala, groovy, cojure and any other which are currently supported...