
Git Merge Conflicts Explained: A Step-by-Step Guide for Developers
Version control with Git is a cornerstone of modern software development, enabling teams to collaborate on complex projects seamlessly. At the heart of this collaboration is the ability to merge different lines of development, or branches. While often a smooth process, it can sometimes lead to the dreaded “merge conflict.”
Understanding how to navigate and resolve these conflicts is an essential skill for any developer. This guide will walk you through the fundamentals of Git merging and provide a clear, step-by-step process for resolving conflicts when they arise.
Understanding the Basics of Git Merge
Merging is the process of integrating changes from one branch into another. For instance, you might merge a feature
branch where you’ve developed a new function back into the main main
or master
branch. Git handles this integration in two primary ways.
The Fast-Forward Merge
The simplest type of merge is a fast-forward merge. This occurs when the branch you are merging into (e.g., main
) has not had any new commits since your feature branch was created. In this scenario, Git can simply move the pointer for the main
branch forward to point to the latest commit of your feature branch. It’s a clean, linear progression of history.
The Three-Way Merge
A more common scenario in a collaborative environment is a three-way merge. This is necessary when the history of the branches has diverged. In other words, while you were working on your feature
branch, other developers have pushed new commits to the main
branch.
Git cannot simply move the pointer forward. Instead, it performs a three-way merge by looking at three specific commits:
- The tip of the
main
branch. - The tip of your
feature
branch. - The common ancestor of both branches.
Git then creates a new merge commit that combines the changes from both branches, preserving the history of both lines of development.
What Is a Merge Conflict?
A merge conflict occurs when you try to merge two branches that have competing changes. Specifically, Git runs into a conflict when the same line of code has been edited in both of the branches you are trying to merge.
When this happens, Git cannot automatically decide which version of the code is correct. It pauses the merging process and hands control over to you, the developer, to make the final decision. Your repository is left in a MERGING
state until you resolve the conflict.
A Step-by-Step Guide to Resolving Merge Conflicts
Encountering a conflict can be intimidating, but the resolution process is logical and straightforward.
Step 1: Identify the Conflict
Your first clue will be a message in the terminal after running git merge
, stating that the merge failed due to a conflict. To see which files are affected, run the following command:
git status
Git will list the conflicted files under an “Unmerged paths” section.
Step 2: Open the Conflicted Files
When you open a conflicted file in your code editor, you will see special conflict markers added by Git. These markers visually separate the conflicting changes from the two branches.
<<<<<<< HEAD
: This marks the beginning of the conflicting content from your current branch (the one you are merging into).=======
: This separates the two conflicting versions of the code.>>>>>>> [branch-name]
: This marks the end of the conflicting content from the branch you are merging from.
Here’s an example of what you might see:
<<<<<<< HEAD
<div class="header">Welcome to Our Application</div>
=======
<div class="header">Welcome to Our New App</div>
>>>>>>> new-header-text
Step 3: Manually Edit and Resolve the Conflict
Your job is to edit the file to produce the final, correct version. You must decide which code to keep. You can:
- Keep the changes from
HEAD
. - Keep the changes from the other branch.
- Combine both changes in a meaningful way.
- Write entirely new code that replaces both versions.
Using the example above, if you decide the second version is the correct one, you would edit the file to look like this, removing all the Git conflict markers:
<div class="header">Welcome to Our New App</div>
Step 4: Stage the Resolved File
Once you have saved the edited file, you need to tell Git that you have resolved the conflict. You do this by staging the file using the git add
command.
git add <path/to/your/resolved/file.html>
Staging the file signals to Git that the conflict in that specific file is resolved and its current state should be included in the final merge commit. Running git status
again will show the file has moved from “Unmerged paths” to “Changes to be committed.”
Step 5: Commit the Merge
After resolving and staging all conflicted files, you can finalize the merge by creating the merge commit. Simply run:
git commit
Your editor will open with a pre-populated commit message, usually something like “Merge branch ‘feature-branch’ into ‘main'”. You can keep this message as is or add more detail. Once you save and close the commit message, the merge is complete.
Pro Tips for Preventing and Managing Conflicts
While conflicts are a normal part of development, you can minimize their frequency and complexity.
- Communicate with your team: Be aware of what others are working on. If you know two people are editing the same part of the codebase, expect a conflict.
- Pull frequently: Before starting new work and before pushing your changes, always pull the latest version of the main branch (
git pull origin main
). This keeps your local environment up-to-date and allows you to resolve smaller conflicts more frequently. - Keep branches short-lived and focused: The longer a branch lives without being merged, the more it will diverge from the main branch, increasing the likelihood of major conflicts. Aim for small, atomic changes.
- Use a graphical merge tool: Many developers prefer using a graphical merge tool. Tools built into editors like VS Code or standalone applications like GitKraken can provide a side-by-side view that makes it much easier to see the differences and choose which changes to keep. You can launch a configured tool by running
git mergetool
.
Source: https://linuxhandbook.com/courses/git-for-devops/git-merge-conflicts/