Branching, Merging and Dot Notation

This topic explores the concepts of branching, merging and dot notation as they relate to StarTeam.

Branching Allows an artifact’s version stream to be forked. Each fork can be independently modified, receiving its own versions.
Merging Propagating a change on one branch to another branch.
Dot Notation A dotted decimal notation assigned to artifact revisions to indicate both the branch on which the revision resides and the relative version number of the revision within the branch (for example: 1.4 or 1.2.1.5).

About Branching

There’s a big difference between copying an artifact and branching an artifact. Although copying allows each copy to be modified independently, it is not known how copied artifacts are related to each other in the repository. In contrast, with branching, special knowledge about an artifact’s branches is retained. This information supports things such as intelligent revision comparison and three-way merging.

When a new artifact is added to the repository, a main branch is started and new revisions are added to it. At any time, a parallel child branch can be started. In the example above, one child branch is created from main branch version 1, and another child branch is created from main branch version 2. Within a branch, the version number starts over (at zero in this example). New revisions are applied to a specific branch, incrementing the version number on that branch but not affecting other branches. Branching is needed to support parallel development on files. However, there are advantages to allowing non-file artifacts to branch as well. For example, if a defect artifact can be branched, the two branches can be used to track fixes to the same defect that exist in different releases.

Back to top

Merging

Inevitably, a change on one branch will need to be propagated to another branch. In the diagram above, version 3 of the artifact on the lowest branch is applied to both of the parent branches. However, you can’t just copy a revision from one branch to another branch—this could wipe out changes that are specific to the target branch. Instead, what you want to do is merge the changes from the source to target branch.

Note: Overwriting the target artifact with the source revision instead of merging it is sometimes the desired effect, for example with binary files.

More specifically, StarTeam stores synchronization information that allows three-way merging. The three parts of a merge operation are:

  1. The source revision containing changes to be propagated.
  2. The target revision that will be modified.
  3. The last source revision common to the source and target branches, known as the common ancestor.

For files, merging is done by passing these three file revisions to the StarTeamFile Compare/Merge tool. The tool compares both the source revision and target revision to the common ancestor revision and determines two important things:

  1. What changes appear in the source revision only that should be propagated to the target revision.
  2. What changes appear in the target that may conflict with changes in the source revision.

In many cases, merging detects no conflicts, so the StarTeamFile Compare/Merge tool automatically propagates the source changes to the target revision. When conflicts are detected (and sometimes even when none are), the StarTeamFile Compare/Merge tool displays the differences to a user who can review the differences, resolve conflicts, and approve the final result. The StarTeamFile Compare/Merge tool then creates a result file reflecting the target file updated with changes. StarTeam adds the result file to the target revision’s branch, creating a new revision.

In the diagram above, revision 3 on the lower child branch was merged to both of the upper branches. When it was merged to the main branch revision 3, it created main branch revision 4, which contains the merge results. (The arrow points to the revision that was created as a result of the merge.) For this merge, the common ancestor between the two branches is main branch revision 2: it is the most recent revision that both branches had in common. When the lower child revision 3 is merged with upper child branch revision 2, upper child branch revision 3 was created. For this merge, the main branch revision 1 is the common ancestor.

For files, there is more to merge than contents: files have other properties such as name and description. In order to propagate a name change, for example, merging a file requires merging these properties as well. Non-file artifacts that branch also require merging in order to propagate changes.

Back to top

Dot Notation

In addition to a version number, each revision is assigned a dotted-decimal value called a dot notation. Whereas the version number is unique within a revision branch, the dot notation value is unique within the entire revision tree. An example is shown below.

As shown, revisions on the artifact’s main branch use the single dot notation pair 1.n, where 1 indicates that it is the initial (first) branch and n is the same as the version number. When the artifact is branched from the main branch, revisions on the child branch use the dot notation 1.m.1.n, where m is the main branch version number from which the branch was created and n is the version number on the new branch.

Note: An artifact can branch more than once from same point: in the example above, branches 1.2.1.n and 1.2.2.n were both created from main branch revision 1.2. The second 2 in 1.2. 2.n tells you that this is the second branch from revision 1.2. Branch 1.2.2.1.1.n has three pairs of numbers, telling you that it is a third-level branch, created from parent revision 1.2.2.1.

Artifacts that can’t branch (tasks, topics, and requirements) are always on the main branch, so their dot notation is always 1.n.

Object IDs and Root Object IDs

All revisions in the same revision tree have the same root object ID (root OID). All revisions that belong to the same branch have the same object ID (OID). Furthermore, for all revisions on the main branch, the object ID and root object ID are the same. This is illustrated below.

In this example, the file foo.java started with OID and root OID 123, and the corresponding 1.n branch has revisions up to 1.2. At revision 1.1, it branched to form the 1.1.1.n branch, which uses the new OID 311. Revision 1.1.1.2 was branched to form the 1.1.1.2.1.n branch with OID 875. But all revisions in the entire branch tree have the original root OID 123. Each revision holds the properties specific to it: name, description, contents, etc.

Also shown is a change request (CR 413) that began with OID and root OID equal to 400. At revision 1.2, it branched to form branch 1.2.1.n with OID 573.

Now, consider a folder artifact. Each revision holds properties such as name, description, and exclude spec (file patterns to ignore within working folders). What’s really different about StarTeam folder artifacts is that they do not have a property that represents their contents.

Back to top