Comment by timv
10 years ago
I think that the hate that gets lumped on mercurial's branches, though understandable, is a bit unfair
Disclaimer, it's been years since I used hg as my primary DVCS. So some of my thoughts here might be out of date, or have a misrecollection.
> branching in hg is pretty much broken*
It really isn't. It's absolutely not suited for the task that many people want to use it for, but it's totally fitting with the intended use case and the "history is immutable" philosophy of mercurial.
Using mercurial branches for anything resembling feature branching is a bad idea. But mercurial branches are perfect for things like ongoing lines of development. So, for a project like PostgreSQL, you'd have a "master" (default) branch for the head of development and then once a release goes into maintenance mode you create a new branch for "postgres-9.4" and any fixes that need to be applied to that release will be made to the maintenance branch.
Following hg's "immutable history" policy the fact that the commit was performed on a maintenance branch is tracked forever. And it should be because the purpose of your source control is to track those kinds of things: "This is the branch we used for maintenance releases of version X.Y.Z, it is now closed since we no longer support that version"
The issues with mercurial's branches are:
- For a long time they were the only concept in hg that had a simple name and looked like "multiple lines of development". Even though hg supported multiple heads and multiple lightweight clones, neither of those had commands or features with a clear and simple name, so they people turned to "branches" expecting them to do what they wanted even when they were a bad fit.
- "branch" is very general name that is often used (quite rightly) to refer to a bunch of slightly different ways of working with multiple concurrent versions. In general use it might refer simply having 2 developers who both produce independent changes from the same parent. Or to intentionally having multiple short lived lines of development based around feature. Or splitting of development right before a release so that the "release branch" is stable. Etc. Yet the feature in hg that is called "branch" is useful for only some of those things. It would have been better to call it a "development line" or something like that.
- It took far too long for hg to get a builtin way to refer to named heads (bookmarks). The model assumed that each repository (clone) would only ever want to have 1 head on each branch (development line) and that producing multiple heads was a problem that ought to be resolved as soon as possible. There's a lot of history behind that approach (almost every CVS and SVN team I ever worked with did that), but DVCS tools made it easier to move away from that, yet official hg support lagged.
So even today, the "branch" concept in hg is only useful for a small number of cases, and the "bookmarks" concept is what most people want, but they're separate things with names that don't align with expectations.
This distinction between branches and bookmarks looks like one of the things missing the most from git. Grab a random branch from some place and try to guess whether the committer intends to rewrite it in the future or not: good luck.
For the rest: https://stevebennett.me/2012/02/24/10-things-i-hate-about-gi...
> So even today, the "branch" concept in hg is only useful for a small number of cases, and the "bookmarks" concept is what most people want, but they're separate things with names that don't align with expectations.
And it doesn't help that the primary hosted repository system is Bitbucket and Bitbucket didn't support pull requests from bookmarks last time I checked.
So what about all this contradicts "branching in hg is pretty much broken"?
Your original comment linked broken branches with the fact that they can't be deleted. That's only true if you intended to talk about Mercurial named branches which aren't broken, they just aren't what you want them to be.
Bookmarks (today, and for several years) work just fine. So "branching" in the general sense isn't broken even though the combined feature set is a bit haphazard.
That bitbucket doesn't work well with bookmarks is a sign of how little Atlassian cares about hg, rather than an hg issue.
If you're arguing that the hosting options for hg are limited and fall far below the git options, then I'm not going to disagree.
In other words, in Git, a branch is just a named pointer to a particular revision. In Hg, these are called 'bookmarks' and they work exactly how you're imagining; and there is an immutable sort of bookmark that is called a 'tag' (bookmarks can be repointed; tags cannot). By creating a new head (i.e. branching) and naming that new head with a bookmark, you do exactly what `git branch` does.
Mercurial also supports an autonaming of revisions which automatically applies to all child revisions, too: these are meant to be independent lines of development with their its own head revision, and are called 'named branches'; that is what `hg branch` does. The problem that you're identifying (and that I agree is counterintuitive!) is that these names become part of the commits themselves and therefore public knowledge. Mercurial warns you when you `hg branch` that this is happening and says "did you want a bookmark?" but does not tell you, e.g., "to undo what you just did, type `hg branch default`."