Background and Our Needs
I first heard about distributed version control systems from Allan Odgaard on the TextMate blog. We’ve been working for about a year on Unison, which is a web application to develop online training. Our development has been so fast-paced at times we’ve been forced to push out releases more quickly than we could test them thoroughly. More than once we’ve needed to push out a less-than-stable feature for a high-profile client. We would later realize something wrong with the feature, but there was no way to go back.Branching and reverting changes in version control software is supposed to allow you to do these things, but both are so annoying in SVN that we never actually used either. We only kept a branch around when we wanted to make a release and continue development in the trunk. We would never have dared roll back any commits
Enter Distributed Version Control
Distributed Version Control promised to solve these problems for us. We would be able to branch as often as we liked, which would then allow us to keep branches around for longer without worrying about merging them later.
I first looked at git, then tried mercurial (hg) for awhile, then finally decided on git. I’m going to try to provide an unbiased review of some of their strengths and weaknesses.
Realize that both tools are good at merging, both have strong user communities, and they are very similar choices. I found good comparisons hard to come by.
Mercurial
Mercurial has several advantages over git.
Excellent Documentation: The hgbook helped me to understand the concepts
Cleaner Commands: The interface requires fewer options and flags
Intuitive Commands: The names they picked for reverting changes make more sense
Windows Support: They have a full windows client, although using it to make lots of branches would get crazy fast
It also has some disadvantages
“Named Branches” suck: They added this feature as an afterthought. The way everyone branches is by “cloning” a repository. So, if you want to work in a new branch, you have to make a brand new copy of everything. The implementation of named branches simply isn’t workable
Rewriting History is difficult: hg doesn’t have the features git does here
Git
Git has its own strengths
Branching is Supreme: This is a big one. Git lets you make new branches at any time, and lets you switch back and forth between them in one working copy.
Remote Branches: Git can send and receive changes from several different public repositories. This is useful if you need to publish more than one branch so others can download your changes.
Merging and Rewriting History: You can squash several commits together into one big commit when you merge, getting rid of the useless messages. You can easily pull a new version of the code you’re working on into your experimental branches.
Disadvantages
Slightly more confusing: There are more commands by default, and the reverting commands are hard to keep straight at first
The Wrapup
The interface to Mercurial is easier, and I like their mainstream approach, but git is simply far better with anything advanced. I don’t feel that Mercurial can handle making branches for each feature you are developing, and doesn’t do a good job of pushing/pulling changes from public repositories.
In the end, we picked Git. I’m going to revisit mercurial in another year and see if they’ve finished adding a few more necessary features. I wanted a DVCS in the first place so I could branch like crazy, and Mercurial really doesn’t support it well enough.