Getting Started

Installing EMF Compare

Marketplace Client

Using the bundled Eclipse marketplace client you can install EMF Compare in one click. Just type "emf compare", click on search, and then on install.

Update Site

EMF has been part of the Eclipse release train since Galileo, you can install it using the following update sites, depending on your platform. Note that the following are not meant to be visited in your internet browser; they must be pasted in the Help > Install New Software dialog of your Eclipse, as p2 repositories.

Please note that the EMF Compare development team does its best to maintain downward compatibility towards Galileo (Eclipse 3.5). Following is the compatibility chart :

EMF Compare

Eclipse 3.2 - EMF 2.2

Eclipse 3.3 - EMF 2.3

Eclipse 3.4 - EMF 2.4

Eclipse 3.5 - EMF 2.5

Eclipse 3.6 - EMF 2.6

Eclipse 3.7 - EMF 2.7

Eclipse 3.8 - EMF 2.8

0.7

OK

0.8

KO

OK

OK

1.0

KO

OK

OK

OK

OK

1.1

KO

KO

OK

OK

OK

OK

OK

1.2

KO

KO

OK

OK

OK

OK

OK

1.3

KO

KO

KO

OK

OK

OK

OK

2.0

KO

KO

KO

OK

OK

OK

OK

An empty cell indicates that the compatibility hasn't been tested for a particular combination.

Usage

Once installed, you can compare your files (locally or from any Version Control System) as usual using the compare with menu.

Sample Use Case

With the following, we'll follow the life cycle of a metamodel describing a very basic library as it evolves separately in different branches. This will allow us to give more concrete examples of how EMF Compare can be used, and how it can help you.

Creating a model

For this test, we'll suppose that you are trying to use EMF Compare on UML models shared under git. This will not go in details about UML and Git. We'll assume that you know how to manipulate an UML model, create or clone a git repository, share a project under it and use standard Git operations.

The name of our sample project will be "library". It contains a single folder "model" containing two models :

library_Types.uml will contain our primitive types,

library.uml will contain our actual model.

The two models will be commited to our git clone. The whole thing looks like this :

The model itself is a very simple library. Graphically speaking :

Now that this initial model file has been committed, we'd like to improve it a little. For example :

Add an alias property to the Writer class,

Add a new History Category,

Rename the pages property of Book into length.

Our model now looks like this :

But how do we know exactly what changed? Let's compare this with the file from the Git Index :

This will open a comparison editor that initially looks like the following :

There are three main areas of interest in this editor.

Displays a structured list of the differences detected between the current version of the model and the version that lies in the Git Index.

This will react to the selections in (1) and display the left side of this comparison. As a rule of thumb, the left is the local version of the model. In this example, left will then be the version we have modified in our workspace. This is originally empty, more on this section in the example just below.

As above, this will react to selections in (1), but this time it will display the right side of the comparison. This is generally the remote version of the model; the version to which we've compared ours. In this case, this will represent the version of the model as it is in the Git Index. This is originally empty, more on this section in the example just below.

(2) and (3) are initially empty. They are there to display more information about the differences detected between our models. Let's select one of these differences :

We've selected the difference corresponding to the addition of attribute alias in the class Writer. A double-click on this difference updated our two panes below.

alias has been added to the properties of Class Writer. In the model, this corresponds to a change to the reference ownedAttributes of the Writer Class. This sub-panel indicates the actual reference that was changed in oder to remind us of the context.

This displays all values of the reference outlined in (2) as they are in the left model. This is where we see the new value, alias outlined.

As for (2), this will display the context of the selected difference. The same reference will usually be displayed in both (2) and (4).

This panel displays all values of the reference outlined in (4) as they are in the right model. In here, we see the location of alias outlined as an empty space. This rectangle is where the new value will be added if we merge it... Though in this case, it is not possible to merge towards the right : it is a version located on a repository and is thus non-editable.

This is useful in order to determine exactly what changed in our version, but serves no other purpose : merging changes here would only mean reverting back our modifications to the "clean" state from the repository. Let's commit our changes.

Branching

Now, we'd like to create a new feature for our library : we'd like clients to be able to borrow our books. We'll branch our repository in order to create this new feature and name this new branch borrowables :

Starting right away, we add the necessary new concepts to our model to represent the possibility of lending books. We "may" later need to have more than books to be lendable, so let's make a Borrowable interface to hold this concept. We'll also need a Person class, as well as a new data type to represent the person's birth date :

In a tree viewer, our models now look like (highlighted in red, the concepts we added with this step) :

However, while we are working on our borrowables branch, the master branch may still evolve : other people on the project might be adding new concepts of their own, or we could be switching to the main branch for a high priority fix ourselves. Let's imagine that two features have been added since we branched our repository. First, someone needed to have the library hold not only Books, but also Magazines. Second, we needed the publication date of our Books and magazines to be recorded.

The first of these two commits will add the following concepts to our master branch's model :

While the second only adds a primitive type and a property :

Merge

If you have followed to this point, we now have two diverging branches, master and borrowables which both hold a different version of our library.uml model. Here is how these two models look like at this point :

Master

Borrowables

User Interface

The main points of interest are highlighted in the following picture :

Overview of the differences detected between the given two (or three) models.

First version of the compared models.

Second version of the compared models.

This button will only be visible in the case of three-way comparisons (for example, comparing with a remote repository). It will make a third version of the compared model (the common ancestor of the two others) visible in the interface.

This button will allow you to group differences together in the structural view. For example, grouping all "Additions" or "Deletions" together.

This button will allow you to filter some differences out of the view according to a set predicate. For example, filtering out all "Additions" or "Moves".

Allows you to merge all non conflicting differences (left to right, or right to left) at once.

Allows you to merge the single, currently selected difference in a given direction (left to right, or right to left).

Allows you to navigate through the detected differences.

Features

Handling Conflicts

PENDING

Grouping Differences

This feature allows you to group differences together in the structural view according to a set predicate. By default, EMF Compare provides three distinct grouping strategies :

Default

Do not try and group differences together, display them as they were detected.

By Kind

Group differences by their kind (additions, deletions, moves, changes).

By Metaclass

Group difference according to the metaclass of the object on which they were detected.

Logical Model

EMF Compare does not act simply on the selected files, but on their whole logical model (a given model can be split through multiple files through EMF control action). Thanks to that, if you try and compare a model file that reference other model files, the comparison will still be able to take these "other" files into account. For example, if you try and compare a genmodel file (that depends on its underlying ecore file) :