February 19, 2010

Git it on

Filed under: Programming,VCS — Tags: , — Nathan @ 11:29 am

Subversion was my first. I didn’t know what I was doing. I fumbled around mostly. Our relationship was very vanilla. We had our everyday routine and very rarely did we deviate whatsoever. Mostly I would just checkout, only then to commit again later. Then, one day when I was out and about I met someone new. Git. That’s when everything changed. Things started being much faster and wilder. I was doing it in ways I never had before. Forks! Wow! The relationship is hot, and new, so perhaps it’s that the endorphines haven’t worn off yet, but I’m enamored. Yeah, I know that there are others just like Git out there; just as fast and fun, will do the same things if you whisper slightly different phrases. But, for now, Git is all I need.

Enough with the double entendre

OK, the back story. I have used Subversion for my personal projects for years. I even have my dissertation committed to a svn repo (which itself is backed up all over the planet!). Even though I’ve used Subversion for years, I do very little with it. svn up; svn add AFILE; svn commit pretty much summarizes most of my usage. A couple of times I did attempt to do things better by creating a branch to add a new feature, but that branch ended up taking a life of its own, leaving the main trunk an orphan and taking up all of my attention.

My usage of subversion was little more than a backed-up version of the tricks that I used to use before I had any revision control system. Let’s say I was about to do some major change to the file AFILE, then I would create AFILE.bak before editing, so that if I hosed something in a big way, I could at least put it back or diff it against the backup.

Sure, there are ways of doing all of this better with Subversion, but the system doesn’t really afford them. Thus my current infatuation with Git. I’ve only been using it a week, but my development style has already changed.

How do I use git? The main tool in my arsenal is git checkout. Let’s look at this example:

nathan @ macbook ~/repo/Example $ ls
Makefile hello.c  world.c

nathan @ macbook ~/repo/Example $ git branch
* master

As you can see, at the moment there’s only one branch: master. Let’s say that world.c is something that I spent a lot of time on, but I’m about to make a major revision to it. So, I would do this:

nathan @ macbook ~/repo/Example $ git checkout -b adding.new.feature
Switched to a new branch 'adding.new.feature'

nathan @ macbook ~/repo/Example $ ls
Makefile hello.c  world.c

nathan @ macbook ~/repo/Example $ git branch
* adding.new.feature
  master

I’m still in my same directory, but now any changes I make will happen only to this branch. When I’m done working on whatever minor revision I’m working with, making sure of course that I’ve tested everything thoroughly, I will commit the change to this branch, then switch back to “master”:

nathan @ macbook ~/repo/Example $ git add world.c 

nathan @ macbook ~/repo/Example $ git commit -m "Made revision \
to world.c"
[adding.new.feature b00248b] Made revision to world.c
 1 files changed, 1 insertions(+), 0 deletions(-)

nathan @ macbook ~/repo/Example $ git checkout master
Switched to branch 'master'

Since I’m now back at the master branch, even though I’m in the exact same directory, my view will be that of the master. The edits I made to “world.c” will not be visible. If I’m confident with those edits, I can merge them in.

nathan @ macbook ~/repo/Example $ git branch
  adding.new.feature
* master

nathan @ macbook ~/repo/Example $ git merge adding.new.feature
Updating b3d7029..b00248b
Fast-forward
 world.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

The fact that I can have a DAG (directed acyclic graph) of branches makes me happy. One for the love of graph theory, and two because I’m much bolder with my revisions and refactorings. Beyond all of the features that it offers, this confidence alone is worth the switch to Git, or any other DVCS.

The coup de grâce is that I use this on top of an existing Subversion repository. So I can collaborate with others just like I always did, with my post-commit scripts in place. Of course, this is unnecessary since I can just git push remote.repo and send it to any repo I’d like.

It’s only been a week, but I’m in love.


  • I'm a software engineer at Google
  • I'm from Alabama
  • I live in San Francisco
  • I like to work on ridiculous things
  • I'm currently learning German, Scala, and Computer Vision
  • This book referred to JavaScript I wrote when I was 15.