release: git-gb
Today I’m releasing git-gb, a little tool that I’ve been working on for the last 6 months.
git-gb
is a better way to list git branches in your terminal. Inspired by the GitHub branches view, the output
- is sorted by timestamp of the last commit for each branch
- shows how many commits a branch is ahead and behind of master
- whether a branch is merged or not
Sample output:
~/c/gb:master$ gb
2014-11-22 20:54PM | foobar | behind: 15 | ahead: 2
2014-11-24 21:18PM | readme | behind: 0 | ahead: 1
Installation
Follow along the Installation section of the README for up to date instructions.
The many rewrites of git-gb
I first wrote a prototype of gb in Ruby using the Rugged bindings to libgit2. It worked, but starting a Ruby VM without loading any code was already relatively much slower than running git branch
$ time ruby -e "puts 'hello'"
0.05 real 0.03 user 0.02 sys
$ time git branch
0.00 real 0.00 user 0.00 sys
The prototype was also really slow. This was a non starter for me. While I find the regular output of git branches to be pretty useless when you have over a dozen branches, speed was important.
For my next protype I looked at using Go with the git2go bindings to libgit2. The reasoning was that Go itself would be fast and I didn’t want to dig into C. It There was a problem on my machine with a version mismatch between git2go and libgit2 and I abandoned this idea quickly.
At this point I decided to jump in and just learn the bits of C that I needed again. The first prototype I wrote just worked and I was sold. It was still a little slow, but this time it was because the graph lookup to get the ahead/behind is slow'ish. I added a JSON cache of the comparisons and the times below are the results from a repo with 92 branches.
$ time git branch
0.01 real 0.00 user 0.00 sys
$ time git gb
0.02 real 0.01 user 0.00 sys
$ time git gb -clear-cache
0.31 real 0.28 user 0.03 sys
Though the C version worked, in the back of my mind I always wanted to write this tool in Go as an opportunity to play around with Go a little bit. With a new computer (clean dependencies) and the urge to write something useful in Go, I started rewriting it a few weeks ago.
The rewrite was pretty straightforward and you can follow along in this pull request. In my opinion, the result is less code that is easier to understand.
Because the slow part of this program is the ahead/behind lookup, it’s as fast as the C version.