How To Resolve Merge Conflicts in Git

December 30, 2024

Introduction

The git merge command helps a contributor add to a project from a branch. When multiple contributors work on the same part of a code or work with numerous branches, merge conflicts often happen. The primary goal of git merge is to resolve or warn about these conflicts automatically.

This guide explains what a merge conflict is, how to prevent one, and offers resolutions for when they do not sort out automatically.

How to resolve merge conflicts in Git - a tutorial.

Prerequisites

  • Git installed and configured (on Windows, Mac, or Ubuntu).
  • A git merge conflict between a local and remote branch.
  • A text editor such as Vim or nano.

What Is a Git Merge Conflict?

When working with version control systems such as Git, most merge conflicts resolve automatically. However, there are situations where git merge is unable to resolve an issue.

Note: Check out our handy Git commands cheat sheet, which features commonly used commands such as git merge.

Some examples of merge conflicts include:

  • Changing the same lines of code in a file.
  • Removal of files while changes happen in another place.

Since the problem happens locally and the rest of the project members are unaware of the issue, resolving the conflict is of high priority and requires an immediate fix.

Types of Git Merge Conflicts

Merge conflicts occur when Git encounters discrepancies between two branches that cannot be automatically resolved. These conflicts typically arise in two main stages of the merge process: before the merge starts and during the merge itself.

The sections below explain the two main merge conflict types.

Conflict Before Merge

A conflict before a merge occurs when Git identifies changes in the working directory or staging area of the current project that could be overwritten by the commits being merged. These are not conflicts between branches but conflicts with local pending changes.

Git prevents the merge to ensure that no local modifications are unintentionally lost. Common causes include uncommitted changes or files that differ from their last committed state. When this happens, Git halts the process and outputs an error message similar to the one below:

error: Entry '<fileName>' not uptodate. Cannot merge. (Changes in working directory)

To resolve these conflicts, stabilize the local repository state using one of these methods:

  • git stash. Temporarily save local changes and apply them later.
  • git checkout. Discard changes in the working directory.
  • git commit. Save the changes to the repository.
  • git reset. Unstage changes from the index.

Once you resolve the issue locally, proceed with the merge.

Conflict During Merge

A conflict during a merge happens when Git detects discrepancies between the current local branch and the branch being merged. These conflicts are often caused by code changes made by different developers on the same file or lines of code. In such situations, Git cannot determine the correct resolution.

Git attempts to merge the branches automatically but leaves unresolved portions for manual intervention. It interrupts the merge process and outputs an error message like the one below:

error: Entry '<fileName>' would be overwritten by merge. Cannot merge. (Changes in staging area)

The possible solutions for addressing conflicts during a merge are:

  • Inspect the conflicted files. Look for conflict markers (<<<<<<<, =======, >>>>>>>) within the affected files.
  • Manually resolve conflicts. Choose the appropriate code from each branch or rewrite the section.
  • Mark conflicts as resolved. Use the git add [file_name] command to stage the resolved files.
  • Complete the merge. Finalize the process with git commit.

Note: Learn about the differences between git rebase and merge.

How to Identify Merge Conflicts in Git

Being able to identify merge conflicts in Git is essential to resolve issues and successfully merge branches. When a merge conflict occurs, Git provides clear indicators and commands to help you diagnose the problem.

When a conflict arises during a merge, Git outputs a descriptive message to alert you to the issue. This message typically appears in your terminal and includes details about the conflicted files. For instance, if you run the git status command after a failed merge, you may see something similar to the message below:

$ git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

  both modified:   merge.txt

The key point in this output is the unmerged paths section, which lists files with conflicts, such as merge.txt in this case.

To understand what caused the conflict, examine the affected files. Use the cat command or open the file in your preferred text editor to reveal conflict markers. For example:

$ cat merge.txt
<<<<<<< HEAD
content to be modified
content to append
=======
different content to be merged later
>>>>>>> new_branch_to_merge_later

The markers serve as conflict dividers and break the file into three sections:

  • <<<<<<< HEAD - Content from the current branch (e.g., main) pointed to by HEAD.
  • ======= - The divider separating the conflicting sections.
  • >>>>>>> new_branch_to_merge_later - Content from the branch being merged (e.g., new_branch_to_merge_later).

How to Resolve Merge Conflicts in Git

There are three ways to resolve a merge conflict in Git:

1. Accept the local version. To accept all changes on a file from the local version, run:

git checkout --ours [file_name]

Alternatively, accept the local version for all conflicting files with:

git merge --strategy-option ours

2. Accept the remote version. To update the changes on a file from the remote branch, enter:

git checkout --theirs [file_name]

To accept the remote version for all conflicting files, use this command:

git merge --strategy-option theirs

3. Review changes individually. The final option is to review each change separately. This option is also the best path to take, especially when working with multiple files and people. To make this job more manageable, use special tools to help review individual conflicts.

Ultimately, the choice of which parts of the code stay and which don't depends on the developer's decision for the current project.

Getting a Merge Conflict in Git

The merge conflict in Git happens when the command git merge throws an error.

Output of git merge with conflict error.

The error message prints the information about where the conflict is present. Check the file from the error message and look at the contents where the merge conflict happened:

Contents of file with a merge conflict.

Git automatically adds three indicators alongside the conflicting lines of code:

  • <<<<<<< (seven "less than" characters) followed by HEAD, which is an alias for the current branch. The symbols indicate the beginning of the edits within this section.
  • ======= (seven "equals sign" characters), which show the end of the revisions within the current branch and the beginning of the edits within a new one.
  • >>>>>>> (seven "greater than" characters) followed by the branch where the attempted merge happened. The added symbols indicate the ending of the edits within the conflicting branch.

The added syntax helps search through the code to find the location of the merge conflict. However, a much more straightforward approach is to use a difference/merging tool to discover the issues and track the changes.

Note: Learn how to combine multiple commits by squashing commits in Git.

Setting Up Default Diff Tool in Git

To set up the default diff tool for git mergetool:

1. Run the following line in your terminal:

git mergetool --tool-help

The output prints out all the supported diff tools for your current setup:

Git merge tool help file.

Different tools are available based on the editor you are using. For example:

  • Emacs diff tools: Ediff or emerge
  • Vim diff tools: vimdiff, vimdiff2 or vimdiff3

The further steps show an example of how to set up the vimdiff tool for Vim.

2. Change the git config to set the default merge tool:

git config merge.tool [tool_name]

For example, if you are using Vim, run:

git config merge.tool vimdiff

3. Set the diff tool to show the common ancestor for both files, which is the version before any edits:

git config merge.conflictstyle diff3

4. Set the option to not prompt before running:

git config mergetool.prompt false

The diff tool setup for Git is complete.

Using Mergetool to See the Differences

To use the mergetool and see the differences, run:

git mergetool
Example of the vimdiff git mergetool display.

The output displays a window with four views:

1. LOCAL represents the file version from the current branch.

2. BASE is how the file looked before any changes.

3. REMOTE shows how the file looks in the remote branch where the conflicting information is.

4. MERGED has the final merge file. This result represents what gets saved to the repository.

The primary navigation commands between these windows are:

  • CTRL+WW to move between the windows.
  • CTLR+WJ to jump to the MERGED window view.
  • CTRL+WX to switch places of the windows.

For advanced navigation, information is available with the command:

:help window-moving

Updating and Resolving a Merge Conflict

Update the MERGED file to resolve a conflict. Some shortcuts for updating the MERGED version include:

  • :diffg LOCAL updates to the LOCAL version.
  • :diffg BASE updates to the BASE version.
  • :diffg REMOTE updates to the REMOTE version.

Note: Ensure the cursor is on the line where the conflicts are before running these commands.

Once the information is updated, save and quit with :wqa.

Commit and Cleanup

The final step is to commit and clean up the extra files. Commit the updated version by running:

git commit -m "<your message>"

Note: If you made a mistake while committing, you could undo the last commit.

The diff tool creates extra files on the project for comparing versions. Clean them up with:

git clean -f
Example output after resolving a merge conflict.

Git Commands Used to Resolve Merge Conflicts

The commands used to resolve merge conflicts also ensure that your repository remains in a stable state throughout the process. Each command serves a specific purpose, from staging resolved changes to cleaning up temporary files.

The table below summarizes the key Git commands used to handle merge conflicts:

CommandDescription
git stashTemporarily save local changes and apply them later.
git checkout --ours|--theirs [file_name]Discard changes in the working directory or accept a specific version during conflict resolution.
git commit -m "message"Save changes to the repository.
git resetUnstage changes from the index.
git mergeMerge branches and resolve conflicts.
git merge --abortAbort an in-progress merge process.
git add [file_name]Stage resolved files after resolving conflicts.
git config merge.tool [tool_name]Configure Git settings, such as the default merge tool or conflict style.
git mergetoolOpen the default merge tool to visualize and resolve conflicts.
:diffg LOCALUpdate the merge file to the LOCAL version using Vimdiff.
:diffg BASEUpdate the merge file to the BASE version using Vimdiff.
:diffg REMOTEUpdate the merge file to the REMOTE version using Vimdiff.
:wqaSave and quit all windows in Vimdiff after resolving conflicts.
git clean -fRemove extra files created during conflict resolution.

Tips On How to Prevent Merge Conflicts

Merge conflicts only happen when a system cannot resolve the problem automatically.

Here are some tips on how to prevent merge conflicts:

  • Use a new file instead of an existing one whenever possible.
  • Avoid adding changes at the end of the file.
  • Push and pull changes as often as possible.
  • Do not beautify code or organize imports on your own.
  • Avoid the solo programmer mindset by keeping in mind the other people who are working on the same code.

Conclusion

Merge conflicts happen when working in Git or other version control programs from time to time. By following the instructions in this guide, you know how to handle merge conflicts and how to prevent them from happening.

For more Git resources, see how to set upstream branch in Git, or learn to use GitHub with our tutorial for beginners.

Was this article helpful?
YesNo
Bosko Marijan
Having worked as an educator and content writer, combined with his lifelong passion for all things high-tech, Bosko strives to simplify intricate concepts and make them user-friendly. That has led him to technical writing at PhoenixNAP, where he continues his mission of spreading knowledge.
Next you should read
Bare Metal Cloud GitHub Actions
May 6, 2021

GitHub Actions is a platform for software development workflow automation with a built-in...
Read more
What Is Git Upstream And How To Set Upstream Branch
November 21, 2024

In order to properly track your changes and push them to Git...
Read more
How to Update Git
May 8, 2024

This tutorial provides an overview of different ways you can update Git on Linux, Windows, and MacOS systems.
Read more
How to Remove a Git Remote From Repository
November 17, 2020

When a remote repository moves to another host or a team member stops working on a project, the related git...
Read more