Three Way Merge Guide

Concurrent merge, ancestor → edit1 → edit2

Three way merge is a special case of graft where edit1 and edit2 have a common immediate ancestor.  

Three way merge has three files as input. The first of these is a common ancestor file, the other two are independent edits of the ancestor.  

The result file can optionally show the results of doing one of these, depending on the setting of the three way merge mode:

  • showConflicts
  • resolveUsingEdit1
  • resolveUsingEdit2

There is also an option to process the changes in strings at a word by word level or by whole string equality.

Merging of arrays is controlled by how items in the arrays match together. 

  • positionPriority
  • typeWithValuePriority
  • orderless

In the delta format the dx_delta object accurately describes the contributions of the input files to the merge result. However, subsequent processing is simplified if these deltas are classified to describe the types of change which they represent. The current classification scheme describes changes in the result file as an add, a delete or a modify.

This classification has a number of uses. For example, it could be used to style changes in a publication, using strike through, red/green background or change bars to indicate change visually. Another use-case would be to drive a GUI associated with change display.

Because we can consider the ancestor version to be older than the other edits in the merge we have a temporal frame of reference and so the concepts of add and delete are defined relative to the ancestor version. This choice then leads to the following definitions for change categorisation:

  1. add: something that does not exist in the ancestor, but does in one or more edits. The dx-delta object will contain only a "B" key.
  2. delete: something that exists in the ancestor, but is missing in at least one of the edits. The dx-delta object will contain only an "A" key.
  3. modify: other changes not already classified as an add or a delete. The dx-delta object will contain both "A" and "B" keys.

This example shows a conflicting modification:

Ancestor
{"words": "The quick brown fox jumps over the lazy dog"}
Edit1
{"words": "The quick brown fox jumps silently over the lazy dog"}
Edit2
{"words": "The quick brown fox jumps way over the lazy dog"}

With default settings, threeWayMergeMode is set to showConflicts:

Result with default settings
{
    "dx_deltaJSON": {
        ...
        "dx_deltaJSON_delta": {
            "words": {
                "dx_delta": {
                    "edit1": "The quick brown fox jumps silently over the lazy dog",
                    "edit2": "The brown fox jumps way over the lazy dog"
                }
            }
        }
    }
}

The result can also be resolved by setting threeWayMergeMode pick either Edit 1 or Edit 2.

Result resolved using Edit 2
{
    "words": "The brown fox jumps way over the lazy dog"
}

For details of the request see Three Way Merge Request

#content .code