Here are the proposed merge/join rules for DCMS. DCMS will allow you to generate and apply patches that fall outside of these rules if you wish, but it will treate these as user-applied changes and will not attempt to preserve consistency across repeated merges or joins.
A "merge" takes changes in a parent branch and applies them to the most recent revision of a child branch. An "join" takes changes in a child branch and applies them to the most recent revision of a parent branch. To ensure consistency of the results, integration must occur into the branch before a join is permitted.
3. Merge/join rules:
Using my previous notation, if branch B.1 is derived from trunk T.4, development proceeds, and we are now at B.5 and T.17, then:
Applying delta [T.17-T.4] to branch B.5 is a legal merge. Applying delta [B.5-B.1] to T.17 is NOT a legal join.
The correct approach for performing the second operation is to first merge [T.17-T.4] into B.5 yielding B.6, and then join B.6 to the trunk as T.18.
More specifically, DCMS keeps track of a notion of the "top merge" for each file, which is the highest revision of the trunk that has been merged into that file. A join is permitted iff, for all modified files in the branch, the top merge is the most recent revision in the trunk.
Note that this join policy should eventually migrate to script code.
Note that a join is also a merge. In the above example, when B.6 becomes T.18, the "top merge" for each file in B.6 becomes T.18.
I would be delighted to relax this strict hierarchy. If someone can come up with a branch algebra that can keep track of spaghetti merges I'ld be happy to adopt it. The above rules will ensure correct merge/join behavior. They can be relaxed later.
Meanwhile, is there anything fatal in the above restrictions?