Sunday, December 17, 2006

Branch inheritance explained

Since we started working on Plastic SCM, we wanted branch management to be a center piece. That's why we didn't walk the easy path and we didn't implement path space branching.
To be able to have really flexible branching we had to make branches first level players, and not some sort of directories like happens in many other version control systems (and basically this is what path space means). Every revision of a file or directory in Plastic has an associated branch. Simply put: revisions reside on branches.
But I'm not writing about the basic branching operations but about one of the really powerful new features Plastic includes: branch inheritance. In Plastic you can create a branch as a child of some other branch, creating a whole branching hierarchy.

Ok, but let's go step by step. Suppose you have four files on your system, all of them created in the main branch. Files can have as many revisions as you need to in the branch, as a result of several check out / check in cycles.
Note:for clearcase users: the main branch in Plastic is not the same as the main branch in clearcase. In clearcase every item must have a revision on main. This is not the case in Plastic, where the main branch is just a regular one, with only one special feature: it is created during repository creation.
Creating a branch in Plastic is a really inexpensive operation because it just creates a new repository object, no metadata is copied, nothing special happens.
So we can create a child branch of main named br:/main/child. You can use the GUI tool or the command line to create it.
cm mkbr br:/main/child

So, what's on the branch if nothing else happens during branch creation. Well, if the newly created one is a child of another branch, it will actually inherit the contents from its parent. The second image shows the situation. If you look at the main branch you will see there are four revisions on it (depicted as small cubes). But the child branch represents its content as circles, why? There are no revisions on the child branch yet, but if you select
it on your workspace you will get four files downloaded. How does it work? The system will take a branch and try to download its revisions, if no revisions are found, it will go to the parent branch. The third figure shows both the relationships between the real revisions on the main branch and the virtual ones at the child branch. It also shows what gets downloaded to the workspace, and how its associated selector looks like.
The selector actually tells the system to take the latest revisions from branch /main/child but due to branch inheritance it will also look at /main when no revision is found at the child.
The next step would be modifying a file on the child branch. We would check it out, modify it and check it back in onto the /main/child branch. Suppose we do that with the file Bar.h. Now there is a revision on /main/child so, what the same selector would download? The last figure answers the question. It will take the revision of Bar.h located at the /main/child branch, but the rest of the files will come from /main. You will notice that branch inheritance is a step ahead, opening multiple possibilites. We used inheritance internally for months to implement the branch per task pattern. This way, instead of specifying multiple selector rules, we just had to say a given task branch was child of the project's branch.
But branch inheritance is also key for some other practices like change propagation on a branch hierachy. Suppose you have a branch to handle some project's status. Then you make some child branches to make specific modifications to customers, but you still want the parent branch to receive mainteinance. You can easily have the changes made on the parent one be propagated to the child ones specifying the correct selector (actually the same we were using for the sample). (Note: obviously when a file or directory has been changed in the
child branch, changes in the parent won't be propagated unless you force a merge operation).
Currently our branching mechanism is powerful enough to support the branching pattern you want, and inheritance is not only useful today, it opens up new possibilities that we will be including in coming releases like streaming.

4 comments:

Anonymous said...

Continuing on your example, what happens if you create a new version of foo.c on the main branch? Does a checkout of the child branch see the new version of foo.c or does it see the older version of foo.c, which was current when the child branch was created?

pablo said...

Hi,

That's a pretty good question actually.

My answer is: it depends on the way you create the branch.

Let me explain: when I wrote this long ago, the new version of foo.c would come to the branch (typical branch inheritance), unless the selector tells something different, of course.

But now plastic implements smart branches which basically let you tune inheritance:

- if the branch inherits from "LAST" on its parent, then the new foo.c will come

- if the branch inherits from a certain changeset, the inheritance is "fixed", so the change won't "flow" into the child

- if the branch inherits from a label, the inheritance will be fixed (like with changesets) unless the label gets moved

I don't know whether I was able to solve your question. If you want to know more about branch inheritance, selectors and so on, drop me an email and I'll send you a presentation I normally use during training to explain the whole thing...

Ken said...

Seems pretty powerful and flexible. I wish our SCM software could do that. Sure I would be interested in your presentation. Does PlasticSCM handle requirements management and traceability in any way?ktlb06@gmail.com

pablo said...

Ok Ken,

I'll drop you a line