git really is better than svn

Posted by Jason King about 1 month ago

For many months when git (or really when github) first arrived on the scene I heard nothing else from all the fanboys than how great git was, how crap svn was, and that everyone who was anyone was using git now. That sort of zealous response to new software or services always gives me pause.

Inevitably, I’d ask one of the fanboys why they recommended git over svn, and usually they would come up with one of two standard “reasons”

  1. Git handled branching much better than svn
  2. Git was distributed and therefore cool

I had rejected the first immediately - if you’re familiar with svn, have a shell script or two to wrap up the repetitive task of retrieving the full URL from svn status, know about svn switch !!:$ and especially if you had svn 1.6 with branch tracking, then really svn is very good at branching too.

I had rejected the second for any situation where this wasn’t important - like 99% of corporate situations where you have your own svn server sitting on a 100mb/s LAN.

Unfortunately, no one ever mentioned the real advantages of git over svn.

Time to try git

I began a new role in San Diego, and we have some developers in Tijuana who have a very sketchy internet connection that can be down for many hours at a time. Sounded to me like one of the 1% of times when having a distributed SCM might prove useful. So in I dove.

The real advantages of git over svn

The fanboys would have had me totally sold had they mentioned these things.

1. You can split during commit

This sequence of events happens so often that it’s really nice to have it supported as a first class citizen in your SCM. You begin working on an issue, let’s call it “password recovery” and as you’re working you notice some hard coded URLs in some template files and you fix those, and you notice some poorly named variables and you fix those, and you notice some debug code and you remove that, and you finish your work only to realize that you now have a working directory that contains more than one logical unit of work.

git add --patch .

Tadaa - you can now use an interactive mechanism to stage your commit, picking the files or even changed lines within files that are specific to each logical unit of work. Then commit that, with an appropriate comment and move on to the next commit in the same way. So in our example we can pick and choose which files, and lines within files, that we want as part of our “password recovery” commit, commit that, then pick and choose the variable naming fixes, commit those, etc..

We end up with a useful history with change-specific commits. This alone would have sold me on git.

2. You amend/edit a previous commit

You’re adding the “password recovery” feature, editing away, and you make your commit. Then you notice a new file that you forgot to add in. No svnadmin required, no dirty history, instead you just stage the file ready for commit, and then amend the previous commit:

git commit --amend

You get the opportunity to edit the comment if you need to, and a totally new history is created in your repository.

One of the advantages of having a distributed system is that if you’ve not pushed that commit to any other developers yet, then you can fix your own repository up without adversely affecting anyone else.

3. You can undo previous commits

The --amend option is really just a convenient layer around the ability to fully reverse our a previous commit. You can do this yourself with:

git reset HEAD^

This will reset your repository to how it was one before the HEAD (that’s what the ^ means). Your files in your working directory will remain untouched, it just changes the repository so that it no longer has the commit recorded. You can then re-edit, reorganize, whatever you want before committing what you actually wanted in your repository.

Many more

There are many more very nice things that you can do with git.

Some are simple things, like that creating a new repository is very cheap and quick, so you end up doing it for things that you wouldn’t necessarily bother with for svn. It’s also done in place by default, as opposed to svn where you have to do the checkout/add trick to make a repository in place.

Some are quite complex things, like bisect is an incredible tool for easily tracking down which version a bug was introduced in. You could do it with svn too, but it ships with git - ready to go.

It’s definitely worth a try whenever you can justify it :)

Tags: git, scm, svn
Hierarchy: previous, next

Comments

There are 0 comments on this post. Post yours →

Post a comment

Required fields look like this.

Markdown enabled. See the syntax rules for help.