similar lines of development and pull access control

Martin Geisler mg at daimi.au.dk
Tue Feb 3 02:39:06 CST 2009


Dexter Douglas <luomo1138 at yahoo.com> writes:

Hi Dexter

> I would like to create a repository with two lines of development
> that are related, so I can merge changes between them both.  I have
> a project that consists of code that I am able to share with others
> plus code that due to contract I am unable to share.

There are at least two ways to do this with Mercurial.

The first solution that came to my mind is this: First import your
public core code in a repository, call this "public". Then make a
clone of "public", calls this clone "everything". In "everything" you
import and commit your secret code.

You must then carefully decide where to make each change: changes to
secret code must of course be made to the "everything" repository, and
changes to the public code should go into "public". You will be able
to pull changesets from "public" to "everything" and by doing this you
will always make sure that "public" is a subset of "everything".

You wont be able to directly pull selected changes from "everything"
to "public", since pulling a changeset will always pull all ancestor
changesets as well. If you happen to make a commit in "everything"
which should have gone to "public" instead, then use the transplant
extension to apply the changeset to "public".

The development of Mercurial uses this technique -- not with public
vs. secret code, but with bleeding-edge vs. stable code. Important
bugs are fixed by changing "hg-stable":

  http://selenic.com/repo/hg-stable

and these changes are then immediatedly pulled into "hg":

  http://selenic.com/repo/hg

You will notice that "hg-stable" is a subset of "hg".

Once in a while a changeset goes the other way via the transplant
extension. This is when a bugfix was made to "hg", but it is later
deemed safe or important enough to be promoted to "hg-stable".


Another option, which might be simpler for you, is to simply use two
separate repositories: "public" for the public code and "secret" for
the secret components. Then instead of an "everything" repository,
those with the right priviledges will simply checkout both "public"
and "secret" and use them to build the software. To better emulate
your SVN repository, you can place "secret" within "public" and hg
will simply ignore it:

  public/.hg
  public/foo.c
  public/foo.h
  public/secret/.hg
  public/secret/secrets.txt
  public/another/directory/in/public/hello.c

When you use hg inside the public/secret directory, you will effect
the "secret" repository. And when you use hg in "public", but outside
"secret" you only effect the files in "public" -- there is no
recursion going on like in Subversion. (But work is under way to
support nested repositories, see http://hg.piranha.org.ua/subrepo/)

This way there is no risk of committing a fix in the wrong
repository. But you will end up with two repositories, each with their
own separate history -- if you change something in "public" and this
requires a change in "secret", then you wont be able to commit these
changes in one atomic commit. Instead I would commit in "public" first
and then commit in "secret" with a commit message of "Synchronized
with public dfe90d9f4659" where dfe90d9f4659 is the changeset just
committed in "public". This approach is no different from when an
application (the "secret" repository) depends on a library (the
"public" repository) with a changing interface.

-- 
Martin Geisler

VIFF (Virtual Ideal Functionality Framework) brings easy and efficient
SMPC (Secure Multiparty Computation) to Python. See: http://viff.dk/.


More information about the Mercurial mailing list