Fix: CONFLICT (content): Merge conflict in [file] – Automatic merge failed
The Error
You run git merge, git pull, or git rebase and Git stops with:
Auto-merging src/app.js
CONFLICT (content): Merge conflict in src/app.js
Automatic merge failed; fix conflicts and then commit the result.If you then run git status, you see:
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: src/app.jsYou may also see needs merge if you try to run other Git operations while conflicts are unresolved:
error: you need to resolve your current index first
src/app.js: needs mergeWhy This Happens
A merge conflict occurs when Git cannot automatically combine changes from two branches. Specifically, both branches modified the same lines in the same file, and Git does not know which version to keep.
Here is a typical scenario:
- You create a feature branch from
main. - On
main, someone changes line 10 ofapp.js. - On your feature branch, you also change line 10 of
app.js. - You try to merge. Git sees two different edits to the same line and has no way to decide which one wins.
Git can automatically merge changes that touch different lines or different files. It only creates a conflict when the changes overlap.
Conflicts are not errors. They are Git asking you to make a decision.
How to Read Conflict Markers
When a conflict occurs, Git inserts markers into the affected file:
<<<<<<< HEAD
const port = 3000;
=======
const port = 8080;
>>>>>>> feature-branchHere is what each section means:
<<<<<<< HEADmarks the start of your current branch’s version (the branch you are merging into).=======separates the two versions.>>>>>>> feature-branchmarks the end of the incoming branch’s version (the branch you are merging from).
Your job is to replace this entire block — including the markers — with the code you actually want.
Fix 1: Resolve Manually in Your Editor
This is the most common approach and works with any editor.
Step 1: Check which files have conflicts:
git statusLook for files listed under “Unmerged paths” marked as both modified.
Step 2: Open the conflicting file in your editor. Search for <<<<<<< to find each conflict.
Step 3: For each conflict, decide what the final code should be. You have three choices:
- Keep your version (HEAD): Delete the incoming changes, the markers, and the separator.
- Keep the incoming version: Delete your changes, the markers, and the separator.
- Combine both: Write new code that incorporates both changes.
For example, if you want to keep the incoming port:
const port = 8080;Or if you want to combine both:
const port = process.env.PORT || 8080;Make sure no conflict markers (<<<<<<<, =======, >>>>>>>) remain in the file.
Step 4: Mark the file as resolved by staging it:
git add src/app.jsStep 5: Once all conflicts are resolved and staged, commit:
git commitGit opens your editor with a pre-populated merge commit message. Save and close it to complete the merge.
Fix 2: Use VS Code’s Merge Conflict UI
VS Code detects conflict markers and shows an inline UI with clickable options above each conflict:
- Accept Current Change — keeps your branch’s version (HEAD).
- Accept Incoming Change — keeps the other branch’s version.
- Accept Both Changes — keeps both versions, one after the other.
- Compare Changes — opens a side-by-side diff.
To use it:
- Open the conflicting file in VS Code. The conflict sections are highlighted in green (current) and blue (incoming).
- Click the option you want above each conflict block.
- If the file has multiple conflicts, resolve each one.
- Save the file.
- In the terminal, stage and commit:
git add src/app.js
git commitVS Code’s Source Control panel (the branch icon in the sidebar) also shows all conflicting files with a C badge. You can stage files directly from there.
Fix 3: Accept All of One Side (—theirs / —ours)
If you know you want to take one side’s version of an entire file, use git checkout:
To keep the incoming branch’s version (discard your changes to this file):
git checkout --theirs src/app.js
git add src/app.jsTo keep your branch’s version (discard the incoming changes to this file):
git checkout --ours src/app.js
git add src/app.jsTo accept one side for every conflicting file at once:
# Accept all incoming changes
git checkout --theirs .
git add .
# OR accept all of your current changes
git checkout --ours .
git add .Caution: This discards the other side’s changes entirely for those files. Only use this when you are confident you want one version over the other.
During a rebase, --ours and --theirs are swapped. In a rebase, --ours refers to the branch you are rebasing onto (usually upstream), and --theirs refers to your commits being replayed. This is the opposite of a merge. Double-check which side you want before running the command.
Fix 4: Abort the Merge Entirely
If you are not ready to deal with conflicts and want to go back to the state before the merge:
git merge --abortThis resets your working directory and index to the state before you ran git merge. No changes are lost from either branch — the merge simply did not happen.
Use this when:
- You merged the wrong branch by mistake.
- You need to do prep work before attempting the merge again.
- You want to try a different strategy (like rebasing instead).
Fix 5: Use a Merge Tool
Git can launch a visual merge tool that shows a three-way diff (base, local, remote):
git mergetoolThis opens each conflicting file in your configured merge tool. Popular options include:
- vimdiff (built-in, terminal-based)
- meld (graphical, cross-platform)
- kdiff3 (graphical, three-way merge)
- Beyond Compare (commercial)
- IntelliJ / WebStorm (built-in merge tool)
To configure your preferred tool:
git config --global merge.tool meldAfter resolving all conflicts in the tool, save and close it. Git marks the files as resolved. Then commit:
git commitNote: git mergetool creates .orig backup files by default. To disable this:
git config --global mergetool.keepBackup falseSpecial Cases
Conflicts During Rebase
When you run git rebase and hit a conflict, the workflow is slightly different from a merge:
CONFLICT (content): Merge conflict in src/app.js
error: could not apply abc1234... Your commit message
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".- Resolve the conflicts in each file (same as Fix 1 or Fix 2).
- Stage the resolved files:
git add src/app.js- Continue the rebase (do not run
git commit— the rebase handles it):
git rebase --continue- If more conflicts appear on subsequent commits, repeat steps 1-3.
To abort the entire rebase and go back to your original branch state:
git rebase --abortTo skip the current commit entirely (dropping those changes):
git rebase --skipConflicts in Binary Files
Git cannot merge binary files (images, PDFs, compiled assets). You will see:
warning: Cannot merge binary files: logo.png (HEAD vs. feature-branch)
CONFLICT (content): Merge conflict in logo.pngThere are no conflict markers to edit. You must choose one version:
# Keep the incoming version
git checkout --theirs logo.png
git add logo.png
# OR keep your current version
git checkout --ours logo.png
git add logo.pngIf you need to combine the binary files (for example, overlaying two images), do it outside of Git with the appropriate tool, then git add the result.
Conflicts in package-lock.json / yarn.lock
Lock files conflict constantly, and you should never manually edit them. Instead:
For npm (package-lock.json):
# Accept either version (it doesn't matter which)
git checkout --theirs package-lock.json
# Regenerate the lock file from the merged package.json
npm install
git add package-lock.jsonFor yarn (yarn.lock):
git checkout --theirs yarn.lock
yarn install
git add yarn.lockFor pnpm (pnpm-lock.yaml):
git checkout --theirs pnpm-lock.yaml
pnpm install
git add pnpm-lock.yamlThe key insight: the lock file is a derived artifact of package.json. Resolve conflicts in package.json first (manually), then regenerate the lock file by running the install command. The regenerated lock file is the correct resolution.
Prevention
Merge conflicts are a normal part of collaborative development, but you can reduce their frequency:
- Pull before you push. Run
git pull(orgit pull --rebase) before starting new work each day. The more in-sync you stay, the fewer conflicts you encounter. - Use short-lived feature branches. The longer a branch lives, the more it diverges from
main, and the harder the merge. Merge feature branches within a few days, not weeks. - Break up large files. A 500-line file that everyone edits is a conflict magnet. Splitting it into smaller, focused modules reduces the chance that two people touch the same lines.
- Communicate with your team. If two people are working on the same file, a quick message (“I’m refactoring the auth module this morning”) avoids painful overlapping edits.
- Use
git rerere. This built-in feature (“reuse recorded resolution”) memorizes how you resolve conflicts. If the same conflict appears again (common during repeated rebases), Git resolves it automatically. Enable it with:
git config --global rerere.enabled trueStill Not Working?
Conflict between a deleted and modified file
If one branch deleted a file and the other modified it, you see:
CONFLICT (modify/delete): src/old-module.js deleted in feature-branch
and modified in HEAD. Version HEAD of src/old-module.js left in tree.Decide whether the file should exist:
# Keep the file (accept the modification)
git add src/old-module.js
# OR delete it (accept the deletion)
git rm src/old-module.jsThen commit.
Submodule conflicts
If a submodule pointer conflicts, you see:
CONFLICT (submodule): Merge conflict in libs/my-submoduleCheck which commit each side points to:
git diff libs/my-submoduleThen set it to the commit you want:
cd libs/my-submodule
git checkout <desired-commit-hash>
cd ..
git add libs/my-submoduleGit rerere resolved it wrong
If you enabled rerere and it applied a previous resolution incorrectly:
# Undo the recorded resolution for a specific file
git checkout -m src/app.jsThis re-creates the conflict markers so you can resolve the file manually again. The next resolution you commit will replace the old recorded one.
Conflict markers left in committed code
If you accidentally committed a file that still contains <<<<<<< markers, the merge is technically complete but the code is broken. Find and fix them:
# Search your project for leftover conflict markers
grep -rn "<<<<<<< " .Edit the files to remove the markers, then create a new commit with the fix.
Related Articles
Fix: CONFLICT (content): Merge conflict in file — fix conflicts and then commit the result
How to fix Git merge conflicts during merge, rebase, cherry-pick, and pull — resolve conflict markers, use merge tools, accept theirs or ours, abort, and prevent future conflicts.
Fix: fatal: not a git repository (or any of the parent directories): .git
How to fix the 'fatal: not a git repository' error in Git by checking your working directory, initializing a repo, recovering a deleted .git folder, and resolving submodule, CI/CD, and IDE path issues.
Fix: git stash pop – CONFLICT, local changes would be overwritten, no stash entries found
How to fix git stash errors: 'CONFLICT' after git stash pop, 'Your local changes to the following files would be overwritten', 'No stash entries found', and 'Could not restore untracked files from stash entry'. Covers stash pop vs apply, conflict resolution, recovering dropped stashes, and stashing untracked files.
Fix: You are in 'detached HEAD' state
How to fix Git's 'detached HEAD' state, 'HEAD detached at xxx', 'HEAD detached from xxx', and 'Warning: you are leaving X commits behind'. Covers creating a branch, saving commits, recovering lost work with reflog, and when detached HEAD is intentional.