Concurrent Development: Merging Branches
Concurrent development allows two or more developers to work on different versions of an object in separate locations. The following diagram illustrates how concurrent development is managed in Deltanji:
- The object version X.MyClass.CLS/App.6 exists in the library.
- Developer1 checks the object out to the Development Area, creating the new object version X.MyClass.CLS/App.7.
- Developer2 then checks the same object out to the Bug-fix Area, creating the new object version X.MyClass.CLS/App.8.
- Developer2 then checks the object back in to the ForTesting location.
- Developer1 attempts to check the object back in to the ForTesting location too, but the action is not allowed. This is because ForTesting is defined as a single-version location and the version of this object that already exists there (X.MyClass.CLS/App.8) is not an ancestor of Developer1's version. ForTesting is sometimes referred to as a 'merge enforcement point' because it ensures a merge occurs at the appropriate point in the workflow.
- In order to proceed, the two versions must be merged. First Developer1 performs the merge by diffing (comparing) the two different versions (typically using Beyond Compare) and making the relevant adjustments to ensure that X.MyClass.CLS/App.7 (the version currently checked out) contains all relevant changes that were made in X.MyClass.CLS/App.8.
- Developer1 then declares the merge in Deltanji (see below), which creates a new version of the object in the location to which X.MyClass.CLS/App.7 was checked out. The new version, 9, is merely a renumbering of version 8, which ceases to exist.
- X.MyClass.CLS/App.9 can now be checked in. The overall result is that the changes made by both Developer1 and Developer2 are incorporated into a single version in the library. That version has two predecessors and is sometimes referred to as a 'merge product'.
While the diagram above only constitutes a simple example, the same basic principles still apply with more complex concurrent development.
When the same object version is checked out multiple times, each check-out creates a branch. A branch is essentially a record of lineage. As such, Deltanji is able to keep a track of how the same object has been developed in different ways.
In the diagram above two branches form. One has X.MyClass.CLS/App.7 at the tip of the branch, and the other has X.MyClass.CLS/App.8 at its tip.
Unless a transfer route explicitly overrides the constraint, an object version on one branch can never overwrite a version on another branch. Deltanji enforces this by checking ancestry. If the version of the object already in a single-version destination location is not an ancestor of the one that the user is trying to transfer, the transfer will not be allowed.
It usually becomes necessary to merge two branches together at some point in order to integrate the changes that have developed along each branch.
Note: Deltanji does not automatically integrate the changes to the objects' components. Rather, declaring a merge in Deltanji merely creates a new object version that is defined as a successor (child) of both branches. As such, before declaring a merge you must integrate the content of the latest object versions on each branch using an appropriate editing tool.
1. Choose the latest object version from one of the branches. Integrate the changes (i.e. perform the merge) from the other branch until it represents both branches sufficiently.
Note: It may be useful to use the compare function to perform a diff on the two latest object versions on each branch. The "Compare" button on the "Merge Versions" dialog (see Step 2 below) can be used to launch a 3-way merge session in Beyond Compare, the visual diff tool recommended for use with Deltanji.
2. While the object version at the tip of the second branch is still checked out
- EITHER right-click on it and choose Merge Versions
- OR click on it and from the menu bar choose Edit -> Merge Versions