Monday, January 16, 2012

What Is So Wrong With Mercurial's Named Branches?

I just installed the very latest version of mercurial, 2.0.2. It added a new little feature that warns you when you create a branch. Huh? This is what it looks like:

$ hg branch foo
marked working directory as branch foo
(branches are permanent and global, did you want a bookmark?)

Really? Have we let the git advocates push us this far? Do we really need to start discouraging named branches?

I googled around to see if I could find where the self-hate for mercurial's named branches is coming from and I found things like this, "it is almost never a good idea to use this facility for short-term branching, since branches created this way are inherently 'eternal'." (those quotes around eternal are good, actually, but you didn't explain why they should be there), and this, "you can never really delete branches (since that would mean altering older commits)." (editing history, oh noes!), and others like this. And these were all written by apparent mercurial supporters! I understand when a git developer writes misinformation about mercurial and uses it to try and make git look better (that's only human), but we mercurial users should know not to listen to it!

Here's what I think is going wrong. Git users love flexibility. The love it so much that they even include modifying their local repository history right into their standard workflow. git rebase is a core command. From what I can gather, even though mercurial now (as of years ago, actually) has powerful rebase and patch queue extensions, mercurial users still get the heebie-jeebies when they think about modifying repository history. This is where the git envy comes from. You see, git useres can alter their branch names, or even delete branch names without using scary rebase. Fact is, though, git could adopt mercurial-style named branches and git users would rebase them away or rename them with rebase willy-nilly just like they do with everything else that they deem needs editing in their history. The fact that git users can rename or delete their branches without using rebase is almost completely incidental. If you allow the use of rebase or patch queues, mercurial named branches are not any more permanent than any other changeset in the repository history. Mercurial bookmarks allow mercurial users flexibility around branch names without needing to resort to scary history editing extensions, and that makes us happy, but I don't think that we should talk down mercurial named branches. There are times when you want the branch name associated with a commit to be just as "permanent" as the commit is. Let us do that without dumb warnings that make named branches sound like a bad idea.

The only other argument people may have against mercurial's named branches is the possibility of name collisions. As if that's something that's really hard to deal with. Anyone who has written a fair amount of C code (I'm looking at you, git developers) knows how to prefix a name to get poor-man's namespaces. Alternatively, many projects require an issue tracker number in a feature-branch or bugfix-branch name. Name collision problem solved.

In conclusion, mercurial named branches are fine. Use them more. Use rebase and/or patch queues[1] to rename or delete the branches when necessary. If that really bothers you, you have bookmarks now, but don't go all git-apologetic on named branches. Mercurial is every bit as awesome as git.

1. Before you push to a publicly accesible repository, of course. Ask a git user why that's important.