Reputation: 3327
There are numerous discussions here that have addressed issues that seem related to this question, but nothing has really answered it directly. Basically, using Mercurial, I want to be able to work on multiple, independent tasks within the same project, at the same time.
For example, I'm simultaneously tasked with bugs X & Y. I work on X for a while until I hit a point where I need to put it on hold for a few days. Say I need input from someone else who is out of the office. So I want to move on to working on bug-Y. Clearly, one option is to just create a new clone of the stable repository. The problem is that requires a new working directory, new Eclipse project, yada-yada... I'd like to be able to keep one working copy.
With SVN I could create a new branch in the repository for each task and just switch my working copy between them. With ClearCase I could create a new activity for each one. In both cases, I could work on each task independently, in clean environment. Then when I'm done with a task, I can commit/push just that one to the central repo.
I've read about Hg named branches & bookmarks. I'm sure that somewhere in there there's a solution to fit our workflow, but I'm not seeing it yet. Can someone explain the steps I can use to achieve this? Is it possible to create two heads in my local repository that I can just switch between? And then update/commit/push/pull those heads independently? In practice I might never even merge them locally, just push each one to our stable repo when it's ready. Am I just thinking about this in entirely the wrong way? I'm very new to Hg (and DVCS's in general) and trying to develop a workflow for it.
Upvotes: 4
Views: 2228
Reputation: 12182
When working on multiple tasks/bugs, I prefer using bookmarks over named branches. They do not clutter your history with branching info (but this may be a personal preference).
You normally just work on the default branch. To keep track of this "main line of development", we create a bookmark named "master" (or however you'd like to call it). Now before you start working on bug X, you create a bookmark "bugX".
You then must work on bug Y, because you have to e.g. wait for input of someone else. To do this, you first go back to the master bookmark (where you left the "main line"), create a new bookmark for the bug Y and start working on it.
You also have to stop working on bug Y now and you want to continue your work on the "main line". You first grab the newest changes from the central repo and then start working on the master branch. When the feature is finished, you can push it. Be sure to only push the master branch with "hg push -r master":
Sometime laster you can finish bug X:
This bugfix must now be brought into the master branch and be pushed to the central repo. You could merge it with "hg merge bugX" or even better - rebase it. When everything is done, delete the bugX bookmark:
"hg bookmark -f master" is needed to let the master bookmark now point to the last changeset of bugX that has been rebased on top of the master branch (I think this is done automatically with mercurial 2.1).
The same procedure can now be done with bugY and you end up with a straight line history.
In a team, you could even consider pushing the master bookmark to the central repository so that it has not to be maintained after pulling (hg push -B master).
This workflow also is described more or less in this blog post.
Upvotes: 1
Reputation: 73768
I wrote a guide about using named branches for tasks that you might find useful. You write in your answer:
Here are a few gotchas I found:
- Merge your feature branch back onto 'default' when your ready to push - you can't just push your branch to the remote repository
You need to hg push --new-branch
when you want to allow Mercurial to create a new named branch in the remote repository. This is because branches are global and long-lived — so you should not just create them with temporary names.
- When you push make sure you select to only push the 'default' branch - if you don't it will try to also push any other feature branches that have not yet been pushed
You can use hg push --branch X
to only push branch X
(and any ancestors, of course).
- Hg will complain that your push is creating new remote branches - that's ok as long as the branch is already merged locally
Actually, merging it locally has nothing to do with this message — it comes every time you introduce a new branch and it's not important if it's merged or not. Named branches are really the tool you use when you want to have multiple heads in a shared repository. By naming the branches, you avoid confusion when people pull and update: hg update default
will still give you the main line of development even though there might be a X
branch with highly experimental and unstable code.
Upvotes: 1
Reputation: 3327
Ok - so I think I've figured this out. I think I'll be using named branches. Thanks for everyone's help.
Here are a few gotchas I found:
If anyone looking at this has further comments and/or suggestions I'll be glad to hear them. I'm not 100% satisfied with this solution yet.
Upvotes: 0
Reputation: 26597
The process you're describing is really simple to implement with Mercurial, and there's many way to do it.
For example, you can use anonymous branches :
You just created two anonymous branches in your working copy starting at the decided changeset.
You're absolutely not limited to the number of anonymous branches or their starting point, you can even create new anonymous branches on your anonymous branches.
In some cases, tools like TortoiseHG or the the GraphLog extension can really help you understanding which are the parents of each branches and what's the best way of merging them back.
Bookmarks are only a way to easily keep track of various changeset, you can put bookmark on each of your new heads. Depending on the version of Mercurial you're using, the bookmark will "follow" each new commit you make in its particular branch or not.
You can also use named branch to achieve the same purpose, but the problem is you can't easily delete a named branch after it's been created, the name will still be their.
PS: this workflow, or something very similar is described in the following blog post : http://stevelosh.com/blog/2010/02/mercurial-workflows-branch-as-needed/
Upvotes: 3
Reputation: 852
I generally just go ahead and create named branches for any sub-project or non-trivial bug fix. You can switch back and forth between branches easily with 'hg update'. When I'm done with something, I just merge it back into default.
Here's an article with some good info on branching in Mercurial: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
Upvotes: 1