开发者

how can I work on both default and branch at same time in Hg?

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 just hg 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜