A few months ago I adopted Mercurial for a project on which I was working. At that time I was faced with a choice between Mercurial or Git, and Mercurial seemed the right choice because it behaved similarly to Subversion, with which nearly everyone is familiar. Git, however, seemed to be developed by-hackers-for-hackers. Although this often yields the best feature set it does, in my view, tend to lead to confusion (and occasionally architectural omissions).
(That said, I was tempted by Git; I’d closely followed the discussion which led to its development on the Linux kernel mailing list years ago, so I felt ahead of the game!)
Only four months later, and it looks to me like I backed the wrong horse. The list of open source projects using Mercurial is impressive – OpenJDK, Mozilla, OpenSolaris, Symbian OS – but they tend to be corporate efforts, and therefore aren’t likely to be trend-setters. All the cool kids seem to be hanging around the Git block – Linux, Perl, X.org, Qt, Ruby on Rails, Wine, Samba, GHC, Scratchbox, VLC and not to mention Android. That sort of momentum of grass-roots-led open source projects is, I reckon, bound to push Git ahead irrespective of the merits of the two.
So what are the merits of the two? From a few hours’ research, most people seem to agree on these facts:
- Mercurial behaves more like subversion, in terms of command-line syntax. Some see this is as good, some as bad.
- Git has squillions of commands. Likewise.
- Git is rubbish on Windows. Subversion has the excellent TortoiseHg. Efforts to produce an equivalent for Git seem to have stopped.
- Git has no knowledge of file renames. Most people seem to think this is a disadvantage, but the more enlightened opinions note that this is actually an advantage, because Git will automatically notice portions of files that are similar, and can therefore keep track of changes even if a file is split into two. Allegedly. Cool!
- Git has freakishly good Subversion integration. It appears you can almost ask it to treat a Subversion branch on a server as just another Git branch.
- The physical structure of Mercurial is possibly more suited to integration with other tools/IDEs/etc., in that there are clear libraries. Tools would need to launch processes to integrate with Git.
- Both are a bit rubbish with projects composed of many smaller projects, though it sounds like Git’s submodules support is more ‘core’ than the Subversion ‘forest’ extension designed to support this. I may be wrong.
I’ve also heard two other things, but I can’t justify them: one is that Git has a more coherent branching strategy than Mercurial (there’s no reason why you need to create a new repository for a new branch), and the other is that Git is rubbish with UTF-16 text.
Behind the scenes, the concepts are very similar. The only real difference is that Mercurial works on changesets, which can only build on the relevant prior changeset, whilst Git works in terms of entire trees of files (which, behind the scenes, may be stored as deltas).
So, when I eventually switch from Subversion to a distributed system, I’ll probably be switching to Git. I hope there’s a viable path for progress on the Windows version by then.