HowTo -- MPS and Git

Skip to end of metadata
Go to start of metadata

Working with MPS and git

This section explains how to use git with MPS. It assumes a basic knowledge
of git and the git command line. The section focuses on the integration with
MPS. We will use the git command line for all of those operations that are not
MPS-specific.

We assume the following setup: you work on your local machine with a clone of an
existing git repository. It is connected to one upstream repository by the name
of origin.

Preliminaries

VCS Granularity

MPS reuses the version control integration from the IDEA platform. Consequently,
the granularity of version control is the file. This is quite natural for
project files and the like, but for MPS models it can be confusing at the
beginning. Keep in mind that each model, living in solutions or
languages, is represented as an XML file, so it is these files that are handled
by the version control system.

The MPS Merge Driver

MPS comes with a special merge driver for git (as well as for SVN) that makes
sure MPS models are merged correctly. This merge driver has to be configured in
the local git settings. In the MPS version control menu there is an entry
Install Version Control AddOn. Make sure you execute this menu entry
before proceeding any further. As a result, your .gitconfig should contain
an entry such as this one:

The .gitignore

For all projects, the .iws} file should be added to {{.gitignore, since
this contains the local configuration of your project and should not be shared
with others.

Regarding the (temporary Java source) files generated by MPS, two approaches are
possible: they can be checked in or not. Not checking them in means that some of
the version control operations get simpler because there is less "stuff" to deal
with. Checking them in has the advantage that no complete rebuild of these files
is necessary after updating your code from the VCS, so this results in a
faster workflow.

If you decide not to check in temporary Java source files, the following
directories and files should be added to the .gitignore in your local
repo:

  • For languages: source_gen, source_gen.caches and
    classes_gen
  • For solutions, if those are Java/BaseLanguage solutions, then the same
    applies as for languages. If these are other solutions to which the
    MPS-integrated Java build does not apply, then source_gen and
    source_gen.caches should be added, plus whatever else your own build
    process creates in terms of temporary files.

Make sure the .history files are not added to the gitignore*!
These are important for MPS-internal refactorings.

MPS' caches and Branching

MPS keeps all kinds of project-related data in various caches. These caches are
outside the project directory and are hence not checked into the VCS. This is
good. But it has one problem: If you change the branch, your source files
change, while the caches are still in the old state. This leads to all
kinds of problems. So, as a rule, whenever you change a branch (that is not
just trivially different from the one you have used so far), make sure you
select File -> Invalidate Caches, restart and rebuild your project.

Depending on the degree of change, this may also be advisable after pulling from
the remote repository.

Committing Your Work

In git you can always commit locally. Typically, commits will happen quite
often, on a fine grained level. I like to do these from within MPS. The screenshot below
shows a program where I have just added a new variable. This is highlighted with
the green bar in the gutter. Right-Clicking on the green bar allows you to rever
this change to the latest checked in state.

In addition you can use the Changes view (from the
Window -> Tool Windows menu) to look at the set of changed files. In my case
(\fig

Unknown macro: {changesview}

) it is basically one .mps file (plus two files realted
to writing this document ). This .mps file contains the test case to
which I have added the new variable.

To commit your work, you can now select Version Control -> Commit Changes.
The resulting dialog, again, shows you all the changes you have made and you can
choose which one to include in your commit. After committing, your git status
will look something like this and you are ready to push:

Pulling and Merging

Pulling (or merging) from a remote repository or another branch is when you
potentially get merge conflicts. I usually perform all these operations from the
command line. If you run into merge conflicts, they should be resolved from
within MPS. After the pull or merge, the Changes view will highlight
conflicting files in red. You can right-click onto it and select the
Git -> Merge Tool option. This will bring up a merge tool on the level of the
projectional editor to resolve the conflict. Please take a look at the
screencast at

to see this process in action.

The process described above and in the video work well for MPS model files.
However, you may also get conflicts in project, language or solution files.
These are XML files, but cannot be edited with the projectional editor. Also,
if one of these files has conflicts and contains the < < < < and
> > > > merge markers, then MPS cannot open these files anymore because
the XML parser stumbles over these merge markers.

I have found the following two approaches to work:

  • You can either perform merges or pulls while the project is closed
    in MPS. Conflicts in project, language and solution files should then be
    resolved with an external merge tool such as WinMerge before attempting
    to open the project again in MPS.
  • Alternatively you can merge or pull while the project is open (so the
    XML files are already parsed). You can then identify those conflicing files
    via the Changes view and merge them on XML-level with the MPS merge
    tool. After merging a project file, MPS prompts you that the file has been
    changed on disk and suggests to reload it. You should do this.

Please also keep in mind my remark about invalidating caches above.

A personal Process with git

Many people have described their way of working with git regarding branching,
rebasing and merging. In principle each of these will work with MPS, when taking
account what has been discussed above. Here is the process I use.

To develop a feature, I create a feature branch with

I then immediately push this new branch to the remote repository as a backup,
and to allow other people to contribute to the branch. I use

Using the -u parameter sets up the branch for remote tracking.

I then work locally on the branch, committing changes in a fine-grained way.
I regularly push the branch to the remote repo. In less regular intervals I pull
in the changes from the master branch to make sure I don't diverge too far from
what happens on the master. I use merge for this:

Alternatively you can also use

This is the time when conflicts occur and have to be handled. In repeat this
process until my feature is finished. I then merge my changes back on the
master:

Notice the --squash option. This allows me to "package" all of the commits
that I have created on my local branch into a single commit with a meaningful
comment such as "initial version of myFeature finished".

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.