At work we use Mercurial. I don't know that we will keep using it as we are a rather global company and some of the other teams don't have the time adopt a new VCS that is much more complicated than existing systems. Despite mercurial's mixed reviews among the team, I'm becoming more of a fan. I can't say I'm really a fan of mercurial per se, but it is becoming clear how a DVCS is beneficial in a more intimate way. There are the traditional arguments surrounding things like "commit on a plane" and "branching made easy" but I don't think people totally see the impact until they really have to work with a tool like mercurial for an extended period of time. It doesn't mean it's easy by any means, but after a while there are definite advantages.
One of the benefits of a DVCS is the ability to take a set of changes and place them in another branch. This is not as simple as it sounds. There are a suite of things to consider and even more potential data to keep track of. Where did the patch come from? Can you revert the changes to a different version that existed before the current version was added? If it is a set of patches or changesets, do you get to revert specific changes or is it an all or nothing kind of operation? Is there now a permanant link between the two branches/tags/heads after copying over the changes? How would that even work?!
When you start limiting things a bit, the idea becomes manageable. Mercurial has a plugin called transplant that makes some decisions. You don't necessarily get massive amounts of information which makes it relatively simple to move changesets around without much hassle. It also moves the changeset around as an atomic entity, which means that after you've transplanted, you don't need to commit or add a message saying you transplanted things. All in all, it is pretty easy once you get the hang of it.
To do a transplant first you need a repo. We are going to do everything in place, which means we are not going to clone to another directory, creating an implicit new branch.
elarson $ echo 'print "hello world!"' > hello.py
elarson $ hg add hello.py
elarson $ hg branch 1.0
marked working directory as branch 1.0
elarson $ echo 'print "goodbye world!"' >> hello.py
elarson $ hg st
A hello.py
elarson $ hg ci -m 'ended'
elarson $ hg id
020db5c02665 (1.0) tip
elarson $ hg branch 2.0
marked working directory as branch 2.0
elarson $ echo 'print "wait... ah nvmd"' >> hello.py
elarson $ hg ci -m 'nvmd'
elarson $ hg up 1.0
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
elarson $ echo 'print "talk to you again later"' >> hello.py
elarson $ hg st
M hello.py
elarson $ hg ci -m 'tty'
created new head
elarson $ hg id
65a5be09f306 (1.0) tip
elarson $ hg heads
changeset: 2:65a5be09f306
branch: 1.0
tag: tip
parent: 0:020db5c02665
user: Eric Larson <eric@ionrock.org>
date: Mon Feb 09 21:10:41 2009 -0600
summary: tty
changeset: 1:93127fc79160
branch: 2.0
user: Eric Larson <eric@ionrock.org>
date: Mon Feb 09 21:09:38 2009 -0600
summary: nvmd
elarson $ hg up 2.0
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
elarson $ hg transplant -b 1.0 2
applying 65a5be09f306
65a5be09f306 transplanted to 9cbf35e4f623
elarson $
In the example we made two branches and both had some work in them. In the real world, this is as if you are working on a new release (2.0) and you fixed a bug in a previous release (1.0) that you need to forward port to your new release branch. If there were a series of commits you'd just do something like hg transplant -b 1.0 3:5 7. That would transplant the changesets 3 through 5 and also changeset 7. If there are conflicts you will get to merge as usual. For example, if you use Emacs (really, what else would you use?) ediff should come up with the merge interface and you can move along.
Also, I should mention there is something to be said for being able to work in the same directory all the time. As a Python developer, I use virtualenv, but for day to development, it can be much easier to just keep your system some what bleeding edge and only use virtualenv's for specific projects or sandboxes. It is nice to have your server running, hg up to some branch to test and see your server restart and be ready to go. It is a small issue, but once you get used to it, it is pretty convenient.
If you are using mercurial I hope you spend some time trying to learn the more detailed aspects of it. The concept of heads, while trying, is pretty helpful at times. There are also a host of plugins that can be helpful. For example, Mercurial Queues is one that consistently comes up when comparing Git and rebasing. I've found queues to be extremely confusing, but transplanting has worked for me. There are also other plugins like Local Branch that seem pretty nice. A DVCS raises the complexity bar in terms of possible work flows, and there is a pretty good chance that whatever DVCS you choose, there should be a way to make it work. For me, transplant works.