Why Mercurial > Git, or How I Learned To Stop Censoring Myself and Participate in Flamewars.

After reading Five Features from Mercurial That Would Make Git Suck Less, found via Hacker News, I have a simple explanation (something I’ve thought for a long while now).

So, Git’s written in C, and Mercurial’s written in Python (well, except for a few bottlenecks, like a binary diff, written in C). No wonder Mercurial has some nice features and intelligent DWIM behavior.

Applications written in higher-level, dynamic languages (like Python and Ruby) are always going to be more ‘intelligent’ than those written in low-level, static languages (like C and Java). A website built on top of Ruby on Rails or Django is going to feel smoother to use than one built on plain CGI, or even frameworks like Struts or WebObjects. Why?

Because these dynamic, expressive tools stop you from having to worry about the every-day issues that all applications have to deal with, so that you can concentrate on making your many Interfaces (User, Developer or otherwise) simple and intelligent, and the usage and development experience smooth.

The people programming Git don’t just have to know how to build a source-control tool. They also have to deal with the particular nuances of each operating system—the reason why, so far, Git only works properly on POSIX-based platforms—down to the types of integer supported, memory management, sockets, filesystems and character encodings.

The developers of Mercurial can concentrate 100% on building the best damn source-control utility they’re able to. Python handles the stuff like garbage collection, character en/de-coding, networking and filesystems, so that the Mercurial devs can handle the stuff like branching and merging, pushing and pulling, committing and reverting.

The terms ‘accidental complexity’ and ‘essential complexity’ have been brought to my attention.

Just out of interest, here’s the result of running ohcount (http://labs.ohloh.net/ohcount) on the source code for Git itself (minus the Documentation/ and git-gui/ directories):

Language          Files       Code    Comment  Comment %      Blank      Total
----------------  -----  ---------  ---------  ---------  ---------  ---------
c                   326      88337      12440      12.3%      13930     114707
shell               440      48546       3676       7.0%      12177      64399
perl                 26      20243       3134      13.4%       3333      26710
tcl                   1       9926        430       4.2%        841      11197
autoconf              2       8146         20       0.2%       1005       9171
python                5       2937        276       8.6%        670       3883
emacslisp             2       1621        152       8.6%        222       1995
make                  6       1517        264      14.8%        205       1986
cpp                   5       1438        423      22.7%        356       2217
css                   1        420          5       1.2%        101        526
assembler             2        220        136      38.2%         51        407
bat                   1          1          0       0.0%          0          1
----------------  -----  ---------  ---------  ---------  ---------  ---------
Total               817     183352      20956      10.3%      32891     237199

And the results for Mercurial (just the mercurial directory within the actual repo itself, which represents the bulk of the core code):

Language          Files       Code    Comment  Comment %      Blank      Total
----------------  -----  ---------  ---------  ---------  ---------  ---------
python               77      19147       4208      18.0%       3558      26913
c                     6       1646        175       9.6%        304       2125
----------------  -----  ---------  ---------  ---------  ---------  ---------
Total                83      20793       4383      17.4%       3862      29038

One has nearly 10 times as many files, and 10 times as many lines of code as the other. Can you guess which one?

In a spirit of irony, `ohcount` has been rewritten from Ruby to C. A couple of people might get a little hung up about the inclusion of these code metrics. I’m not trying to make a scientific or absolute statement about the quality of the code or tools, and I didn’t expect anyone to construe it as such. It’s funny how the most controversial bit of the blog post is the part which was something of an afterthought.