Git Merge Conflicts
Introduction
Merge conflicts are a natural part of collaborative development with Git. While Git can automatically merge most changes, sometimes it needs human intervention to decide how to combine conflicting modifications. This guide will help you understand what merge conflicts are, when they occur, how to resolve them, and how to minimize them in your workflow.
🎥 Video: How to Resolve Merge Conflicts in Git (7 mins) - A practical walkthrough of resolving merge conflicts
What is a merge conflict?
A merge conflict is a situation that occurs when Git cannot automatically determine how to integrate changes from different branches. When this happens, Git marks the conflicting areas in the affected files and requires a developer to manually resolve these conflicts before the merge can be completed.
In essence, a merge conflict is Git saying: “I’m not sure which version of this code to keep, so I need you to decide.”

When a conflict occurs, Git will modify the affected files to show both versions of the conflicting code, separated by special marker lines:
<<<<<<< HEAD
This is the code from your current branch
=======
This is the incoming code from the branch you're merging
>>>>>>> feature/branch-name
Depending on your editor, the conflict might be color-coded, something like this:

- The section between
<<<<<<< HEADand=======shows the content from your current branch (often called the receiving branch) - The section between
=======and>>>>>>> feature/branch-nameshows the content from the branch you’re trying to merge (the source branch)
When do merge conflicts happen?
Merge conflicts typically occur in the following scenarios:
1. Line-level conflicts
The most common type of conflict happens when the same lines of a file have been modified differently in the two branches being merged.

2. File addition conflicts
Both branches add a file with the same name but different content.

3. File deletion conflicts
One branch modifies a file while another branch deletes it.

4. Directory structure conflicts
One branch changes a file while another changes the directory structure containing that file.
5. Binary file conflicts
Changes to binary files (like images) that Git can’t automatically merge.
⚠️ Note: Conflicts are more likely to occur when:
- Multiple developers work on the same files
- Branches diverge for long periods before merging
- Large, sweeping changes are made across many files
Example of a merge conflict and its resolution
Let’s walk through a typical merge conflict scenario and its resolution.
The scenario
Two developers are working on an HTML file. Developer A is working on the main branch, while Developer B is working on a feature branch called feature/new-header.
Starting point (both developers have this version):
<!DOCTYPE html>
<html>
<head>
<title>Our Website</title>
</head>
<body>
<header>
<h1>Welcome to Our Website</h1>
</header>
<main>
<p>This is our website content.</p>
</main>
</body>
</html>
Developer A changes the heading in header:
<!DOCTYPE html>
<html>
<head>
<title>Our Website</title>
</head>
<body>
<header>
<h1>Welcome to Our Company Website</h1> <!-- Notice 'Company' -->
</header>
<main>
<p>This is our website content.</p>
</main>
</body>
</html>
Developer B changes the same heading in feature/new-header:
<!DOCTYPE html>
<html>
<head>
<title>Our Website</title>
</head>
<body>
<header>
<h1>Welcome to Our Amazing Website</h1> <!-- Notice 'Amazing' -->
</header>
<main>
<p>This is our website content.</p>
</main>
</body>
</html>
The conflict
When Developer B tries to merge their feature branch into main after Developer A has already committed their changes:
$ git checkout main
$ git pull # Get Developer A's changes
$ git merge feature/new-header
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Now, the index.html file contains:
<!DOCTYPE html>
<html>
<head>
<title>Our Website</title>
</head>
<body>
<header>
<<<<<<< HEAD
<h1>Welcome to Our Company Website</h1>
=======
<h1>Welcome to Our Amazing Website</h1>
>>>>>>> feature/new-header
</header>
<main>
<p>This is our website content.</p>
</main>
</body>
</html>
The above conflict might look like this in your editor, including highlighting and buttons to accept one version or the other.

The resolution
Developer B needs to decide which version to keep or how to combine them.
<!DOCTYPE html>
<html>
<head>
<title>Our Website</title>
</head>
<body>
<header>
<h1>Welcome to Our Amazing Company Website</h1>
</header>
<main>
<p>This is our website content.</p>
</main>
</body>
</html>
After editing the file to resolve the conflict:
# Stage the resolved file
$ git add index.html
# Complete the merge with a commit
$ git commit -m "Merge feature/new-header, resolve heading conflict"
[main a1b2c3d] Merge feature/new-header, resolve heading conflict
The flow of resolving the conflict looks like this:

Tools for resolving conflicts
Git provides several approaches to resolve conflicts:
Command line
# See which files have conflicts
$ git status
# After manually editing conflicted files
$ git add <resolved-file>
$ git commit
Via Editor
Most modern IDEs have built-in Git conflict resolution tools that highlight conflicts and provide buttons to accept one version or the other, as well as a way to add & commit the resolved conflict.
Tips to avoid merge conflicts
While merge conflicts can’t be completely eliminated, you can reduce their frequency and complexity with these practices:
1. Pull before you push
Always pull the latest changes from the remote repository before pushing your own changes.
$ git pull origin main
$ git push origin main
2. Frequent small commits
Make smaller, focused commits rather than large, sweeping changes that touch many files.
# Instead of one large commit:
$ git add .
$ git commit -m "Add user authentication, profile page, and settings"
# Better approach:
$ git add auth/*
$ git commit -m "Add user authentication"
$ git add profile/*
$ git commit -m "Add user profile page"
$ git add settings/*
$ git commit -m "Add user settings page"
3. Short-lived branches
Don’t let feature branches live too long. The longer a branch exists separately from main, the more likely it is to develop conflicts.
4. Regular integration
Regularly merge or rebase your feature branches with the main branch to reduce divergence.
# While working on a feature branch
$ git checkout feature/my-feature
$ git pull origin main # Get latest main changes
# OR
$ git rebase main # Replay your changes on top of latest main
5. Clear team communication
Communicate with team members about which files you’re modifying to avoid simultaneous changes to the same areas.
6. Modular code design
Design your codebase to be modular, with separate files for separate functionality, to reduce the chances of developers needing to modify the same files.
7. Use a consistent code formatting style
Adopt a team-wide code formatting standard and use automatic formatters to avoid conflicts due to formatting differences.

💡 Tip: If you know you’ll need to merge significant changes, communicate with your team before starting to minimize conflicts.
Abort a problematic merge
If a merge becomes too complex, you can abort it and try a different approach:
$ git merge --abort
Further Reading
- Git Branches - Understanding how branches work
- Git Workflow Recommendation - Best practices for Git workflows
- Git Remote v Local - Working with remote repositories
- Git Rebasing - An alternative to merging that can help avoid some conflicts