I didn’t think I would blog about the launch of github, because I thought it was pretty meh. Sure it’s nice to put your projects on it and be able to fork other projects, but it was still pretty useless as there was no way of visualizing all the branches (git is all about the commit graph).

So they fixed their most important flaw and they add features that should make collaboration easier. This makes me really hopeful for github’s future. Github is the place to be for open source projects!

You might have heard about distributed version control systems recently, for example git. There are a lot of articles popping up left and right about DVCS. What I find interesting about this is that version control has again become something to talk about. This is very healthy as version control is such an important tool for software developers.

When I started using using subversion five years ago, version control faded to the background. Subversion greatest strength is its simplicity. After a while, you get used to its quirks and it just works. Sure, some operations are painful, like merging back a branch, but you learn how to do it (and try to minimize to number of times you have to do it).

But five years is a pretty long time in computing terms. Maybe something better has come along. Maybe the reasons you chose something five years ago don’t hold anymore. This applies to everything. Sometimes you come across a company policy that looks stupid. At the time the decision was taken, it might actually have made sense. But things changed (as they tend to) and nobody took the time to check if the assumptions used to make the decision were still true today.

I suggest you use all the hype around git, and the discussions it generates, to revisit, to question all your assumptions about what is version control and what it can do for you. Is version control about sharing code with other developers and having some kind of history and backup? That’s something that, yes, it provides, but it can do so much more.

Have you ever used a VCS that required you to lock a file before editing, to avoid conflicts if two developers edited the file at the same time? If you’ve used any system that doesn’t require it, you just know that it’s a not a real problem. However, how do you explain it to the developer that is convinced that it is a very real problem? That’s the problem I have with git right now after using it for six months. I don’t how to convince people to try it when they raise objections. I can only say that it’s awesome and that going back to subversion from git would be more painful for me than going back to locking file from subversion.

It appears that Rails will switch to git real soon. Nice! However, it means confusion for developers used to svn. You might find a few tips on this blog to help you get started, but right now I want to give you the secret to git mastery:

You need to think in terms of how you want to modify your graph. My what you say?!? A git repository is a directed acyclic graph of commits (the nodes). Huh?? Read this article: Git for Computer Scientists. Do not continue reading before you understand that article. Everything falls into place when you understand that all git commands manipulate these four basic structures: blobs, trees, commits and tags.

From now on, before typing a git command in the shell, try to picture in your head how you want your repository to look after the command. Your best friend is gitk for visualization (use the –all option to see all branches). Run it before and after each command you do with git. Here is what you should be thinking when using these commands:

git commit: I am creating a new node in my graph, linked to the current node.

git branch branch_name: I am tagging a node with a name.

git merge: I am creating a new node that will link two parents nodes, one for each branch I am merging (could be more than two).

git fetch remote_repos: I am adding all the nodes from a distant repository to my graph.

git push: I am sending all the nodes I created to a distant repository.

git pull: I want to fetch all remote nodes AND merge.

Once you think like this, “advanced” git stuff becomes trivial. For example, this morning one coworker realized that his last three commits actually belonged to a branch. Try to visualize the solution. When you think about it, nothing has to change about the actual graph, just which nodes the tag (the branch name) needs to point at. So you just create a branch where you are, on the last commit, and then you can use the reset command to move back the other branch to the correct commit.

That’s the core of git. There are maybe two other things to worry about when using git. The first is the index, which is sort of a staging area where you prepare your commits. The other thing is the way git configuration works and the way it names and references branches (and the special reference HEAD) and remote repositories. Check out the git user manual.

I’m beginning to wonder if I wasn’t a bit pessimistic when I said 80% of rails developper to switch to git before christmas ’08. My own unscientific measurement for January show more than 50% of new projects are using git. If you still haven’t installed git and are looking for a reason, here’s one: Dr Nic is the new maintainer of the Rails Textmate Bundle and you’ll need git to get it. It includes new helpers specific to Rails 2.0. Speaking of Textmate, it looks like someone picked up the development of the git bundle. January also saw the release of thin and the next version of merb is now also on git. Seriously, I don’t think I need to keep pushing people to git anymore. The momentum is too strong and you will have to use git in the very near future. If you still need more convincing, here are a couple of very interesting links:

Git does not require a special “server” to run. For example, if you are on a local network, you can just put the repository on a shared network drive. Git does not handle the security. You configure the read/write access on the folder. I’m not an expert in system administration so I’m going to suggest some options and provide links that I found helpful:

Ssh is you friend for security. If you do not want to provide shell access to everyone, you can setup one git user and use ssh keys to provide access. If you go that route, take a look at gitosis, which is a bunch of python scripts that automates part of administering that kind of setup. Gitosis gives you a git repository to configure access and projects. It’s very nice.

Last night I presented git at Montreal On Rails and I think it went pretty well. I might have forgotten a few things I wanted to say, but I got quite enough question about other aspects of git to fill an hour, aspects that I didn’t expect to be able to squeeze in. Although git is a very different beast than subversion, I feel like most people understood what it is all about. We have some very smart people here in Montreal, and it sure does not look like a ghetto.

Now let me remind you of your homework for the week (it leads toward the path to git enlightenment):

Listen to Linus Torvalds git talk at google. It really helps understanding the design of git.

If you are currently using svn, see my guide on how to start using git while keeping a central svn repository.

Explore parallel universes with branches. Develop a new feature in a branch. Try out a plugin in a branch. Have a branch with rails edge. Do some crazy experimental refactoring in a branch, including renaming files (yes! git will correctly merge).

Play with git. Set up local “remote” repository to experience what distributed version control is all about. Try out strange branching scenario just to see how git will handle it.

Read the documentation. See if you can find how to: commit only part of file, send your last 3 commit to another branch, change your last commit (there are 2 ways actually).

Change gitk fonts

Bash completion

Lookup contrib/completion in the git source directory. Git-completion.bash includes the instruction to set it up. You need to copy that file somewhere and source it in your ~/.profile. Once this is done, you can press tab to complete git commands, options and the name of branches in bash. The script also adds __git_ps1 which you can use in your PS1 to include the name of the current branch in your bash prompt. Because you will use branches with git, it can help you remember that you switched branch just before leaving work the day before.

Note: These instructions are for Mac OS 10.4. I don’t know if they’ll work with Leopard.

Installing git is easy, just compile from the source. Git svn is harder to install because it is a bunch of perl scripts that needs the svn perl bindings (it comes with git btw). Here are the steps I recommend to make sure everything works.

First, we’ll install git using Macports. This will take care of installing all the required perl libraries:

$ sudo port install git-core +svn

However, macports installs a slightly old version of git. So I suggest downloading the latest and compiling from source.

$ sudo make install
# Note: watch out for the way your PATH is setup
# to make sure you are using this new git version
# instead of the macports version
$ git --version

Now if you try to run git svn, you might get an error about it not finding SVN/Core.pm. That means your version of subversion does not include the perl bindings (which is the standard if you installed svn with macports). I suggest you install subversion from this package that includes the language bindings. Now you need to add this to your ~/.profile:

export PERL5LIB=/usr/local/lib/svn-perl

Everything should work. Now it’s time to import your svn repositories and enjoy git.

I’ve been using git for three months now and it has had zero impact on my team. They weren’t even aware I was using it for the first few weeks. That means, you can start using it now, for your personal development, without having to convince anybody.

Git comes with a svn wrapper. You can import your svn repository to a local git repository. You then get all the advantages of git: easy branching/merging, offline operation(very useful if you work with a laptop), etc.

$ git svn clone http://path/to/svn -T trunk -t tags -b branches

This command will import all the revisions from svn and create branches in your git repository (one for trunk, and one for all your branches). You will be on a branch master (linked to trunk) and can start working. You commit normally to your repository.

Rebase works by reverting your changes, getting the latest revisions from svn, and then reapplying your changes. You resolve any conflicts (if there any). The last command then pushes your changes to svn for your team to enjoy.

Those are the three commands you need to know to use git with svn.

Caveats

Svn:externals are not supported. I suggest you use piston to handle them.

Rails developers will switch to Git because just like Rails is ten times better than any java( or .Net) framework, git is ten times better than subversion.

I will be presenting git at the next Montreal On Rails. You may want to wait for my presentation to switch to git, but that means going a whole month without benefitting from git’s awesomeness. So here are a couple of links to get you started:

Linus Torvalds presentation on git at Google: You NEED to listen to this talk to change the way you look at source control and understand why git rocks so much. Linus is great and funny in this talk. Warning: he will call you stupid.

Peepcode screencast on git: Peepcode rules and this screencast will show you how to use git. It costs 9$, but if you were at the last Montreal on Rails, you should have a special code to get one screencast for free.