We’ve watched many of our favorite open source libraries migrate from Google Code hosting to BitBucket and GitHub lately. The main reason is that most of the projects wanted to move from centralized version control like Subversion (used by Google Code) to distributed version control systems like Mercurial (BitBucket) and Git (GitHub).
If you needed further proof that the world is moving toward distributed version control, last year Google Code began offering Mercurial as an alternative to Subversion (though Mercurial projects are still in the minority on Google Code).
Assuming you’ve already made the often painful migration from CVS to Subversion, you may be wondering why you would want to switch version control systems yet again.
The short answer is that if you’ve ever tried to branch and merge in Subversion then you already know the main advantage distributed systems have over Subversion — branching and merging your code is no longer a massive headache doomed to failure.
In fact, distributed systems make branching, and merging those branches back, so easy that it will completely change the way you think about working with your code.
There are other advantages to distributed version control as well. But before you’ll really understand them, you have to understand the conceptual differences between the two. I’ll admit that I tried out Mercurial a while back and, while it was simple to figure out, I just didn’t get Mercurial’s way of doing things.
Then I ran across Joel Spolsky’s awesome Mercurial overview. More than just an intro and tutorial on Mercurial (though it has those, too) Spolsky’s site is essential for deprogramming your Subversion-ingrained habits.
The Subversion Re-education section is devoted to the differences between Mercurial and Subversion and how embracing Mercurial’s approach will make your life easier. It’s a highly recommended read for those thinking about making the move from Subversion to a distributed system like Mercurial.
The biggest point that Splosky clarified for me was the advantage of Mercurial’s “changesets” over Subversion’s “revisions:”
Here’s the difference. Imagine that you and I are working on some code, and we branch that code, and we each go off into our separate workspaces and make lots and lots of changes to that code separately, so they have diverged quite a bit.
When we have to merge, Subversion tries to look at both revisions—my modified code, and your modified code—and it tries to guess how to smash them together in one big unholy mess. It usually fails, producing pages and pages of “merge conflicts” that aren’t really conflicts, simply places where Subversion failed to figure out what we did.
By contrast, while we were working separately in Mercurial, Mercurial was busy keeping a series of changesets. And so, when we want to merge our code together, Mercurial actually has a whole lot more information: it knows what each of us changed and can reapply those changes, rather than just looking at the final product and trying to guess how to put it together.
Obviously, no matter how much better Mercurial might be in the end, it’ll take some adjusting. As Splosky writes, “in the early days, you will be tempted, I know you will, to give up on Mercurial and go back to Subversion, because it will be strange, like living in a foreign country, and you’ll be homesick.”
However, if you stick with Mercurial, eventually your brain will adjust and you’ll see the light.