I'm working at a company that is using CVS, so HgSubversion wasn't an option. I had the same question a few days ago and developed a workflow based on this:
http://momentaryfascinations.com/programming/how.to.use.mercurial.for.local.source.code.management.with.a.public.subversion.server.html
I created a Mercurial repository where my CVS repository is, which I treat as "readonly". I then clone this "readonly" hg repo to working repositories, where I make changes/fixes locally. I have been cloning the repo for every feature and fix that I make, but you could also just have one repo, and use a different branching strategy to manage your development. Here's a good overview of such strategies.
The key to this workflow is having that "readonly" repository. I used to make my changes in the first Mercurial repository I created, which was on top of CVS. This worked, but it got confusing when updating from CVS. By having this additional layer, you can deal with making your own changes and updating from CVS separately.
Keeping in sync with CVS
Whenever there are changes in CVS, I do a cvs update. To the "readonly" hg repository, this will show up as modified files. To sync up Mercurial, I simply do a
hg ci -m "Updated from CVS."
(So, you'll see a lot of those messages in my hg logs). At this point, my "readonly" repository is sync'ed with CVS. Now I can go to any of the repositories I've cloned and issue a hg pull
and then hg update
to sync them up.
Committing changes from hg back to CVS
Going the other direction, when I want to commit to CVS, I'll go into one of my working repositories where I've committed my changes already to hg. Then I hg push
my changes back to "readonly", hop over to the "readonly" repository, do an hg update
. From CVS's perspective, this will appear as freshly modified. I then do a cvs commit
back into CVS. Here I'll have to repeat/summarize in my log message the work that I've done in my hg repository.
Admittedly, there are rough spots in this workflow. You could be making multiple changes in hg, which add up to just one change in CVS/SVN, so that history will not be kept in CVS/SVN, and you'll have to summarize your commit messages. You have to manually manage keeping CVS and your "readonly" repository in sync. The advantage of this is that you don't need to install any additional extensions - you are just dealing with the files themselves from both perspectives. Everything that is happening is pretty transparent and under your control.
I'm still cutting my teeth on hg, but so far this workflow has been working out reasonably well.
Harvey has provided a nice diagram of this and makes an excellent point that this workflow applies to any other VCS: