Version 2017.4.24.2347
This release adds 3-way merge functionality to DiffLib.
It is based on common base, left, right type of merges, similar to what you would encounter in most version control systems that support any kind of branches and/or merging.
Let's see how to use it.
You have to supply the following parameters to Merge.Perform
:
- The common base, this is considered to be the content of the collection before either side changed it
- The left side, this simply one of the set of changes (compared to the common base) that you want to merge
- The right side, again compared to the common base this provides a set of changes you want to merge
- A diff element aligner (
IDiffElementAligner<T>
implementation) - A conflict resolver (
IMergeConflictResolver<T>
implementation), this is new so described below - Optionally a
IEqualityComparer<T>
comparer as usual
Here's what will happen:
- Common base will be compared with left
- Common base will be compared with right
- The two sets of diffs will be compared, using the common base items as synchronization points
This now gives us matching changed elements from both left and right simultaneously. We now analyze what happened to them in each respective diff and decide how to handle the change.
In the scenarios where conflicting edits have been made, such as left side deleted an item and right side modified it, the conflict resolve will be asked what the end result should be.
The conflict resolver will be given items from the common base, left side, and right side, and have to produce the final set of items this conflict should end up with.
For instance, to simulate the git merge -s ours
strategy, and left
means ours
, you would simply return the left items. If you want to simulate something like take left then right
you would concatenate the two and return them.
There are a couple of basic implementations built into DiffLib:
TakeLeftMergeConflictResolver<T>
, always takes left side and discards rightTakeLeftThenRightMergeConflictResolver<T>
, always take both sides, left firstTakeLeftThenRightIfRightDiffersFromLeft<T>
, take both sides if they differ, otherwise take left (and I notice here that I have gotten the name of the type wrong, will be fixed in an upcoming release)TakeRightMergeConflictResolver<T>
, similar to the left version, just always takes right and discards left