Text Diff Checker ยท 6 min read
What Is a Merge Conflict and How Do You Fix It?
Merge conflicts are one of the most anxiety-inducing moments in collaborative software development. They are also entirely understandable and fixable once you know what they represent.
What Causes a Merge Conflict
A merge conflict occurs when two separate branches of a codebase (or two people working on the same file) have made changes to the same lines of the same file, and Git cannot automatically determine which change should take precedence.
Git handles the non-conflicting cases automatically. If Person A edits lines 10โ15 and Person B edits lines 50โ60, Git merges both changes without any conflict. The conflict arises only when both people edit the same section โ Git cannot know which edit represents the intended final state.
The three-way merge
Git's merge operation always involves three versions of the file:
- The base โ the common ancestor (the version the file was at before either branch diverged)
- The "ours" version โ the state of the file in the current branch
- The "theirs" version โ the state of the file in the branch being merged
If the base version of a section matches the "ours" version, Git knows the change came from "theirs" and applies it automatically. If it matches "theirs," the change came from "ours" and is applied. If both versions differ from the base โ both people changed the same lines โ Git marks it as a conflict and stops.
Reading Conflict Markers
When a merge conflict occurs, Git writes the conflicting section directly into the file using conflict markers. A conflicted file looks like this:
<<<<<<< HEAD
The price is $29.99 per month.
=======
The price is $24.99 per month.
>>>>>>> feature/pricing-update
Breaking this down:
<<<<<<< HEADโ marks the start of the conflict. Everything between this line and the=======is the "ours" version (your current branch โ in this case, HEAD)=======โ the separator between the two conflicting versions>>>>>>> feature/pricing-updateโ marks the end of the conflict. Everything between=======and this line is the "theirs" version (the branch being merged)
In this example, one branch changed the price to $29.99 and another changed it to $24.99. Git cannot know which is correct โ that is a human decision.
How to Resolve a Conflict
Resolving a merge conflict always involves three steps:
Step 1: Understand both versions
Read both the "ours" and "theirs" sections carefully. Sometimes one is clearly more recent or more correct. Sometimes both contain valid changes that need to be combined. Talk to the person whose change is in "theirs" if you are not sure which version is right.
Step 2: Edit the file to the desired final state
Delete the conflict markers (<<<<<<<, =======, >>>>>>>) and the version you do not want, leaving only the correct final content. You can also combine both versions if both changes should be kept. The conflict markers themselves must be completely removed โ leaving them in the file is a common mistake that breaks the build.
Possible resolutions:
- Keep "ours": delete the theirs section and all markers
- Keep "theirs": delete the ours section and all markers
- Keep both: combine the two versions in the correct order, delete all markers
- Write something new: replace the entire conflicted section with a third version that incorporates the intent of both
Step 3: Stage the resolved file and complete the merge
After editing, run git add <filename> to mark the conflict as resolved, then git commit to complete the merge. Git will create a merge commit that records the resolution.
Merge Conflict Tools
The raw text approach works but is error-prone. Most developers use a visual merge tool that shows the three versions side by side:
- VS Code has built-in merge conflict resolution โ click "Accept Current Change", "Accept Incoming Change", or "Accept Both Changes" for each conflict
- IntelliJ IDEA / WebStorm include a three-panel merge editor showing base, ours, and theirs
- vimdiff and Meld are popular standalone merge tools for Linux
- P4Merge (free) is a dedicated graphical merge tool
Configure your preferred tool with git config --global merge.tool vscode (or your tool of choice). Then run git mergetool during a conflict to open it automatically.
Preventing Merge Conflicts
The best merge conflict is the one that never happens. Practices that reduce conflicts:
- Merge or rebase frequently. The longer a branch diverges from its base, the more likely conflicts become. Integrate changes from main into your branch at least once per day on active projects.
- Keep pull requests small and focused. A PR that changes one thing in a few files is far less likely to conflict than a PR that rewrites many files across the codebase.
- Communicate about files. If two people need to heavily edit the same file, coordinate who goes first.
- Use feature flags instead of long-lived branches. Long-lived branches diverge; feature flags let code merge into main while remaining inactive until ready.
- Break up large files. A 2,000-line file is far more likely to experience conflicts than ten 200-line files with clear single responsibilities.
The Conflict Is Not an Error
New developers often interpret a merge conflict as something they did wrong. It is not. Merge conflicts are a normal, expected part of collaborative development. They mean two people were working in parallel โ which is the entire point of version control. Git stops and asks for human judgement because it correctly recognises that it cannot determine the right outcome by algorithm alone.
The conflict marker is Git saying: "I found two changes that I cannot reconcile automatically. Here they are. You decide." It is a request for collaboration, not a bug report.
References
- Chacon, S., & Straub, B. (2014). Pro Git (2nd ed.). Apress. git-scm.com/book.
- Torvalds, L., & Hamano, J. (2023). Git Reference Manual. git-scm.com.
- Spinellis, D. (2005). Version control systems. IEEE Software, 22(5), 108โ109.
- Loeliger, J., & McCullough, M. (2012). Version Control with Git. O'Reilly Media.
- Atlassian. (2023). Git merge conflicts. atlassian.com/git/tutorials.