Cool. The changelog lists lots of updates; I'd be interested to hear from those who have had more experience with Git as to whether this improves Mercurial's stance versus Git.
There are two big things git has traditionally done better than Mercurial: lightweight branching, and rebasing. Both were possible in Mercurial using mq (plus qguards, in the case of lightweight branching), but the experience was rather clumsy. I didn't mind putting up with it, since, at the time the two systems came out, Mercurial was markedly easier to use than git. But, over the last year, git closed a lot of the usability gap, while Mercurial has held almost completely still, and that's resulted in a lot of arguments that Mercurial's time had passed, and git was the way to go.
The good news is that this release fully eliminates git's first advantage, and either eliminates, eliminates and beats, or fails to address the second, depending on where you're coming from. The easy news to process: the rebase extension enables full git-style rebasing, end of story. You can do an automatic pull and rebase via `hg pull --rebase`, if that's what you want, or you can do more customized rebasing via `hg rebase`. So that's done, and, based on my use in production environments, works very well.
Now, Mercurial 1.1 introduces real lightweight branching--no mq hackery--via an extension called `bookmarks`, which ships with Mercurial. These provide identical capabilities and benefits as git's local branches. The complicated discussion we can have revolves around bookmark semantics. bookmarks, like git branches, are basically "floating tags"--tags that mark a head in the repo's DAG, and that move with that head as you issue additional commits. The difference comes from the fact that bookmarks very directly expose what's going on, whereas git's branch command hides what's going on behind what I personally feel is a more intuitive UI. So, the argument is: is exposing what's actually going on better, because it gives you more power; equivalent, since the functionality provided is identical; or worse, because too much implementation is exposed in interface. I personally need more time to sort out preconceived bias of what micorbranching should look like, from the bookmark extension in particular.
Just to be clear - this does not have identical capabilities and benefits to gits branching model.
For one, it does not appear that you can push these branches, which means that you can't work on topic branches with anyone else.
Second, you can't _not_ push commits you have made under another 'bookmark' - in other words, you can't branch to try out some stuff, switch back to your main branch, do a fix and then push, without everyone getting all the crap in your 'try-out' branch. It may not be in the code that is checked out, but it is in the history, which does not look like it can be removed easily.
Also, it's awkward to use - you can't be working and then just create a bookmark, work some more, then go back to where you diverged easily - you have to create a new bookmark at the diverge point, which you have to look up. If you try to create two bookmarks at the same time (so one will stay where you where and the other will move forward) it will (for some reason) move both bookmarks forward (which is pretty confusing).
Apparently, the only way to _really_ do what git does with local branching is to do what the hg book recommends, which is to do a local clone. This takes orders of magnitude more time (depending on the repo), doubles the space taken up on disk and clutters your disk with a bunch of directories.
It may be slightly better than the local branches in hg in that it isn't recorded in the commit itself, but 'bookmarks' are very much not git branches.
Ok, a question from a darcs guy who recently switched to hg:
What are the use cases for rebase and lightweight branching? I really don't understand why I should prefer rebase to simply pull + merge. Also, is lightweight branching just a performance hack, or is there more to it?
Rebasing avoids cluttering up your history, and can help make your patches more useful. Instead of showing a fork in your history, followed by independent development, and then a merge, you instead show your branch applied to the tip of the other branch/repository, as if that had been your intention all along. This can result in more meaningful changesets as well: if a change upstream forces some changes to my new feature's code, it will be more useful for reviewing my feature if I rebase my changes so that they incorporate that slight fix. This is superb when you're keeping a fork of an open-source project, and have a collection of patches you want to keep applying cleanly to the remote software, for example.
In my opinion, lightweight branching is mostly just a performance hack--and since Mercurial already did cloning with hard links on a local file system, you've been able to get the same performance benefits since before Mercurial 1.0. I do think it's worth understanding, though, that there's also a UI benefit to making building throwaway branches really easy, and I think it's silly to discount that purely because it's a user experience benefit. That's why I do think that having the bookmarks extension in Mercurial 1.1 will be a very good thing.
In git, a use case for rebase that I'm intimately familiar with is interoperability with SVN. You can maintain a branch that's a mirror of an SVN repository, but if you do any merging and then try to check the results into SVN the result is a train wreck. In the somewhat acid words of the git-svn manpage:
Running git-merge or git-pull is NOT recommended on a branch you plan to dcommit from. Subversion does not represent merges in any reasonable or useful fashion; so users using Subversion cannot see any merges you've made. Furthermore, if you merge or pull from a git branch that is a mirror of an SVN branch, dcommit may commit to the wrong branch.
The proper technique is to make a branch based on your SVN repo, make a bunch of changes on the branch (using svn rebase to keep your development branch in sync with changes on the SVN master branch, and -- god help us -- diff-and-patch if you have to merge in changes from some other git branch; this is your penance for working on an SVN-hosted project), then commit the whole thing back to SVN once you have it in shape. It sucks compared to true-blue git but is still nicer than SVN, because (e.g.) you get things like...
... the other use case for rebase, git-rebase --interactive, a.k.a. "take the last N commits and let me reorder, combine, and edit them however I want." I love this feature. See:
I'm not going to try to sell you on Mercurial vs. git, mostly because I think that argument is pointless, but just so you're aware, Mercurial also supports reordering and combining patches via mq. And that's an area where I personally feel that Mercurial's method actually makes more sense than git's, though you're welcome to disagree.
[Edit: Oh, and: yes, that's a perfect example of where rebasing makes sense, and is exactly the kind of rebase operation Mercurial now fully supports, without any complicated patch wrangling.]