Written on 26 Oct 2016 − last updated on 21 Feb 2018.
I don’t like git. But I’m going to migrate my projects to it.
My chief gripe with git is its user interface. It’s pretty bad. With ‘user interface’ I mean the commandline user interface. Let me show by example:
$ git help commit | wc -l 506 $ hg help commit | wc -l 59 $ hg help commit -v | wc -l 96
And currently, my git has 164 “core” commands:
$ ls -1f /usr/lib/git-core/ | grep -v / | wc -l 171
Seven of those aren’t executable and don’t work (error or by design?), meaning I
have 164 runnable git commands in the standard installation. Compare this to
mercurial’s 50 built-in commands (from
“But git commit has so many more features”, well, perhaps. But how many of those are actually used by most users? git is bloatware, and like most bloatware it comes with a notoriously difficult to understand manual.
Mercurial has a manual and user interface that I understand without too much effort, and this is by far the biggest reason I much prefer mercurial over git. If I need to know something from mercurial I can just read the documentation and go ‘ah’, with git … not so much. There’s a reason so many of the top Stack Overflow questions are about git.
Now, some might say (and indeed, have said) that I’m lazy and just need to spend
more time and effort learning git. Well, perhaps, but the thing is, git doesn’t
really do anything. Unlike a programming language or API I can’t really
build anything with it. It’s merely logistics to facilitate the actual
building of stuff.
It seems to me that ideally you want to spend as little as possible time on logistics, and as much possible time on actually building stuff. I know enough git to get by, but not enough to deal with rare exceptional situations that occur only a few times a year. For example consider this error I’ve made two or three times in the last few years:
# Do work $ git checkout -b feature-branch $ git commit -m 'Best code ever!' $ git push # Okay, work here is done so let's check out master again. $ git checkout master # Go have dinner. Discover I forgot something after dinner, fix it. # Let's just ammend that commit instead of making a new one! $ git commit --amend # But wait, I forgot I switched back to master >_<
It’s not so easy to undo the amend (the solutions listed here undo
everything, not only the
% hg ci --amend abort: cannot amend public changesets
This makes much more sense, since you typically don’t want to do this. There are exceptions, but those are rare and far in between.
There are many more examples like this to be found.
From a technical point of view mercurial has some advantages as well. It has a
well-designed plugin system; aside from the 50 standard commands mercurial also
ships with 33 extensions (
hg help extensions) by default, which add many of
the commands that are enabled by default in git. It’s also pretty easy to write
your own extension.
git ‘extensions’ are merely commands starting with
git-. These are typically
shell or Perl scripts – or in the case of
git-instaweb a shell script which
generates a Perl script – parsing the output of other git commands. It’s ugly,
it’s difficult to port reliably (as Larry Wall famously said, “it’s easier to
port a shell than a script script”), and its C core leaves it open to classic
memcpy buffer overflows. It’s not even faster, since Python is so
much easier to optimize.
GitHub had to compete with SourceForge. The challenge was pretty low; SourceForge always sucked, was always slow, and the only thing anyone really used it for was finding projects and when you found it, the first thing you did was click “Visit this project’s website”.
As for Linus, well, remember his diving app that everyone got so exited about even though most don’t actually dive? Linus also doesn’t attend user group meetings any more because it became a problem, as Greg Kroah-Hartman explains:
One time somebody sat across from him [Linus] and stared at him for an hour without ever saying anything.
Software written by Linus are like films with Tom Cruise. People go see it because it has Tom Cruise in it, not because it’s necessarily a great film.
The same reason so many use Facebook while constantly complaining about it: the network effect.
We use git and GitHub at $dayjob. Half the time I type
hg when I intended
git or vice-versa. This is also why I use Markdown for most things (even
though there are better alternatives); switching syntaxes is hard.
Lots of people are familiar with git and GitHub – not so much with mercurial and Bitbucket. I feel I’m missing out on bug reports and patches because people simply can’t be bothered sending them on an unfamiliar platform.
A number of tools only work with git, and either don’t want to implement mercurial support or sometimes even removed it. This is broken and stupid, but it is what it is.
One important reason I’ve held out with mercurial and Bitbucket for as long as I
did is because I feel having something to choose is good and don’t like
monopolies. In a monopoly sooner or later things tend to stagnate, the world of
open source is not an exception (look at SourceForge, subversion, Apache, gcc,
For a while I hoped that mercurial and git would both exist as common version control systems, but this doesn’t seem to be happening anytime soon, and I’ve grown tired of spending the increasing ‘mercurial penalty’. As mentioned above, I’d rather spend as little time as possible on these sort of logistics, and simply by using mercurial instead of git I (and others) have to spend more time on these logistics.
So let’s simply ‘go with the flow’ and use git, even though I don’t like it.