Skip to content

Element Selection

When merging models, LemonTree has to decide for each element which version (i.e. which side) it should take. For unmodified elements this is easy, since the version does not matter, but for modified elements LemonTree has to be a bit more clever.

There are two distinct cases which, although mostly identical in implementation, yield different outcomes at different times.

Automatic Mode

When comparing models with LemonTree, you'll find that there is a step PreMerge which can take a while to finish. This step embodies the automatic merge mode. The input to this step is a set of differences (i.e. "Element X is modified in B"), and the output a set of decisions (i.e. "For element X, take version B").

Important to note here is that there is no other input to this step. Since the user has not yet decided on overriding the merge decisions of LemonTree, we start with a blank slate and have to come up with a set of decisions which satisfy basic rules of UML, while reflecting the user intent as closely as possible.

To come up with the merged model, the conflicts are examined first. This process is outlined in Diff & Merge Strategy. Just examining the conflicts and resolving them does not, however, yield a valid (or useful) model - UML is as much about the dependencies of elements as it is about elements. LemonTree therefore decides, for each element, if its dependencies are met, and adjusts the merge decisions accordingly.

An example of such a dependency is the relation between the representation of a diagram (we call that DiagramObject) and its represented element. While you absolutely can have elements without DiagramObjects, you will want the DiagramObjects in your merged model if the element is also a part of that. Read more about it here.

Dependencies like these are handled in this mode. Since they can span many levels and affect a big part of the model, calculating these may take a while.

Manual Mode

This mode comes into play when doing manual decisions (decision overrides) on elements by using the UI. The reasoning for this step is the same as for automatic mode - to preserve validity and usefulness of a model. But instead of starting with nothing, this step is fed with the existing decisions.

An example where you see this in action is when overriding the merge for a Class with an Image. Suppose you have such a class which was marked for deletion by the automatic merge. Overriding the merge decision yields a merged model with that class, but also with its image, since images are deemed an integral part of an element.

Another example are connectors. Suppose you have a deleted connector which points from an existing class A to a deleted class B. Taking the connector will also mark class B to be taken as well, since the connector can't stand on its own.

There are a number of dependencies which we deem important enough to warrant such a resolution step.