When working on a distributed codebase with a team of developers, it’s common to run into merge conflicts. While systems like Git offer flexibility for developers to collaborate by working in their own branches, when it comes time to merge your local changes into the main branch you might run into conflicts. Today we’ll discuss what leads to a merge conflict, how to avoid them, and how to resolve conflicts when they occur.

What is Git Merge?

Git merge is a command that combines your local committed changes back to the remote branch so that other developers can sync with your latest changes. Git merge is used during some pull requests – depending on configuration options or command line flags – to merge changes into the local branch.

If you have unsaved changes in your working directory or staging area then a merge will fail to start. This is to prevent your unsaved changes from being overwritten. This is not a merge conflict with another developer’s code but still needs to be resolved before a merge can take place.

What Causes a Merge Conflict?

A merge conflict occurs when there are differences between your copy of a file and what is in the remote branch. This can occur because you have unsaved changes in your working directory or staging area or because another developer has made changes in the same file and already merged them into the main branch.

Merge conflicts can arise even when you’ve been working on different parts of the same file. So editing or adding a line of code is not the only change a merge conflict detects; it also detects deletions, including if a file was deleted. In all these cases, it’s important to examine what has caused the merge conflict so that you can determine the best way to resolve it.

Merge Conflict Resolution in Git

When thinking about a typical co-dev situation where another developer has already merged changes for the same file into the remote branch, there are a few scenarios that bring about merge conflicts:

  • You added changes before the code they changed.
  • You added changes after the line of code they changed.
  • They deleted code that is still in your version.
  • You both made changes to the same line of code.

Similarly, there are a few options for merge conflict resolution in Git:

  • Accept the changes from the remote server entirely and remove yours.
  • Remove the changes from the remote server and keep your changes.
  • Keep both sets of changes.
  • Remove both sets of changes.
  • Manually combine changes

For each line of code that has a merge conflict, you should evaluate which of these options to choose. For the scenarios where code is added before or after another developer, it might be fine to keep both sets of changes because they don’t overlap. But if you were working on overlapping functions or the same section of the code, you will have to determine which changes to keep.

In cases where significant changes were made by developers independently, the code can become messy or complex and you may choose to remove both sets of changes and start over with a more coordinated plan. You can use git merge –abort.

Finally, if a file was deleted you can either accept the deletion (and perhaps adjust your code to no longer rely on that file) using git rm or restore the file by adding it back to the branch using git add.

How to Avoid Merge Conflicts?

Of course, it’s even easier to merge your changes if you can avoid merge conflicts. There are a few actions you and your team can take to make merge conflicts less likely to occur. The first is so simple that it can be overlooked – communicate.

Communication

When several developers are working on the same files it’s important to understand what each person is doing, in what order, and how that will impact the work of others on the team. For example, feature branches can be used to isolate work in progress. But it’s useful to understand how many feature branches the team has and how they will come together as they’re merged back into the master branch. Where possible, you might stagger people to work on shared code or check in their changes in a certain order to reduce conflicts. Or if a developer checks in a change they know will impact others they can let their teammates know to do a pull request so they know what has changed.

Frequent, Small Commits

The next way to avoid merge conflicts is to make frequent, small commits and review pull requests as soon as possible. Smaller changes are easier to review and less likely to cause merge conflicts because of the size and the amount of time that has passed since the last merge. Reviewing pull requests immediately also reduces the amount of time you’re working on a different version of the files and allows you to quickly resolve conflicts in your code rather than continuing to write code that may result in even more merge conflicts.

Code Formatting Rules

Another way to avoid merge conflicts is to have a shared code style with formatting rules. Every little difference in files – including white spaces, comments, and optional formatting characters – will get flagged as a merge conflict. Having a code formatting guide for your team can help standardize when and where those optional elements are used, reducing the likelihood that they will trigger a merge conflict.

Git Rebase

Finally, rebasing in Git can be used in certain situations to reduce the number of merge conflicts. Rebasing rewrites your local commit history and replaces your local branch with the changes in the main branch – then reapplies your changes. In this way, you’ll have the latest changes from your teammates, which should help you avoid merge conflicts. However, rewriting change history is risky and shouldn’t be used in all cases. How to Prevent Merge Conflicts (or at least have less of them) on DEV Community goes into more detail about how rebasing works.

How Assembla Handles Merge Conflicts

With Assembla you get the flexibility of Git, Perforce or SVN version control system hosting and the collaboration benefits of project management tools, along with integrations with other leading testing and reporting tools. You can leverage Assembla’s project management tools to track projects and bugs. Assembla also includes several features to help developers reduce and resolve merge conflicts.

Code Review and Approval Workflow

Through assigning @Followers, Assembla’s code review process allows specific team members to review changes before they are merged. This helps catch potential conflicts early and ensures that changes are well-understood and agreed upon before integration. 

Merge Request (Pull Request) System

The merge request system in Assembla facilitates discussion and review of changes. Team members can review diffs and comment on specific lines of code with suggested improvements or changes. This collaborative approach helps identify and resolve conflicts early in the process and is an easy way for developers to communicate without having to leave their development environment.

Merge requests on Assembla

Protect branches

You can protect your branches in Git to control which team members can approve and merge requested changes into the master branch or trunk. By having a controlled group of individuals handling merges there is better coordination and fewer chances of conflicting changes being integrated simultaneously.

For more information, check out the video tutorial Code Review in Assembla.

Integration with Continuous Integration (CI) Tools 

You can easily leverage Assembla’s merge request features alongside your CI/CD tools via built-in Jenkins integration or the Assembla API to show whether your changes pass or fail. Jenkins reads the Assembla merge requests and builds and tests the modified project. It then publishes results to Assembla with an upvote or downvote on the merge request, a comment on related tickets, or custom messages.