More On Mercurial vs. Git (with Graphs!)
Mar. 31st, 2011 11:39 amTwo days ago, I posted a very wordy essay in which I tried to explain why I think Git is badly broken, and why everybody should instead use Mercurial until the Git developers fix it. Okay, I wasn't quite that harsh, but I came close.
People on Reddit complained that my written technical language is too confusing, especially because it introduces new terminology to make its point. They demanded graphs, with nodes and edges and circles and arrows and everything. So, I slaved over a hot graph editor for a few hours, and came up with the two graphs below which I hope will illustrate the problem.
Below, I've drawn a simplified graph of a Git repository change history with three currently defined branches, master, release and topic. Before you Git enthusiasts complain that it's contrived to show an unrealistically bad case of change history complexity, let me assure you this is a simplified example. I have access to a real-world Git repository where there are six currently running release branches and about forty currently running topic branches with several hundred previous branches that have now been deleted from the authoritative server.
Here's the graph. Can you tell me on which branch ab3e2afd was committed? What is the earliest change in the release branch? Where did the topic branch start?

I know. It's not fair. I didn't let you see the commit logs. Believe me, you don't want to see them. They're no help. You'd think the domesticated primates would put helpful clues in them to tell you the answers to these questions, but they never do. Sometimes, even worse, they lie.
A more clever rebuttal to my question is to ask in return, "Why do you need to know?" Let me answer that preemptively: A) I need to know which branch ab3e2afd was committed to know whether to include it in the change control review for the upcoming release; B) I need to know which change is the first change in the release branch because I'd like to start a new topic branch with that as my starting point so that I'll be as current as possible and still know that I can do a clean merge into master and release later; and C) I need to know where topic branch started so that I can gather all the patches up together and send them to a colleague for review.
Much of the craziness that drives Git users to get into heated arguments about "rebase" vs. "merge" is about trying very hard to make sure developers rewrite the history in their local clones sufficiently well that the change history graph on the authoritative shared repository doesn't look like that graph above.
Mercurial users, in most cases, don't have this bizarre urge. Here's why:

See the difference?
Every node in the graph is colored to indicate the name of its Mercurial branch. All the guesswork is gone. You know there was a branch named temp that got merged into release but not master. It's probably marked "closed" now that it isn't needed anymore.
Some of the early work on the topic branch went into temp before merging into the release branch. Later, the release branch merged back into the ongoing topic branch.
All this is possible because Mercurial stores the name of the branch in the changeset header. Git should do this too, and it doesn't. Instead, Git encourages its users to fake up a history that looks "clean" but isn't really accurate.
The saddening thing is that so many Git users seem to have a conceptual block against even recognizing there is a problem here. They embrace the need for historical revisionism that their tools force on them, and they call it a virtue.
I dread to contemplate the possibility of moving a certain large and venerable proprietary operating system source code base out of an old legacy version control system and into the hot new DVCS that all the kids are talking about. I predict I'm going to have to show this weblog posting to a lot of people.
People on Reddit complained that my written technical language is too confusing, especially because it introduces new terminology to make its point. They demanded graphs, with nodes and edges and circles and arrows and everything. So, I slaved over a hot graph editor for a few hours, and came up with the two graphs below which I hope will illustrate the problem.
Below, I've drawn a simplified graph of a Git repository change history with three currently defined branches, master, release and topic. Before you Git enthusiasts complain that it's contrived to show an unrealistically bad case of change history complexity, let me assure you this is a simplified example. I have access to a real-world Git repository where there are six currently running release branches and about forty currently running topic branches with several hundred previous branches that have now been deleted from the authoritative server.
Here's the graph. Can you tell me on which branch ab3e2afd was committed? What is the earliest change in the release branch? Where did the topic branch start?

I know. It's not fair. I didn't let you see the commit logs. Believe me, you don't want to see them. They're no help. You'd think the domesticated primates would put helpful clues in them to tell you the answers to these questions, but they never do. Sometimes, even worse, they lie.
A more clever rebuttal to my question is to ask in return, "Why do you need to know?" Let me answer that preemptively: A) I need to know which branch ab3e2afd was committed to know whether to include it in the change control review for the upcoming release; B) I need to know which change is the first change in the release branch because I'd like to start a new topic branch with that as my starting point so that I'll be as current as possible and still know that I can do a clean merge into master and release later; and C) I need to know where topic branch started so that I can gather all the patches up together and send them to a colleague for review.
Much of the craziness that drives Git users to get into heated arguments about "rebase" vs. "merge" is about trying very hard to make sure developers rewrite the history in their local clones sufficiently well that the change history graph on the authoritative shared repository doesn't look like that graph above.
Mercurial users, in most cases, don't have this bizarre urge. Here's why:

See the difference?
Every node in the graph is colored to indicate the name of its Mercurial branch. All the guesswork is gone. You know there was a branch named temp that got merged into release but not master. It's probably marked "closed" now that it isn't needed anymore.
Some of the early work on the topic branch went into temp before merging into the release branch. Later, the release branch merged back into the ongoing topic branch.
All this is possible because Mercurial stores the name of the branch in the changeset header. Git should do this too, and it doesn't. Instead, Git encourages its users to fake up a history that looks "clean" but isn't really accurate.
The saddening thing is that so many Git users seem to have a conceptual block against even recognizing there is a problem here. They embrace the need for historical revisionism that their tools force on them, and they call it a virtue.
I dread to contemplate the possibility of moving a certain large and venerable proprietary operating system source code base out of an old legacy version control system and into the hot new DVCS that all the kids are talking about. I predict I'm going to have to show this weblog posting to a lot of people.
(frozen) How does bzr stack up?
Date: 2011-04-27 01:08 am (UTC)(frozen) Re: How does bzr stack up?
Date: 2011-04-27 02:22 am (UTC)Nice but...
Date: 2011-05-07 08:53 pm (UTC)no subject
Date: 2011-07-11 11:39 pm (UTC)no subject
Date: 2011-05-09 09:35 am (UTC)It's one of the reasons I moved to Git (the other one being that there's no good Mercurial GUI for the Mac, at least nothing that comes close to Tower for Git): when I picked up Mercurial, named branches didn't exist. And one clone per branch sounds easy and cool, until you start working for real, that is. Then: not so much. Or rather: much not so.
Maybe someone should tell them about updating their documentation, for the sake of all the future users. It would be a shame to have them pick up bad habits that will hurt them, just because the docs are so outdated.
Olivier
P.S.: I've never had so much hoops to go through before I could comment on a web site. As if OpenID wasn't already bloated enough in its basic incarnation. :S
no subject
Date: 2011-05-09 04:22 pm (UTC)That was a long damned time ago. Mercurial has had named branches for at least the last nine major release versions, and long since its 1.0 feature complete version. Maybe you should consider making comparisons between things that are comparable.
I think perhaps you meant to complain about the lack of locally named heads, i.e. bookmarks, which Mercurial has only supported for the last TWO major release versions, and which seem to have been added mainly to help people coming from Git keep from having panic attacks over exactly what you seem to want to complain about.
Seriously, there is very little about Git that isn't simpler and more straightforward in the Mercurial incarnation of it. But there is a huge and valuable feature of Mercurial that Git just completely fails to handle. Git should be fixed to handle it, and that's all I'm saying.
no subject
Date: 2011-05-23 08:44 am (UTC)no subject
Date: 2011-05-23 04:19 pm (UTC)Not disagreeing with you, mind, just thinking that if this is the most damning complaint you can launch against Mercurial, then I'm going to need a lot of convincing to become a Git enthusiast. The documentation there is a crawling abomination and the tutorials are all filled with equally poor advice plus a healthy dose of conflicting judgments about best workflow practices. The internal Git users group at the large software enterprise where I work is a comedy goldmine for precisely the reasons I describe in these two articles. Their transition from legacy centralized VCS into Git is in the thick of things right now, and the battles over workflow and aesthetics are raging hot and heavy. I see all this stuff every day. It's not pretty, and Git's one major flaw is mainly to blame.
WTF with so much validation?
Date: 2011-09-08 02:38 am (UTC)Indeed.
1) The field to type the OpenID URL should be on this page, not open a new one
2) Once you have the OpenID, that should be enough, or at least you should white-list some providers, no need for a captcha
3) Then you ask for e-mail? It's provided by the OpenID persona!
4) And then confirm the e-mail? Come on, what is the point of using OpenID then?
Re: WTF with so much validation?
Date: 2012-04-03 07:17 pm (UTC)If you allow anonymous comments, then the burden on OpenID commenting is basically nothing. You can type your identity URL, click post, and you're done. No hoops.
Your arrows are pointing in the wrong direction
Date: 2011-06-07 03:11 pm (UTC)Note: You are also missing a "temp" pointer in your Git graph for node ab3e2afd. The only way to get rid of this pointer would be to specifically delete it (git branch -d temp).
A) If you are going to release a0ee451c, then all of its ancestors need to be included in change control. You can terminate the lineage to include in change control at the tag or bookmark that notes your last release.
B) I'm not totally sure what you are after here. I think if you are looking for a stable point in history to branch off of, a bookmark would work much better than a branch name. I'm not sure why the first commit in a particular named branch would have more or less stability associated with it.
C) If you are going to send all the "topic" branch commits a colleague, then you must assume that they have all relevant history, which includes everything but 63a702b1, and 9201cef9. They already have the first two "topic" branch commits. Thus you would only need to send them the tip of the "topic" branch.
I guess I'm just not following where there is any information lost, or decisions that couldn't be made. This could be an overly simplified example that lost some of the complexity you have been frustrated with.
My solutions do depend on correct and responsible usage of tags or bookmarks. I also presume that contributors are not deleting pointers in hopes of throwing people off their scent.
no subject
Date: 2011-07-11 11:41 pm (UTC)no subject
Date: 2011-07-12 12:30 am (UTC)no subject
Date: 2011-07-12 02:47 am (UTC)Experience with named-branches scaling?
Date: 2012-05-28 04:51 pm (UTC)[ Also mentioned here: http://mercurial.selenic.com/wiki/StandardBranching#Don.27t_treat_branch_names_as_disposable ]
(I'm not a Mercurial user.)
Thanks.
Images Gone
Date: 2016-03-22 12:58 pm (UTC)do you happen to have the images still / could you update the links? Would love to have them for a company internal discussion with a few teams. We really need to migrate away from git, your arguments of the original post pretty much materialized..., while the merc team is happy.