We're now more than two years into building, maintaining and growing the code base for Travis CI. A lot has happened in the code base, especially in the first year of our existing as a company. Lots of code was moved around, refactored, changed, improved, or written from scratch.

While Travis CI is overall simple, some part of the code relies on complex logic, in particular handling everything in and around the state of a build.

The more the code's been touched, with new states being added, the harder it's been to follow along why it was changed.

Most classes have some coverage with comments, but code comments have one distinct flaw. While code changes frequently, its comments rarely do.

My first reflex when looking at a piece of code, wondering why it is the way it is, is to look at the git history. While git blame has an unfortunately negative connotation, it does provide the basic clues as to where to look for the answers.

Thankfully, in Vim, :Gblame (courtesy of fugitive) provides a good way to start digging.

This is where I changed the way I write and commit code in the past couple of month. I think about future me, future anyone who looks at my code, thinking what the hell is going on here and why?

When they look at a commit message no longer than some 50 characters and a code patch, will they be able to figure out what's going on, why I made this change?

Knowing present and past me, I know they don't. Things are easily forgotten, and a year later no one will remember why something was changed.

For these future mes and someone else, commit messages are the one true history of why a piece of code has changed and how, by way of the diff.

Nowadays, I add detailed commit messages to even the smallest changes. As soon as they touch something that affects the bigger picture or has some reasoning outside of what's visible in the code, the commit message should reflect that.

It turns into a diary of what you've been up to, and it's going to help yourself and everyone else looking at your code.

Write good, clear and detailed commit messages. Future you will thank present you for it.

Mislav has a lot more detail on the commit history as the ultimate truth for a code base's timeline, it's good stuff.

Tags: git, development

There's a small pitfall when using git-svn. I just recently had the problem that someone renamed a file from lowercase to uppercase in our Subversion repository. Why should that bother me, when I'm using Git, you ask? Well, I'm using git-svn, and it didn't really like that kind of change. The default on Mac OS X file systems is that they are case-insensitive. FFFFFF.gif is the same as ffffff.gif.

Speaking of which, that was exactly the file that has been renamed. Doing a git svn rebase failed miserably with the error that ffffff.gif would be overwritten by the merge of the commit in question. Gah!

It took me a while to find a way around it. If you delete the file in question, just from the file system, not from the Git index, mind you, you can merge the branch in question, and have it restore the file as if nothing happened.

The steps are pretty simple:

$ rm file/in/question.gif
$ git merge trunk

The file should be restored in all its renamed glory. It works because all the stuff from the Subversion repository sleeps quietly in a branch called trunk, together with all the metadata git-svn requires.

You won't have that problem when using plain Git, though to rename the file you have to use git mv -f, but git-svn apparently can't handle that situation.

Tags: git

Great community resource for Git started by Scott Chacon. Looks pretty good so far. Even downloadable as PDF.

By the way, GitHub just rolled out some sweet graph awesomeness features.

Also of interest might be this small Git cheatsheet by 37signals.

Via Join The Conversation

Tags: git

Chris (of GitHub and err.the_blog fame) gave an inspiring keynote at this year's Ruby Hoedown. Check out the essay, or enjoy him in full visual glory.

Inspiring quote to scratch your itch:

"In fact, stop worrying so much about other people. Every time I've worked on a project I thought other people would really love, it was a massive flop. Every time I've worked on a project I loved, it worked. If you're sitting in this room, your taste is not as far off from those around you as you'd think. Build something you love and others will love it, too. (Not everyone, of course.)"

Seriously, go check it out.

There are more videos from the Hoedown available, of course.

Tags: git, miscellany, ruby

It's been quite around here. That's mainly due to the fact that I had visitors from Canada over, and led them and two more visitors from Norway around beautiful Berlin and Potsdam. Being a tour guide sure is a full-time job.

I held a (not so small) talk on Git yesterday at the Ruby User Group Berlin meeting. The slides are up on slideshare.

I'm using git and git-svn on a daily basis these days, and like most of the people, I'm enjoying it. I'm using GitHub to host my first open source toy called Macistrano, a Mac OS X desktop frontend for Webistrano, written in RubyCocoa. Yes, it's a frontend for a frontend. Gotta be meta these days.

It's not yet feature complete in the sense of a 0.1 version, so if you check it out, there will be bugs. An official announcement will follow.

To get more out of git, don't forget to check out Scott Chacon's talk at the RailsConf 08, and his excellent PeepCode book "Git Internals". If you just started using git casually, this book will take you deeper into the internal workings of git and the repository. Well worth the $9. For me, it was of great help to understand and appreciate how git works internally.

Tags: git

While working with git-svn over the last week I ran into some minor things that weren't really problems, but still kept my mulling them over every time they happened.

After finishing work on a remote branch I did the usual chain of commands:

$ git checkout master
$ git svn rebase
$ git merge my_branch
$ git svn dcommit

Now, while this works beautifully I had two different experiences how git svn dcommit would put the changes from the branch into the Subversion repository. On one occasion it would just beautifully commit every single commit I did on my local branch. On the other it committed all the changes at once, in one single Subversion commit, using the message "Merged from 'my_branch'".

While it's all no big deal I couldn't put my finger on why it works that way. Either the man page isn't fully clear on the matter, or I just didn't fully understand it. I dug a little deeper through the internets and found out that it will only commit your merged changes as a whole when you did git svn rebase and there were actually changes pouring in from the Subversion repository.

If noone else submitted while you were working everything's fine. Knowing that difference can work out as an advantage, especially if not all of your local commits were clean.

Other than that you can just do the whole procedure from your branch.

$ git checkout my_branch
$ git svn rebase
$ git svn dcommit
$ git checkout master
$ git svn rebase
$ git branch -d my_branch

By the way, you can change the message "Merged from 'my_branch'" by calling git like so:

$ git svn dcommit -e

As if there weren't enough reasons to love it, I came across a nice little article by Ryan Tomayko called "The Thing About Git". He describes how to do partial commits of only some selected changes in specific files instead of having to commit the whole file. git add --patch to the rescue. Neat stuff. I still like git stash, but being able to commit specific changes while leaving others untouched in the local repository can come in handy from time to time.

I'm currently using Git as a gateway drug on a Subversion repository, and I'm getting more and more fond of it every day.

Via GitHub.

Tags: git