Version Control without Source Code

Most software is defined in source code. Not so with Mendix. The most important part of every Mendix project is its model, which contains the domain model definition, forms, and business logic for a Mendix application. This model is interpreted and executed by the Mendix Runtime, resulting in working software.

Version control for developing applications in Mendix is based on Subversion. Subversion has excellent support for text-based diffing and merging, which is used for project resources such as Java actions and theme files. However, since we chose a binary file format for the model file, we cannot use Subversion’s text-based merge algorithm to merge changes between different revisions of the model.

That is why we created our own merge algorithm for the model. The model can be seen as a gigantic tree structure starting with the project as the root node that contains modules, which in turn contain folders and documents. The tree goes all the way down to model elements such as attributes and microflow activities. Therefore, our merge algorithm is tree-based and merges changes between different versions of such trees.

The merge algorithm takes three model trees as its input: the base tree, and two changed trees, called ‘head’ and ‘mine’. This is called a three-way merge algorithm. The first step of the algorithm is to calculate the changes between base and head and those between base and mine. Then it attempts to merge those two lists of changes into one that can be applied to base to yield the merged tree. If it encounters conflicting changes, conflict markers are placed at those locations in the resulting tree. The following image shows an example of a tree merge.

An example tree merge showing how two sets of changes to a base tree are merged.
An example tree merge. Head changed object B, while mine moved B below C and added D. The merged tree contains all of those changes.

The merge algorithm begins by scanning the project structure (modules, folders, and documents) for changes. It detects additions, moves, deletes, and edits. Edits are detected by comparing a hash of the contents between base and the changed tree. This is done to speed up the merge process; unchanged documents do not need to be processed further. If conflicting changes are detected between head and mine, those items are marked as tree-conflicted.

If a document’s contents have changed in both head and mine, then those changes need to be merged. This is done in much the same way as the project structure is merged. Additions, moves, deletes, and edits to both head and mine are detected and attempted to be merged into a single list of changes. If conflicting changes are detected, conflict markers are added.

One advantage of using a tree-based merge algorithm as opposed to a text-based one is this: In text-based merge, when one person moves a block of text while the other modifies it, a conflict will arise. In our tree-based merge algorithm we can merge those changes because we can track a node even though it has been moved. Every node in the model has a unique identifier so that all nodes can be distinguished from each other. If you only have source code, you can not have a unique identifier for text blocks. You could try to use a hash for this, but that changes as soon as the source code changes.

Another advantage is that we have full control of the merge algorithm. We don’t want our users to have to solve a bunch of textual conflicts in the “source code” of their visual models. We present the conflicts visually in a list, allowing users to navigate to the conflicted area in their visual model. The user can use the conflict information in the list to decide how to resolve the merge conflict.

Conflicts represented in the Mendix Business Modeler

In short, our version control feature builds on Subversion and improves on its text-based merge algorithm for changes to the model. Since Mendix models are not text-based like most software source code is, we can use a tree-based merge algorithm that allows more changes to be merged, resulting in fewer conflicts and therefore faster development.


Share to Social Media