The Dreaded Conflict
For many developers, the words CONFLICT (content): Merge conflict in ... induce a mild panic. However, conflicts are a normal part of collaboration. They simply mean that Git needs human intervention to decide how to integrate two divergent sets of changes.
A conflict occurs when:
- Two branches have changed the same part of the same file.
- One branch deleted a file while another branch modified it.
Git is smart enough to merge changes in different parts of the same file automatically. But when lines overlap, it stops and asks for help.
The Anatomy of a Conflict
When a conflict happens, Git pauses the merge process and marks the problematic files as “Unmerged”. If you open such a file, you will see standard conflict markers:
<<<<<<< HEAD
var taxRate = 0.20;
=======
var taxRate = 0.22;
>>>>>>> feature/new-tax-laws
<<<<<<< HEAD: The content between this line and=======is what exists in your current branch (the one you are merging into).=======: The separator.>>>>>>> feature/new-tax-laws: The content between the separator and this line is what is coming from the incoming branch.
Manual Resolution
To resolve the conflict, you must edit the file to look exactly how you want the final result to be. This means removing the markers (<<<<<<<, =======, >>>>>>>) and choosing one version, or combining them.
Example Resolution: If you decide the new tax rate should be used, you edit the file to:
var taxRate = 0.22;
After editing, you must stage the file to tell Git “I have resolved this.”
git add file.js
git commit
Note that git commit without arguments will open your editor with a default merge message.
Aborting a Merge
Sometimes you realize you are in over your head or you started the merge on the wrong branch. You can always bail out.
git merge --abort
This commands resets your working directory to the state before the merge began, wiping away all conflict markers and partial changes.
Using Merge Tools
While manual editing is fine for simple conflicts, complex ones benefit from a dedicated “Merge Tool” (like KDiff3, Meld, P4Merge, or VS Code’s built-in 3-way editor).
To configure a tool (e.g., VS Code):
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
Then, when in a conflict state:
git mergetool
“Ours” vs “Theirs”
Sometimes you know that you strictly want to keep “your” version or fully accept “their” version for a specific file, without looking at the details.
To checkout your version (ignoring incoming changes):
git checkout --ours path/to/file
To checkout their version (overwriting your changes):
git checkout --theirs path/to/file
Be careful! This discards the other side’s changes completely for that file.
Binary Conflicts
Git cannot show diffs for binary files (images, compiled binaries). If you have a conflict in image.png, you have to choose one whole file or the other.
# Keep our image
git checkout --ours image.png
git add image.png
What does the '=======' marker represent in a conflict file?
Accepting Their Changes
# During a merge conflict, you decide to fully accept the incoming version for 'config.json' git --theirs config.json