Update 2016: Instead of fixing the article, the Atlassian web workers removed the comments which point out the misinformation in the article. *sigh*
Summary:
In the Atlassian Blog, a Git proponent spread blatant misinformation which the Atlassian folks are leaving uncommented even though the falseness has been shown by multiple people and even in examples in the article itself.
The claims and corrections:
bookmark@path
, when there could be confusion. This is equivalent to git’s use of path/branch
, but only used where it is needed, while git forces the user to always make that distinction.mq
) and the record extension provides a staging area like the git index — for those who want it. 2 years ago, Atlassian developer Charles O’Farrell published the article Git vs. Mercurial: Why Git? [3] in which he claimed to show "the winning side of Git”. This article was part of the Dev Tools series at Atlassian and written as a reply to the article Why Mercurial? [4]. It was spiced with so much misinformation about Mercurial (statements which were factually wrong) that the comments exploded right away. But the article was never corrected. Just now I was referred to the text again, and I decided to do what I should have done 2 years ago: Write an answer which debunks the myths.
“I also think that git isn’t the most beginner-friendly program. That’s why I’m only using its elementary features” — “I hear that from many git-users …” — part of the discussion which got me to write this article
Charles starts off by contradicting himself: He claims that git is safer, because it “actually never lets you change anything” - and goes on to explain, that all unreferenced data can be garbage collected after 30 days. Since nowadays the git garbage collector runs automatically, all unreferenced changes are lost after approximately 30 days.
This obviously means that git does allow you to change something. That this change only becomes irreversible after 30 days is an implementation detail which you have to keep in mind if you want to be safe.1
He then goes on to say how this allows for easy history rewriting with the interactive rebase and correctly includes, that the histedit extension of Mercurial allows you to do the same. (He also mentions the Mercurial Queues Extension (mq [5]), just to admit that it is not the equivalent of git rebase -i
but instead provides a staging area for future commits).
Then he starts the FUD2: Since histedit stores its backup in an external file, he asks rhetorically what new commands he would have to learn to restore it.
Dear reader, what new command might be required to pull data out of a backup? Something like git ref? Something like git reflog to find it and then something else?
Turns out, this is as easy and consistent as most things in Mercurial: Backup bundles can be treated just like repositories: To restore the changes, simply use
hg pull backup.bundle
So, all FUD removed, his take on safer history and rewriting history is reduced to “in hg it’s different, and potentially confusing features are shipped as extensions. Recovering changes from backups is consistent with your day-to-day usage of hg”.
(note that the flexibility of hg also enables the creation of extensions like mutable hg [6] which avoids all the potential race conditions with git rebase - even for code you share between repositories (which is a total no-go in git), with a safety net which warns you if you try to change published history; thanks to the core feature phases [7])
On branching Charles goes deep into misinformation: He wrote his article in the year 2012, when Mercurial had already provided named branches as well as anonymous branching for 6 years, and one year after bookmarks became a core feature in hg 1.8 [8], and he kept talking about how Mercurial advised to keep one clone per branch by referencing to a blog post [9] which incorrectly assumed that the hg developers were using that workflow (obviously he did not bother to check that claim). Also he went on clamoring, that bookmarks initially could not be pushed between repositories, and how they were added “due to popular demand”. The reality is, that at some point a developer simply said “I’ll write that”. And within a few months, he implemented the equivalent of git branches. Before that, no hg developer saw enough need for them to excert that effort and today most still simply use named branches.
But obviously Charles could not imagine named branches to work, so he kept talking about how bookmarks do not have namespaces while git branches have them, and that this would create confusion. He showed the following example for git and Mercurial (shortened here):
* 9e4b1b8 (origin/master, origin/test) Remove unused variable | * 565ad9c (HEAD, master) Added Hello example |/ * 46f0ac9 Initial commit
and
o changeset: 2:67deb4acba33 | bookmark: master@default | summary: Third commit | | @ changeset: 1:2d479c025719 |/ bookmark: master | summary: Second commit | o changeset: 0:e0e024ff06ad summary: First commit
Then he asked: “would the real master branch please stand up?”
Let’s try to answer that:
Git: there is a commit marked as (origin/master, origin/test)
, and one marked as (HEAD, master)
. If you know that origin
is the canonical remote repository in git, then you can guess, that the names prefixed with origin/
come from the remote repository.
Mercurial: There is a commit with the bookmark master@default
and one with the bookmark master
. When you know that default
is the canonical remote repository in Mercurial, then you can guess, that the bookmark postfixed with @default
comes from the remote repository.
But Charles concludes his example with the sentence: “Because there is no notion of namespaces, we have no way of knowing which bookmarks are local and which ones are remote, and depending on what we call them, we might start running into conflicts.”
And this is not only FUD, it is factually wrong and disproven in his own example. After this, I cannot understand how anyone could take his text seriously.
But he goes on.
His final misinformation is about the git index - a staging area for uncommitted changes. He correctly identifies the index as “one of the things that people either love or hate about Git”. As Mercurial cares a lot about giving newcomers a safe environment to work in, it ships this controversial feature as extension and not as core command.
Charles now claims that the equivalent of the git index is the record [10] extension - and then complains that it does not imitate the index exactly, because it does not give a staging area but rather allows committing partial changes. Instead of now turning towards the Mercurial Queues Extension which he mentioned earlier as staging area for commits, he asserts that record cannot provide the same feature as git.
Not very surprisingly, when you have an extension to provide partial commits (record [10]) and one to provide a staging area (mq [5]), if you want both, you simply activate both extensions. When you do that, Mercurial offers the qrecord
command which stores partial changes in the current staging area.
Not mentioning this is simply a matter of not having done proper research for his article - and not updating the post means that he intentionally continues to spread misinformation.
The only thing he got right is that git blame
is able to reconstruct copies of code from one file to another.
Mercurial provides this for renamed files, but not for directly copy-pasted lines. Analysis of the commits would naturally allow doing the same, and all the information for that is available, but this is not implemented yet. If people ask for it loud enough, it will only be a matter of time, though. As bookmarks showed, the Mercurial code base is clean enough that it suffices to have a single developer who steps up and creates an extension for this. If enough people use it, the extension can become a core feature later on.
“There is a reason why hg users tend to talk less about hg: There is no need to talk about it that much.” — Arne Babenhauserheide as answer to Why Mercurial? [4]
Charles concludes with “Git means never having to say, you should have”, and “Mercurial feels like Git lite”. Since he obviously did not do his research on Mercurial while he took the time to acquire in-depth knowledge of git, it’s quite understandable that he thinks this. But it is no base for writing an article - especially not for Atlassian, the most prominent Mercurial hosting provider since their acquisition of Bitbucket, which grew big as pure Mercurial hoster and added git after being acquired by Atlassian.
He then manages to finish his article with one more unfounded smoke bomb: The repository format drives what is possible with our DVCS tools, now and in the future.
While this statement actually is true, in the context of git-vs-mercurial it is a horrible misfit: The hg-git extension [11] shows since 2009 [12], 3 years before Charles wrote his article, that it is possible to convert transparently from git to Mercurial and back. So the repository format of Mercurial has all capabilities of the repository format of git - and since git cannot natively store named branches, represent branches with multiple heads or push changes into a checked out branch [13], the capabilities of the repository format of Mercurial are actually a superset of the capabilities of the storage format of Git.
But what he also states is that “there are more important things than having a cuddly command line”. And this is the final misleading statement to debunk: While the command line does not determine what is theoretically possible with the tool, it does determine what regular users can do with it. The horrible command line of git likely contributes to the many git users who never use anything but commit -a
, push
and pull
- and to the proliferation of git gurus whom the normal users call when git shot them into their foot again.
It’s sad when someone uses his writing skills to wrap FUD and misinformation into pretty packaging to get people to take his side. Even more sad is, that this often works for quite some time and that few people read the comments section.3
And now that I finished debunking the article, there is one final thing I want to share. It is a quote from the discussion which prompted me to write this piece:
<…> btw. I also think that git isn’t the most beginner-friendly program.
<…> That’s why I’m only using its elementary features
<ArneBab> I hear that from many git-users…
<…> oh, maybe I should have another look at hg after all
This is a translation of the real quote in German:
<…> ich finde btw auch dass git nicht gerade das anfängerfreundlichste programm ist
<…> darum nutze ich das auch nur recht rudimentär
<ArneBab> das höre ich von vielen git-Nutzern…
<…> oha. nagut, dann sollte ich mir hg vielleicht doch nochmal ansehen
Note: hg is short for Mercurial. It is how Mercurial is called on the command line.
Garbage collection after 30 days means that you have to remember additional information while you work. And that is a problem: You waste resources which would be better spent on the code you write. A DVCS should be about having to remember less, because your DVCS keeps the state for you.
FUD means fear-uncertainty-doubt and is a pretty common technique used to discredit things when one has no real arguments: Instead of giving a clear argument which can be debunked, just make some vague hints that something might be wrong or that there might be some deficiency or danger. Most readers will never check this and so this establishes the notion that something IS wrong.
Lesson learned: If you take the time to debunk something in the comments, be sure to also write an article about it. Otherwise you might find the same misinformation still being spread [14] 2 years later by the same people. When Atlassian bought Bitbucket, that essentially amounted to a hostile takeover of a Mercurial team by git-zealots. And they got away with this, because too few people called them up on it in public.
A comment [15] on largefile support missing in BitBucket, despite being a much-requested feature [16] since 2012.
Note that it’s not Atlassian which got big with Mercurial. It’s Bitbucket which got big with Mercurial, and it was later bought by Atlassian. Also Atlassian is still spreading lies about Mercurial in the Atlassian blog by hosting a guest entry by a git zealot which is filled with factual errors, some even disproven in the examples in the article. Despite being called out on that in public [17], they did not even see the need to add a note to that guest entry about misunderstanding by the author.
I asked their marketing team personally several times to correct this. I know they read it, because people I used to collaborate with work at the BitBucket Mercurial support.
Dear BitBucket, this is where you could be: Virtuos Games uses BitTorrentSync with Mercurial for game development using decentralized large asset storage [18].
I guess they show that there is room for a Mercurial hosting company. Maybe it will be kiln [19].
I‘m sorry for the great Mercurial developers working at Atlassian to improve Mercurial support. I know you’re doing great work and I hope you will prove me wrong on this. But from the outside it seems like you’re being used to hide hostility by the parent company against the core part of their own product. “…we decided to collaborate with GitHub on building a standard for large file support” — seriously? There is already a standard for large file support [20] which has been part of Mercurial core since 2011 [21], and works almost seamlessly. It just needs support from BitBucket to be easier for BitBucket users.
This crazyness is a new spin on never trust a company [22]: never ever trust a zealot with a tool which helps “the other side”: They are prone to even put zeal over business. For everyone at BitBucket: If this isn’t a wakeup call, I don’t know what is.
And if you like Git and are happy for a competitor to get weakened: To you really want your tool to win by spreading intentional misinformation? Wouldn’t you feel more at ease seeing your tool win by merit of better technology, not by buying companies which support other tools and then starving them down and forcing them to badmouth their own technology [17]?
In many discussions on DVCS over the years I have been fair, friendly and technical while receiving vitriol [23] and misinformation and FUD [17]. This strip visualizes the impression which stuck to my mind when speaking with casual git-users.
Update: I found a very calm discussion at a place where I did not expect it: reddit [24]. I’m sorry to you, guys. Thank you for proving that a constructive discussion is possible from both sides! I hope that you are not among the ones offended by this strip.
To Hg-users: There are git users who really understand what they are doing and who stick to arguments and friendly competition. This comic arose from the many frustrating experiences with the many other git users. Please don’t let this strip trick you into going down to non-constructive arguments. Let’s stay friendly. I already feel slightly bad about this short move into competition-like visualization for a topic where I much prefer friendly, constructive discussions. But it sucks to see contributors stumble over git, so I think it was time for this.
»I also think that git isn’t the most beginner-friendly program. That’s why I’m using only its elementary features«
To put the strip in words [26], let’s complete the quote:
»I also think that git isn’t the most beginner-friendly program.
That’s why I’m using only its elementary features«
<ArneBab> I hear that from many git-users…
»oh, maybe I should have another look at hg after all«
Because there are far too many Git-Users who only dare using the most basic commands which makes git at best useless and at worst harmful.
This is not the fault of the users. It is the fault of the tool.
If you are offended by this strip: You knew the title when you came here, right?
And if you are offended enough, that you want to make your own strip and set things right, go grab the source-file [27], fire up krita [28] and go for it! This strip is free.1
If you feel that this strip fits Mercurial and Git perfectly, keep in mind, that this is only one aspect of the situation, and that using Git is still much better than being forced to use centralized or proprietary version tracking (and people who survive the initial phase mostly unscarred can actually do the same with Git as they could with Mercurial).
And Mercurial also has its share of problems - even horrible ones [29] (update 2014: These were fixed in version 3.0 [30]) - but compared to Git it is a wonder of usability.
And in case this strip does not apply to your usage of Git: there are far too many people whose experience it fits - and this should not be the case for the most widespread system for accessing the code of free software projects.
(and should this strip be completely unintelligible to you: curse a world in which the concept of monofilament whips isn’t mainstream ☺ — let’s get more people to play Shadowrun [31])
So if you are one of the people, who mostly use commit, pull and push, and turn to a Git-Guru when things break, then you might want to kiss the Git-Guru goodbye and give Mercurial [2] a try.
By the way: the extensions named in the Final Round are record [32], mutable [33] and infocalypse [34]: Select the changes to commit on a hunk-by-hunk base, change history with automatic conflict resolution (even for rebase) and collaborate anonymously over Freenet [35].
And if you are one of the Git Gurus who claim that squashing attacking Ninjas is only possible with Git, have a look what a Firefox-contributor and former long-term Git-User [36] and a Facebook infrastructure developer [37] have to say about this.
All the graphics in this strip are available under free licenses: creative-commons attribution [38] or GPLv3 or later [39] — you decide which of those you use. If it is cc attribution, call me Arne Babenhauserheide and link to this article. You’ll find all the sources as well as some preliminary works and SVGs in git-vs-hg-offensive.tar_.gz [40] or git-vs-hg-offensive.zip [41] (whichever you prefer)
Anhang | Größe |
---|---|
git-vs-hg-offensive-purevector-retouch2.png [42] | 184.31 KB |
git-vs-hg-offensive.tar_.gz [40] | 22.59 MB |
git-vs-hg-offensive.zip [41] | 22.62 MB |
git-vs-hg-offensive.png [25] | 185.98 KB |
git-vs-hg-offensive-purevector-retouch2.kra [27] | 377.58 KB |
git-vs-hg-offensive-thumb.jpg [43] | 11.3 KB |
git-vs-hg-offensive-thumb-240x240.jpg [44] | 11.78 KB |
Links:
[1] http://hg-git.github.io/
[2] http://mercurial-scm.org
[3] https://blogs.atlassian.com/2012/03/git-vs-mercurial-why-git/
[4] http://blogs.atlassian.com/2012/02/mercurial-vs-git-why-mercurial/
[5] http://mercurial.selenic.com/wiki/MqExtension
[6] http://hg-lab.logilab.org/doc/mutable-history/html/
[7] http://www.selenic.com/hg/help/phases
[8] http://mercurial.selenic.com/wiki/WhatsNew/Archive#Mercurial_1.8_.282011-03-01.29
[9] https://web.archive.org/web/20130331015536/http://ghostinthecode.posterous.com/choosing-how-to-branch-in-mercurial
[10] http://mercurial.selenic.com/wiki/RecordExtension
[11] http://mercurial.selenic.com/wiki/HgGit
[12] https://bitbucket.org/durin42/hg-git/commits/06366111af3c6a2ffa06333ed60d3ed3b9ec0763
[13] http://draketo.de/light/english/dvcs-workflow-failures-git-hg#sec-2-3-2
[14] https://blogs.atlassian.com/2013/11/dont-move-to-git/
[15] https://bitbucket.org/site/master/issues/3843/largefiles-support-bb-3903#comment-25745558
[16] https://bitbucket.org/site/master/issues/3843/largefiles-support-bb-3903
[17] http://www.xn--drachentrnen-ocb.de/light/english/mercurial/factual-errors-why-git-atlassian
[18] https://blog.getsync.com/2016/02/03/virtuos-games-uses-sync-to-move-huge-datasets-when-porting-titles/
[19] http://help.fogcreek.com/8168/how-to-use-the-mercurial-largefiles-extension
[20] https://www.mercurial-scm.org/wiki/LargefilesExtension
[21] https://www.mercurial-scm.org/wiki/WhatsNew/Archive#Mercurial_2.0_.282011-11-01.29
[22] http://www.xn--drachentrnen-ocb.de/english/comments/light/never-trust-a-company
[23] http://felipec.wordpress.com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/
[24] http://www.reddit.com/r/programming/comments/20r8vu/factual_errors_in_git_vs_mercurial_why_git_from/
[25] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive.png
[26] http://www.xn--drachentrnen-ocb.de/light/english/mercurial/factual-errors-why-git-atlassian#friendly
[27] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive-purevector-retouch2.kra
[28] http://krita.org/
[29] http://www.xn--drachentrnen-ocb.de/light/english/dvcs-workflow-failures-git-hg
[30] http://www.xn--drachentrnen-ocb.de/light/english/dvcs-workflow-failures-git-hg#update-2014-05-01
[31] http://www.shadowrun.com/
[32] http://mercurial-scm.org/wiki/RecordExtension
[33] http://mercurial-scm.org/wiki/EvolveExtension
[34] http://mercurial-scm.org/wiki/Infocalypse
[35] http://freenetproject.org
[36] http://gregoryszorc.com/blog/2013/05/12/thoughts-on-mercurial-(and-git)/
[37] https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/
[38] http://creativecommons.org/licenses/by/4.0/
[39] http://gnu.org/l/gpl
[40] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive.tar_.gz
[41] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive.zip
[42] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive-purevector-retouch2.png
[43] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive-thumb.jpg
[44] http://www.xn--drachentrnen-ocb.de/files/git-vs-hg-offensive-thumb-240x240.jpg