Monday, December 31, 2007

Try Git

I'm not cutting edge. I was a long time ago but today, I prefer mature stuff. That's why I cultivate the luxury to ignore brand new, cool software until it's not only cool but most of the wrinkles have been ironed out by those guys who like to bleed (it's not called "cutting edge" for nothing).

So when Subversion came out, I stayed with CVS until version 1.2. I installed it and liked it immediately. Now, some years later, even the Eclipse plugins (Subclipse and Subversive) work so well that using them becomes uninterruptive.

The same is true for GIT. When Linus (of Linux fame) announced it, I knew that this guy was probably smart enough to know when to start a new version control system and when to stay with the flock. Alas, I never had the pressure to try it.

Actually, I had the pressure but I didn't notice because I didn't know enough about GIT, specifically what it does different than, say, Subversion (a.k.a "the worlds largest patch for CVS"). In nutshell, GIT is a set of commands to manage one or more repositories with the same or different versioned objects.

Confused? An example: You work at a paranoid company that won't allow you to connect to some OSS CVS/SVN server to update the files of a project which you're using in your daily work. Sad but quite common. Let's ignore for a minute the relative dangers of using CVS (which you aren't allowed to use) and using HTTP (which you can use). What options do you have?

You can download the files at home, put them on a USB drive and take them to work. That works pretty well. Now, one day, you make a change to the sources at home and at work. Only, you forget to commit one of them. So you keep updating the sources and eventually, you will run into problems merging the files because of that one uncommitted change.

This happens because neither CVS nor SVN allow you to "clone" the source repository. GIT works differently: When you start, you either create an empty repository or you copy an existing one. When you do that, you get everything. If that other repository gets corrupted, it could be restored completely from your copy. (Remember? "Backups are for wimps; real man put their software on public FTP servers and let the world mirror them!")

Also, GIT will track the work in each clone repository in an individual branch (unlike SVN where everyone usually works on the same branch). When you checkout the latest version in your working directory, you don't work on the same branch as any other developer. If you commit something, that's in your local branch only. If you break something, no one but you will notice.

Only when you're satisfied with your work, you "push" your changes over to other people. You needn't even push it to everyone at once. You can send your changes to a few colleagues first, before pushing them to the main project repository for everyone to see. Or you can keep it. GIT will happily download all the branches from the main repository without disturbing yours unless you say "Hey, I want to merge to main development into my code."

At that time, you will notice something: GIT will ask you to commit all your work first if you have uncommitted files in your working directory. In SVN this isn't possible or at least not that simple; you'd have to setup a SVN branch for each merge you do. For GIT, it's simple because from its point of view, the changes are not related in the first place. True, the do have a common ancestor somewhere but after that, they are as independent as they can be.

So you have the great luxury to be able to commit all changes you made, saving all your work before you do the actual merge. You can even save stuff away that you don't want to merge, so every modified file after that is actually part of the merge. This also means if something goes wrong, you can simply roll back all changes by checking out the head of your local development branch. Even better, you can create better diffs. It's simple to create a diff for a) everything you changed (diff common-ancestor local-branch-head), b) everything everyone else changed (common-ancestor global-branch-head) and c) everything you changed to do the merge (diff local-branch-head working-copy). In SVN, you usually see a mix of a) and c), at least.

So, if you usually work from several places and can't keep a network connection to the central server all the time, give GIT a try when you start your next project. It's worth it.

No comments: