MPS 2019.3 Help

Using Migrations with branching

Using migrations with branching

To nicely support language evolution, migrations automatically upgrade client code to use the latest version of a language or multiple languages. The Migrations documentation describes the process of creating and running migrations in MPS. Briefly, in order to change models to comply with the language changes, language authors can provide migrations. MPS automatically tracks language versions used in projects and asks the end-user to apply needed migrations.

While there are hardly any surprises when using a single branch of development, typical team setup involves multiple branches for features as well as bug fixes. With multiple branches teams will inevitably face situations like having different versions of languages in different branches, which makes the merge procedure much more challenging.

The main rule of painless merge

To merge two branches smoothly, all languages used in those branches should be of the same versions. The following describes a simple workflow that allows you to easily synchronise language versions in two branches.

No migrations were created in any of the merged branches

To sync language versions, just update languages in the outdated branch and run required migrations. Now both branches have the same versions of used languages and can be easily merged.

Some migrations were created

All considered cases have the same idea behind them: never merge branches that differ in versions of used languages. Thus we need to propagate all the migrations into both branches before merging them.

1. One migration was developed in one of the branches

The only special thing that should be done when you write a migration is that there should be a commit (name it C) containing the migration itself, but no code should be migrated in the same commit. The migrated files can be committed later, e.g. in the following commit.
The main idea here is to give other branches a possibility to get the new migration without having to merge different versions of used languages.

Now, your history looks like this:

       |--- C ---  [branch 1]

------|

       |------------  [branch 2]

To merge branches b1 and b2

  1. Merge b2 with commit C. Now you have the new migration in b2. 

  2. Run the migration on b2

  3. Merge with b1's HEAD

Quite simple, isn't it?

2. Two or more migrations in one of the branches

The principle remains the same, it is just repeated two or more times

       |----- C1 — C2 –  [branch 1]

------|

       |------------  [branch 2]

  1. merge b2 with C1

  2. run C1's migration on b2

  3. merge with C2

  4. run the migration on b2

  5. merge with b1

3. Migrations were created in both branches

In general, we recommend you to avoid this situation as it's harder to resolve. This scenario can best be avoided by having all migrations created in only one agreed-upon branch (e.g. master).

But if you got into this situation, here's a way to resolve it gracefully:

       |--- C1 -----  [branch 1]

------|

       |--- C2 -----  [branch 2]

  1. Merge b2 and C1, b1 and C2

  2. Run C1's migration on b2, C2's migration on b1

  3. merge the branches

Last modified: 28 February 2020