Resolve conflicts
Depending on your version control system, conflicts may arise in different situations.
When you work in a team, you may come across a situation when somebody commits changes to a file you are currently working on. If these changes do not overlap (that is, changes were made to different lines of code), the conflicting files are merged automatically. However, if the same lines were affected, your version control system cannot randomly pick one side over the other and asks you to resolve the conflict.
Conflicts may also arise when merging, rebasing, or cherry-picking branches.
Non-Distributed Version Control Systems
When you try to edit a file that has a newer version on the server, MPS informs you about that, showing a message popup in the editor:
In this case, you should update your local version before changing the file or merge changes later.
If you attempt to commit a file that has a newer repository version, the commit fails, and an error is displayed in the bottom right corner telling you that the file you are trying to commit is out of date.
If you synchronize a file that already has local changes with a newer repository version committed by somebody else, a conflict occurs. The conflicting file gets the Merged with conflicts status. The file remains in the same changelist in the Changes view, but its name is highlighted in red. If the file is currently opened in the editor, the filename on the tab header is also highlighted in red.
Distributed Version Control Systems
Under distributed version control systems, such as Git and Mercurial, conflicts arise when a file you have committed locally has changes to the same lines of code as the latest upstream version and when you attempt to perform one of the following operations: pull, merge, rebase, cherry-pick, unstash, or apply patch.
If there are conflicts, these operations will fail, and you will be prompted to accept the upstream version, prefer your version, or merge the changes manually:
The Conflicts dialog is triggered automatically when a conflict is detected on the Version Control level.
If you click Close in this dialog or call a Git operation that leads to a merge conflict from the command line, a Merge Conflicts node will appear in the Local Changes view with a link to resolve them:
MPS provides a tool for resolving conflicts locally. This tool consists of three panes:
The left pane shows the read-only local copy
The right pane shows the read-only version checked into the repository
The central pane shows a fully-functional editor where the results of merging and conflict resolution are displayed. Initially, the contents of this pane are the same as the base revision of the file, that is, the revision from which both conflicting versions are derived.
Resolve conflicts
Click Merge in the Conflicts dialog, the Resolve link in the Local Changes view, or select the conflicting file in the editor and choose VCS | <your_VCS> | Resolve Conflicts from the main menu.
To automatically merge all non-conflicting changes, click (Apply All Non-Conflicting Changes) on the toolbar. You can also use the (Apply Non-Conflicting Changes from the Left Side) and (Apply Non-Conflicting Changes from the Right Side) to merge non-conflicting changes from the left/right parts of the dialog, respectively.
To resolve a conflict, you need to select which action to apply (accept or ignore ) to the left (local) and the right (repository) versions and check the resulting code in the central pane:
You can also right-click a highlighted conflict in the central pane and use the commands from the context menu. The Resolve using Left and Resolve using Right commands provide a shortcut to accepting changes from one side and ignoring them from the other side, respectively:
For simple conflicts (for example, if the beginning and the end of the same line have been modified in different file revisions), the Resolve simple conflicts button that allows merging the changes in one click becomes available.
Such conflicts are not resolved with the Apply All Non-Conflicting Changes action since you must make sure that they are resolved properly.
It may also be useful to compare different versions to resolve a conflict. Use the toolbar button to invoke the list of options. Note that Base refers to the file version that the local and the repository versions originated from (initially displayed in the middle pane), while Middle refers to the resulting version.
Review merge results in the central pane and click Apply.
Productivity tips
- Apply non-conflicting changes automatically
You can configure MPS to always apply non-conflicting changes automatically instead of telling it to do so from the Merge dialog. To do this, select the Automatically apply non-conflicting changes option on the Tools | Diff Merge page of the IDE settings Ctrl+Alt+S.
- Manage changes in the central pane
You can manage changes in the central pane using the toolbar that appears when you hover over a change marker in the gutter and then click it. The toolbar is displayed together with a frame showing the previous contents of the modified line:
For example, when there are multiple non-conflicting changes, and you only need to skip one or two of them, it's easier to apply all of them simultaneously using the Apply all non-conflicting changes action and then undo the unwanted ones using the Revert action from this toolbar.
- Changes in Node ID
When a node is deleted and then re-typed, a new node is created, which introduces a change in VCS. The node, however, only differs from the deleted node in its internal unique ID value. The MPS diff dialog offers a button to hide such changes and the merge process treats the ID changes as non-conflicting.
- Changes in resolve info
When a node is renamed the references to that node do not change, however their resolve info as well as the visual appearance change. The MPS diff dialog offers a button to hide such changes on the reference nodes and the merge process treats the resolve info changes as non-conflicting.
- Moved nodes
When a node is moved to a new location, the node itself is not really changed. The MPS diff dialog offers a button to track moved nodes as a separate kind of change instead of as a pair of delete and insert operations. In addition to that, the dialog offers an option to hide moves of nodes in an unorderred collection, since in such cases the actual position of a node in that collection is guaranteed not to matter for the model semantics.
- Show inspector
The MPS diff dialog offers a button to show the Inspector tool window in both panels.
- Synchronized scrolling
When scrolling in the diff dialog, both panels scroll at the same time to easy visual comparison of both variants of the code. The MPS diff dialog offers a button to disable synchronized scrolling so that both panels can be scorred independently. This is useful, for example, to compare code that has been moved to a new distant location.
- Diff for merge commits
When a merge commits introduces changes with respect to both of its parent commits, the diff dialog shows three panels instead of two. The middle panel shows the final result of the merge, while the left and the right panels show the two parent commits. The differences between the merge commit and its respective parent commits are graphically highlighted. This three-panel diff dialog appears for merge commits in the Git log view, in the root history dialog window and also as a result of calling the “Show diff” action from an annotated line or cell.