tags:

views:

434

answers:

3

How would you use Mercurial for the following problem.

Suppose I have a library Core. I now want to develop an extension to that library called Extension. I want to keep Core physically separate from Extension, i.e. let's say that Core is an open source library and Extension is a private library that builds on Core (maybe it contains some stuff I want to keep personal. Whatever.) . Obviously I don't want to push the whole source in Extension to the public repository ever. But on the other hand I might want to push certain changes from Extension to Core (if I would decide to "donate" part of the Extension to the Core) or vice versa (if I want to incorporate bug fixes, say).

How would you go about this, minimizing the risk of leaking Extension to Core (once the history is pushed to the public server, there's no going back!), while staying flexible to do this for certain changes. Branches? Clones? Mqs? Something else?

I'm currently only familiar with cloning repositories, and very much like its simplicity.

EDIT: I came up with this scheme, but I can't quite get it to work under windows. Two repositories (Core and Extension). In Extension there are two branches, also Core and extension. Now, you can register per repository a hook in Mercurial, so I'd like to register a 'pretxnchangegroup' hook in the Core repo that disallows checkins from the Extension branch, as sort of explained in the Mercurial book. Except I don't quite get that to work under windows. So:

  • anyone have an example of something like this (in fact, any hook that changes the outcome of a transacion) under windows?
  • I'd still be able to use transplant to cherrypick changes from the Extension to the Core branch, right?
+1  A: 

(once the history is pushed, there's no going back!)

sure there is... that's what version control is all about!

I haven't done anything like this before, but it sounds like the transplant command will be helpful. Also, you can have clones of clones, and push to any of them, et cetera.

nlucaroni
I mean: once it is pushed, it is near impossible to take it back from the server. So the code I'd like to keep private is now shared with the world.
Kurt Schelfthout
Good tip about transplant, though.
Kurt Schelfthout
yeah, this is true, but you want forests too (as mentioned)... i always forget about them in mercurial.
nlucaroni
+1  A: 

The Forest extension allows you to keep several repos as part of a big one. Sounds like that could help out here.

Marcus Lindblom
Didn't know that, but I'm unsure how it could help. Seems like it's more geared to a situation where I'd have a lot of public repositories that I may want to push/pull at once. That just seems to increase the risk of pushing to the public server accidentally.
Kurt Schelfthout
It helps you to keep private and public code apart, but in sync. There's no risk of pushing changes between repos in a forest.But you want to keep Core as a pure subset of Extension? That would be trickier. :-|
Marcus Lindblom
A: 

After some testing, I'm going to try this scheme. Two main repositories and two named branches, Core and Extension.

One main Core repository, which should only contain Core changesets and source. It should thus contain only changesets from the Core branch. This is checked using the following repository hook in hgrc of that repo:

pretxnchangegroup.branch = hg heads --template "current branches: {branches} " | find "Extension" && exit 1 || exit 0

Looks a little weird, but basically it gets fired after a push or pull is completed, but before it is committed. At that point, if the hook fails, the transaction is rolled back. So the hook looks for a changeset of the Extension branch and fails if it finds it - effectively prohibiting Extension changes to enter the Core repo.

The second repo contains both Core and Extension branches and changesets, and is where changesets get exchanged between the two branches. Normal merge from Core to Extension, and transplant from Extension to Core.

hope this helps someone else.

Kurt Schelfthout
Robert S.