tags:

views:

49

answers:

4

What is a good workflow for using mercurial with two long-running branches that are slightly divergent (i.e. I never intend to entirely merge them back together)?

In my case, this is CMS software that has been customized differently for two different web sites. I started with projectA, and once that was working cloned it to projectB and make further tweaks to both A and B to customize them. Now I want to develop some features that show up in both A and B, without merging the site-specific customizations. How?

hg push will push everything, so that won't work
Transplant appears to give me different changeset hashes, which worries me

I feel like maybe the repositories should be set up differently, but I'm not sure how.

+3  A: 

As Thilo comments, the common part would be best developed (and published in A and B) as a third repo declared as a SubRepo.

That way, you respect the first two repos which are independent (one evolution on A doesn't always mean an evolution on B), and you can develop the common part in subrepo C.

VonC
comment -> common?
Geoffrey Zheng
@Geoffrey: right. I have fixed that typo (and a bunch of others as well)
VonC
In theory I like this answer. In practice, I have two concerns: First, subrepos feel complex. I find things like `hg -R nested update; hg ci` very strange (that actually makes a changeset in the outer repo).Second, I currently have two top-level directories: server and tools. Each of them has some common code, so I think I'd need four repos total (`tools/common` subrepo, `server/common` subrepo, plus `A` and `B`).Maybe I should write a deploy tool so I can have a single common subrepo for server and tools. (I'm using app engine, which really wants all the server code in one directory)
Mark Ivey
@Mark: the complexity comes from the fact a subrepo needs to be referenced by its parent. Any change in the subrepo will be committed first, before the parent commit itself (with a reference to the new state of the subrepo). But that ensure both parent and subrepo can be developed at their own pace (an evolution in parent won't always involve an evolution in '`common`'). As for the 2 '`common`', they could indeed be *two* subrepos. The question, again, is their relationship: if a modification of `tools/common` doesn't mean a modification on `server/common`, then 2 subrepos make sense.
VonC
A: 

A solution for Mercurial might be if you can put the different areas in files that can be in .hgignore, but then they won't be versioned, so that may not be so good.

Another way is to just use 1 repo, and set a global flag, and use template A or B depending on the flag, and / or include different code source file depending on the flag. If the difference is small, then can use if-then-else inside the same file.

動靜能量
A: 

You can use hg push to push the changes back together, but you don't necessarily have to merge all the changesets into the trunk. Just take the ones you want.

Avi
A: 

As stated above, a subrepo is probably the best option. Another alternative would be to have a third branch with the common work, and merge from that branch to projectA and projectB (but never back to the common branch).

This alternative is more likely to have accidents (merging the wrong way) but you might find that it is easier to set up and get working quickly.

Tim Delaney
That sounds pretty easy, but I know I would eventually `hg push` things the wrong way. I tested this out, and as long as I catch it right away, I can `hg rollback` in the common branch, but I still think I'd end up messing it up eventually.
Mark Ivey
You can reduce the possibility of this happening by making each branch a named branch, rather than just being in separate repositories. Then you need to explicitly hg merge between the branches. You could also set up hooks in each repository to reject merging in the "wrong" direction.
Tim Delaney