How files and directories are merged

To merge files and directories:

  1. The base contributor is identified.
  2. Each contributor is compared with the base contributor using the DevOps Code ClearCase® merge algorithm. (See the illustration below.)
  3. For any line that is unchanged between the base contributor and any other contributor, the line is copied to the merge output file.
  4. For any line that has changed between the base contributor and one other contributor, the change in the contributor is accepted. Depending on how you started the merge operation, the change may be copied to the merge output file. However, you can disable the automated merge capability for any merge operation. If you disable this capability, you must approve each change to the merge output file.
  5. For any line that has changed between the base contributor and more than one other contributor, you are required to resolve the conflicting difference.

Diff Merge is used to compare contributors and resolve differences. Diff Merge writes the resolved changes to the merge output file.

Three versions are shown. The B version represents the base contributor. Two subsequent versions, the source contributors, C1 and C2, derive from the B version. An equation shows that the destination version equals the B version plus the delta of the B and C1 versions plus the delta of the B and C2 versions.

The merge output file is usually checked in as the destination version in the target stream.

The File merge algorithm

A merge is a straightforward extension of a file comparison. Instead of displaying the differences, Diff Merge analyzes them (sometimes with your help) and copies sections of text to the output file:

  • Sections in which there are no differences among the contributors are copied to the output file.
  • When one contributor differs from the base contributor, Diff Merge accepts the change and copies the modified section of the contributor to the output file:
    
    ------------[changed 3-4]----|--------[changed to 3-4 file 2]---
    now is the thyme                     | now is the time
    for all good men                     | for all good people
                                        -|-
    *** Automatic: Applying CHANGE from file 2 [lines 3-4]
    ============

    (You can turn off automatic acceptance of this kind of change.)

  • When two or more contributors differ from the base contributor, Diff Merge detects the conflict, and prompts you to resolve it. It displays all contributor differences and you can accept or reject each one.
    
              [changed 10]            |          [changed to 10 file 2]---
    cent                              | sent
                                     -|-
              [changed 10]            |          [changed to 10 file 3]---
    cent                              | scent
                                      |-
    Do you want the CHANGE made in file 2? [yes] 
    no  
    
    Do you want the CHANGE made in file 3? [yes] 
    yes
    
    Applying CHANGE from file 3 [line 10]
    ============

Be sure to verify that the changes you accept produce consistent merged output. For example, after performing a merge involving file util.h, you can compare files util.h.contrib (which contains its previous contents) and the new util.h (which contains the merge output).

Determination of the base contributor

If all the contributors are versions of the same element, Diff Merge determines the base contributor automatically. It examines the version tree of the element, which includes all the merge arrows created by previous merge operations. This examination reveals the relationships among versions from the standpoint of their contents (which versions contributed their data to this version), rather than their creation order (which versions were created before this version). Diff Merge selects as the base contributor the closest common ancestor in this enhanced version tree.

The following figure illustrates a common case of merging and the determination of the base contributor for a merge.

Three branches for an element are shown: test, main, and windows. The test branch starts at version 4 off the main branch. The windows branch starts at version 5 off the main branch and is labeled a base contributor in the merge shown from version 6 on the main branch to version 3 on the test branch. Two contributor versions are version 4 on the test branch and version 1 on the windows branch.

If no merges have been performed in the element, the actual common ancestor (5) of the contributors (test/4 and windows/1) in the version tree is selected to be the base contributor.

If the contributors are not all versions of the same element, there is no common ancestor (or other base contributor). In this case, automated merging is turned off, and you must resolve all discrepancies among the contributors.

Recording of merge arrows

Under the following conditions, the merge is recorded by creating one or more merge arrows (hyperlinks of type Merge):

  • All contributor files must be versions of the same file element.
  • One of the contributors must be a checked-out version, and you must specify this version as the target to be overwritten with the merge output (the -to option in the merge command). (Alternatively, you can optionally create merge arrows without performing a merge; in this case, you do not need to check out any of the contributors.)
  • You must not perform the merge but suppress creation of merge arrows.
  • You must not use any of these options: selective merge, subtractive merge, or base contributor specification (the -insert, -delete, and -base options in the merge command).

Diff Merge draws an arrow from each contributor version (except the base contributor) to the target version. You can see merge arrows with the Version Tree Browser.

Locating versions with merge hyperlinks

The find and lsvtree -merge commands can locate versions with Merge hyperlinks. The describe command lists all of the hyperlinks of a version, including merge arrows:

cleartool describe util.h@@/main/3
version "util.h@@/main/3"
.
.
.
Hyperlinks:
Merge@278@/vob_3 /vob_3/src/util.h@@/main/rel2_bugfix/1
-> /vob_3/src/util.h@@/main/3

Directory merge algorithm

Each version of a DevOps Code ClearCase directory element contains the names of certain file elements, directory elements, and VOB symbolic links. Diff Merge can process two or more versions of the same directory element, producing a directory version that reflects the contents of all contributors. The algorithm is similar to that for a file merge. Diff Merge prompts for user interaction only when two or more of the contributors are in conflict.

One of the directory versions, the merge target, must be checked out. (Typically, it is the version in your view.) Diff Merge updates the checked-out directory by adding, removing, and changing names of elements and links.

Tip: A directory merge does not leave behind a .contrib file, with the pre-merge contents of the target version.

Merging directories

To merge directories:

  1. Ensure that all contributor versions of the directory are checked in.
  2. Check out the target version of the directory.
  3. Perform the directory merge immediately, without making any other changes to the checked-out version.

If you follow this procedure, it is easier to determine exactly what the merge accomplished. Enter a diff -predecessor command on the checked-out version, which has just been updated by merge.

Using ln and rmname in Diff Merge

VOB hard links are used to implement directory merges. You can use the ln and rmname commands to perform full or partial merges manually. See the ln and rmname reference pages in the DevOps Code ClearCase Command Reference.