What is the Difference Between Mercurial and Git?

Viewed 639247

I've been using git for some time now on Windows (with msysGit) and I like the idea of distributed source control. Just recently I've been looking at Mercurial (hg) and it looks interesting. However, I can't wrap my head around the differences between hg and git.

Has anyone made a side-by-side comparison between git and hg? I'm interested to know what differs hg and git without having to jump into a fanboy discussion.

25 Answers

I work on Mercurial, but fundamentally I believe both systems are equivalent. They both work with the same abstractions: a series of snapshots (changesets) which make up the history. Each changeset knows where it came from (the parent changeset) and can have many child changesets. The recent hg-git extension provides a two-way bridge between Mercurial and Git and sort of shows this point.

Git has a strong focus on mutating this history graph (with all the consequences that entails) whereas Mercurial does not encourage history rewriting, but it's easy to do anyway and the consequences of doing so are exactly what you should expect them to be (that is, if I modify a changeset you already have, your client will see it as new if you pull from me). So Mercurial has a bias towards non-destructive commands.

As for light-weight branches, then Mercurial has supported repositories with multiple branches since..., always I think. Git repositories with multiple branches are exactly that: multiple diverged strands of development in a single repository. Git then adds names to these strands and allow you to query these names remotely. The Bookmarks extension for Mercurial adds local names, and with Mercurial 1.6, you can move these bookmarks around when you push/pull..

I use Linux, but apparently TortoiseHg is faster and better than the Git equivalent on Windows (due to better usage of the poor Windows filesystem). Both http://github.com and http://bitbucket.org provide online hosting, the service at Bitbucket is great and responsive (I haven't tried github).

I chose Mercurial since it feels clean and elegant -- I was put off by the shell/Perl/Ruby scripts I got with Git. Try taking a peek at the git-instaweb.sh file if you want to know what I mean: it is a shell script which generates a Ruby script, which I think runs a webserver. The shell script generates another shell script to launch the first Ruby script. There is also a bit of Perl, for good measure.

I like the blog post that compares Mercurial and Git with James Bond and MacGyver -- Mercurial is somehow more low-key than Git. It seems to me, that people using Mercurial are not so easily impressed. This is reflected in how each system do what Linus described as "the coolest merge EVER!". In Git you can merge with an unrelated repository by doing:

git fetch <project-to-union-merge>
GIT_INDEX_FILE=.git/tmp-index git-read-tree FETCH_HEAD
GIT_INDEX_FILE=.git/tmp-index git-checkout-cache -a -u
git-update-cache --add -- (GIT_INDEX_FILE=.git/tmp-index git-ls-files)
cp .git/FETCH_HEAD .git/MERGE_HEAD
git commit

Those commands look quite arcane to my eye. In Mercurial we do:

hg pull --force <project-to-union-merge>
hg merge
hg commit

Notice how the Mercurial commands are plain and not special at all -- the only unusual thing is the --force flag to hg pull, which is needed since Mercurial will abort otherwise when you pull from an unrelated repository. It is differences like this that makes Mercurial seem more elegant to me.

Git is a platform, Mercurial is “just” an application. Git is a versioned filesystem platform that happens to ship with a DVCS app in the box, but as normal for platform apps, it is more complex and has rougher edges than focused apps do. But this also means git’s VCS is immensely flexible, and there is a huge depth of non-source-control things you can do with git.

That is the essence of the difference.

Git is best understood from the ground up – from the repository format up. Scott Chacon’s Git Talk is an excellent primer for this. If you try to use git without knowing what’s happening under the hood, you’ll end up confused at some point (unless you stick to only very basic functionality). This may sound stupid when all you want is a DVCS for your daily programming routine, but the genius of git is that the repository format is actually very simple and you can understand git’s entire operation quite easily.

For some more technicality-oriented comparisons, the best articles I have personally seen are Dustin Sallings’:

He has actually used both DVCSs extensively and understands them both well – and ended up preferring git.

The big difference is on Windows. Mercurial is supported natively, Git isn't. You can get very similar hosting to github.com with bitbucket.org (actually even better as you get a free private repository). I was using msysGit for a while but moved to Mercurial and been very happy with it.

There's one huge difference between git and mercurial; the way the represent each commit. git represents commits as snapshots, while mercurial represents them as diffs.

What does this means in practice? Well, many operations are faster in git, such as switching to another commit, comparing commits, etc. Specially if these commits are far away.

AFAIK there's no advantage of mercurial's approach.

Nothing. They both do the same, both perform about equally. The only reason you should choose one over the other is if you help out with a project that already uses one..

The other possible reason for choosing one is an application or service which only supports one of the system.. For example, I pretty much chose to learn git because of github..

Are there any Windows-based collaborators on your project?

Because if there are, the Git-for-Windows GUI seems awkward, difficult, unfriendly.

Mercurial-on-Windows, by contrast, is a no-brainer.

Sometime last year I evaluated both git and hg for my own use, and decided to go with hg. I felt it looked like a cleaner solution, and worked better on more platforms at the time. It was mostly a toss-up, though.

More recently, I started using git because of git-svn and the ability to act as a Subversion client. This won me over and I've now switched completely to git. I think it's got a slightly higher learning curve (especially if you need to poke around the insides), but it really is a great system. I'm going to go read those two comparison articles that John posted now.

I'm currently in the process of migrating from SVN to a DVCS (while blogging about my findings, my first real blogging effort...), and I've done a bit of research (=googling). As far as I can see you can do most of the things with both packages. It seems like git has a few more or better implemented advanced features, I do feel that the integration with windows is a bit better for mercurial, with TortoiseHg. I know there's Git Cheetah as well (I tried both), but the mercurial solution just feels more robust.

Seeing how they're both open-source (right?) I don't think either will be lacking important features. If something is important, people will ask for it, people will code it.

I think that for common practices, Git and Mercurial are more than sufficient. They both have big projects that use them (Git -> linux kernel, Mercurial -> Mozilla foundation projects, both among others of course), so I don't think either are really lacking something.

That being said, I am interested in what other people say about this, as it would make a great source for my blogging efforts ;-)

There is a great and exhaustive comparison tables and charts on git, Mercurial and Bazaar over at InfoQ's guide about DVCS.

Yet another interesting comparison of mercurial and git: Mercurial vs Git. Main focus is on internals and their influence on branching process.

Related