February 25, 2010

The problem is timid edits.

Filed under: Programming,VCS — Tags: , , — Nathan @ 11:46 pm

I recently posted about Git and how it has changed my development style in only a week of using it. After discussing this with a couple of people, I believe I have a better way of articulating the underlying problem.

Fundamentally, it comes down to what I have been calling “timid edits”.

We’ve all been there. There’s some nasty piece of code that you just can’t get to work right. There’s some edge-case that you realize you forgot to deal with and you’re trying to wedge in the fix. You change this, you change that. You exert tremendous effort trying to bend your existing code to the right shape, but to no avail. In the end, after god knows how long, you just say screw it and rewrite the whole function.

Why did it take so long to reach that point? Why didn’t you just rewrite the offending code-block when you realized there was some flaw? I think sometimes we mislead ourselves into thinking that code that ‘almost-works’ is somehow actually ‘close’ to the actual solution when we are in fact at a dead end. Similarly, I think that we feel like deleting code will take us further away from our goal and perhaps we feel as if we can’t get back.

These timid edits don’t only affect debugging, but also get in the way of refactoring. “Our API works, why rewrite it?” “My class hierarchy works, why change it?” Because of our timidity when it comes to rewriting code we fail to reap the possible benefits like efficiency, clarity, or maintainability.

In order to deal with this issue—timid edits—we have to have confidence in our understanding of the problem itself, and have confidence in our ability to recreate its solution.

We have tools that can help us find our way back, when we go wandering away from the solution. These tools can embolden us. I have recently begun using Git for exactly this purpose. I keep very frequent way-points and also create lots of small, short-lived branches.

At the end of the day we need to stop floundering around, worrying with our code as it is. We need to have a good understanding of the tools at hand so that they can instill in us the confidence to stop timid edits.

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.