Resolve a merge conflict step by step
Git says I have merge conflicts — how do I fix them?
Short answer
Git pauses and marks the clashing sections with <<<<<<<, ======= and >>>>>>>. Edit each file to the version you actually want, delete the markers, git add the file, then git merge --continue. If it gets overwhelming, git merge --abort returns you to exactly where you started.
git status
# edit the conflicted files, then:
git add .
git merge --continue
The standard resolve loop — status tells you which files need attention
Does this match your situation?
- 'CONFLICT (content): Merge conflict in <file>' appears after a merge, pull or rebase.
- Files contain <<<<<<< HEAD and >>>>>>> markers.
- git status lists files as 'both modified'.
Step-by-step fix
See exactly which files are conflicted
Only the listed files need your attention — Git has already merged everything else automatically. Knowing the scope makes the job feel far smaller than it first appears.
step 1git status git diff --name-only --diff-filter=UUnderstand the conflict markers
Everything between <<<<<<< and ======= is your side; everything between ======= and >>>>>>> is theirs. You are not obliged to pick one — the right answer is often a combination of both.
step 2<<<<<<< HEAD const maxHealth = 100; // your version ======= const maxHealth = 150; // the incoming version >>>>>>> feature/balanceDelete all three marker lines when you're done. Leaving one behind is the most common cause of a broken build after a merge.
Edit each file to the version you want
Work through the files one at a time. If one side is wholly correct, Git can take it for you without manual editing.
step 3# take your side entirely: git checkout --ours src/config.ts # take their side entirely: git checkout --theirs src/config.ts # or open a visual three-way merge tool: git mergetoolMark each file resolved and finish the merge
Staging a conflicted file is how you tell Git you've settled it. Once all of them are staged, continue — Git creates the merge commit.
step 4git add src/config.ts git status # confirm nothing is left unmerged git merge --continue # during a rebase: git rebase --continueBail out if it's gone wrong
Abort restores the exact state from before the merge started. There's no penalty for aborting and trying again with a clearer head or a smaller merge.
step 5git merge --abort # during a rebase: git rebase --abort
Why this works
Git merges by finding the common ancestor of both branches and applying each side's changes relative to it. When both sides modified the same region, there is no mechanical way to know which the author intended, so Git stops rather than guess. Marking a file resolved is literally just staging it: the index is what the merge commit will be built from, so once every conflicted path has a single agreed version in the index, the merge can complete.
How to stop it happening again
- Merge or rebase from main frequently — small, regular integrations rarely conflict.
- Keep pull requests small and focused on one area of the codebase.
- Enable git rerere so repeated conflicts during long rebases resolve themselves.
- Agree on formatting and enforce it automatically, so reformatting doesn't manufacture conflicts.
Commands used in this guide
git mergeCombine another branch's history into the current one.
git mergetoolOpen a visual three-way diff tool to resolve conflicts.
git rerereRemember how you resolved a conflict and replay it automatically next time.
git statusShow what's changed, what's staged, and what Git is ignoring.
git checkoutThe old all-in-one: switch branches, restore files, or detach HEAD.
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
What do <<<<<<<, ======= and >>>>>>> mean in Git?
They delimit a conflict. Content between <<<<<<< HEAD and ======= is from your current branch; content between ======= and >>>>>>> is from the branch being merged in. You edit the region into the correct final version and delete all three marker lines.
How do I cancel a merge with conflicts?
git merge --abort restores your branch and working directory to exactly the state before the merge began. If you're mid-rebase, git rebase --abort does the equivalent.
What do --ours and --theirs mean during a conflict?
--ours is the branch you're currently on and --theirs is the one being merged in. Be careful during a rebase: the sides are swapped, because your commits are being replayed on top of the other branch.
Can I make Git resolve the same conflict automatically next time?
Yes — git config --global rerere.enabled true. Git records how you resolved each conflict and replays that resolution whenever the identical conflict reappears, which is a huge time-saver when rebasing a long-lived branch repeatedly.
Related rescue guides
How do I undo a Git merge?
If the merge hasn't been pushed, git reset --hard HEAD~1 removes it cleanly. If it has been pushed, use git revert -m 1 <merge-hash> so history stays valid for everyone else. And if you're still in the middle of a conflicted merge, git merge --abort is all you need.
Read the fix →Usually recoverableMy rebase went wrong and my commits are gone — how do I get them back?
The pre-rebase commits are still in the object database. git reflog shows the position from before the rebase started, and ORIG_HEAD is a shortcut to it — git reset --hard ORIG_HEAD usually restores everything in one command.
Read the fix →Always fixableHow do I undo a commit that's already on the remote?
On a shared branch, use git revert <hash> — it adds a new commit that reverses the change, so nobody else has to do anything. Rewriting with reset plus a force-push is only appropriate on a branch you're certain nobody else has pulled.
Read the fix →Always fixableI committed to main instead of my feature branch — how do I move the commits?
Create a branch at your current position to keep the commits, then reset the branch you polluted back to where it should be. Nothing is lost because the new branch holds the commits the whole time.
Read the fix →