'Selective' branching of files: is it possible in Mercurial?

Vladimir makhnich at gmail.com
Sun Mar 15 09:21:15 CDT 2009


Hello,

I would like to know whether it is possible to make several files in 
repository to be "branched" (i.e. exist on several branches), while the rest 
of files are in sync with default branch (and have only one "head" revision).

Google gave me no answer, neither did Mercurial documentation. In fact, I 
suppose the answer is 'no', but may be you will offer some tricks.

I will try to explain the problem.

Let's assume we have a large project, and there is some component that have 
two diverged versions (e.g. it's graphic component, and one version is faster 
and another is smoother). The interface (I mean public methods) of both 
versions is the same, so all other modules of the project do not depend on 
what component version is now in use. And let's assume we have a team of 
developers, some of them use the first version and some of them use the 
second, and most of the time they work on the common part of the project, but 
sometimes one or another version of the component is also updated.

What the developers want is to see changes of each other if the changes have 
been made to the common part of the project, and to see changes of the 
component only if the changes were made to a corresponding component version.

For example: let us have 2 files, component.c and main.c. At some point there 
appeared two diverged lines of component.c, let's name them component.c(A) 
and component.c(B). The common part of the project resides in main.c.

Let us have three developers, and they are using different version of 
component.c:

Alice: component.c(A), main.c
Bob: component.c(B), main.c
Tom: component.c(B), main.c

Suppose Alice has changed main.c. How can Bob fetch this changes? 'hg update' 
will try to merge different 'component.c' versions. And vice versa: Alice 
cannot update from Bob's branch without messing her component.c version.

Well, we can try to forbid changing local component.c during merge. For 
example, Bob can set merge options in hgrc file so that "internal:local" will 
always be used as a merge rule for component.c. So Bob's component.c will 
never suffer from Alice's version. But that's not what we want. Suppose that 
Tom fixed some bug in component.c(B), and at the same time Bob slightly 
changed his component.c(B). How can Bob fetch Tom's changes? Bob's "merge" 
will discard all the work Tom has done.

Playing with 'transplant' extension also doesn't solve the problem: well, Bob 
and Tom can 'transplant' from Alice only changesets that do not touch 
component.c, but (if so) they will need to look through each changeset first, 
and also there can appear some changeset that contains changes to both 
component.c and main.c

What we want is:

1) each version of component.c lives along its own branch (Alice's 
component.c - along branch A, Bob's and Tom's ones - along branch B), and all 
update/commit commands for the component.c work with corresponding branch;

2) main.c lives along SINGLE branch, and commit command doesn't create a new 
head in case if Alice first commited and pushed her version of main.c, and 
then Bob pulled-updated-changed-commited his new version of main.c . Though 
Alice and Bob uses different branches for component.c, they want to use the 
same branch for main.c.

In Borland Starteam, there is a possibility to make some files to be identical 
along different branches, while allowing other files to exist in "branched" 
state. More exactly, for such files one of the branches simply contains a 
link to an object at the another branch - and all changes to that file are 
visible from both branches. Is it possible to get similar behavior in 
Mercurial? Or, if not, how should Alice, Bob and Tom act? Moving component.c 
into a separate repository is not very convenient.

Thanks in advance.

  Best regards,
    Vladimir.


More information about the Mercurial mailing list