OK, I'm new to Mercurial and version control branching in general, so I may have a fundamental misunderstanding of what's going on here -- please be kind... ;)
We are a small development team (2 developers) working on a project, and we have a need to implement a fairly significant change that may take weeks or months. At the same time, the program is in daily use, so we have a need to make regular patches and fixes.
Because of the long-running nature of the significant change, I created a branch off the default branch (call it dev1). I will want to periodically merge the changes from the default branch into the dev1 branch, for reasons that don't need to be reiterated here. However, I do NOT want the changes from dev1 merged into the default branch until much later in the development.
I have tried several different ways to do this, but it always seems the merge affects both branches. After the merge, if I update to the default I now have changes from dev1 merged into the source.
Can I work on both branches using the same repository? If so, can someone please share the sequence of commands to use? If not, it seems to me I would not be able to push the dev1 branch up to the master repo until it w开发者_高级运维as finished, and that just doesn't seem right.
We are running the latest TortoiseHg for Windows, and for the most part I love the graphical tool. However, I am perfectly willing to drop to the command line to do certain tasks when necessary.
Thanks for any help, Dave
This depends on what sort of branch you've created.
If you have created a named branch, and are working in a single working directory, then you need to use one workflow, but if you have cloned your production repository, you need to use a different workflow.
Named branch workflow, single repo/working directory
In this case, you are using update to switch between the default
branch and the dev1
feature branch.
When you want to work on the default
branch, update to it, do your bug fixes, and commit those changes. Do not merge in changes from dev1
branch.
When you want to work on your dev1
branch, update to it, merge in your bug fixes from the default branch, work on your feature and commit when done.
If you are working on the dev1
branch and a colleague fixes a bug in default
that you need, commit your work, fetch their changes, merge them in and then resume your work (there are shortcuts you can take here, but this way you can backout the merge if it gets messy)
Note: All of these assume that all of your changes are committed at the point you want to switch between dev1
and default
branches.
The important thing to note is that you only get the changes from your dev1
branch in default
when you merge them in. If you only merge default
into dev1
then your feature branch will keep up to date with default
so that when you are ready to deploy the feature into the default
branch, you can do so with one simple merge operation.
Unnamed branch workflow using dev1
repo cloned from production repo
This workflow is similar, but allows you to work on the default
and dev1
branches simultaneously, without having to update to switch between the two.
When you want to work on the default
branch, use the repository where the tip is your production code. Do your bug fixes, and commit those changes just as you would normally.
When you want to work on your dev1
branch, use the repository where the tip is your dev1 feature branch. If there have been fixes in the default
repository, pull in the changes and merge them into your clone, but do not push the merge changeset back. Only push your changeset back when you want to deploy you feature to production code. Once the changesets from default
have been merged in, you can continue working on the feature.
If you are working on the dev1
branch and a colleague fixes a bug in default
that you need, commit your work, fetch their changes from your shared repository into your default
production clone, then pull those changes down into your dev1
feature clone, merge them in and then resume your work.
Again, the important thing to note is that you only get the changes from your dev1
branch in default
when you push them up to your default
production repository. If you only pull/merge default
changesets into the dev1
clone then your feature branch will keep up to date with default
so that when you are ready to deploy the feature into the default
branch, you can do so with one simple push operation.
Yes, you can absolutely do this with Mercurial.
First, in case it isn't clear to you (it wasn't to me for some time), there are 3 types of 'branches' in Mercurial:
- clone a repository
- a 'named branch' (using the
hg branch
command) - an anonymous branch, which you can manage with bookmarks or just remembering the changeset
I'm guessing that you used the hg branch
method. Be aware that this is often not what you want, because that branch name will live in the repo's history forever (well, there is the --close-branch
option, but still...).
The essential workflow is:
- update to dev branch with
hg up devbranch
- commit changes to dev branch
- merge with main branch via
hg merge default
or justhg merge
as desired - (repeat as desired)
And for working on the default branch:
- update to default branch with
hg up default
- commit changes
- (repeat as desired)
Do NOT do this:
- update to default branch with
hg up default
- merge with dev branch with
hg merge
I suspect that you are using the command hg merge
without specifying a branch name. That will merge with any other head, which may or may not be what you want.
Edit: The above info is probably not your issue. Your issue is probably running a merge when your current branch is the default one.
You don't want to run hg merge
from your default branch.
# bang on dev1
# more banging on dev1
# someone beats on default for a while
# update to dev1
hg up dev1
# bring in the changes from default
hg merge -r default
# validate successful merge
hg commit -m "merging"
The key is committing on dev1 when you bring changes over from default.
Note that I'm using named branches here.
This sentence:
After the merge, if I update to the default I now have changes from dev1 merged into the source.
tells me that you're doing something wrong. It is perfectly doable what you want to do, work on two branches in parallel, and merge from one to the other, without influencing both.
It is important to know that the merge is a directional merge. You merge from one branch to the other, and when you initiate the merge, you should be on the to-branch.
directional in the sense that the direction plays a role in the outcome. For the actual contents of the file, it doesn't matter which direction you merge, but the new merge-changeset you commit will be on the branch you was on when you initiated the merge (unless you override.)
So, update to the head of dev1
first, then merge with default
, and after committing, you should have a new changeset on the dev1
branch, but default
should be left undisturbed.
This is more of a tip than an answer, but...
I use this workflow a lot. I find the Transplant extension very useful for named branch workflows. TortoiseHg supports it, so you can enable it in the TortoiseHg options. It lets you cherry-pick from other branches, which is very useful - especially if you regularly commit to the wrong branch.
精彩评论