Core Concepts 7 min read Updated Oct 3, 2026

Resolving Merge Conflicts

Merge conflicts have an outsized reputation for being scary, mostly because the first one tends to happen before anyone's explained what the on-screen markers actually mean. Once you can read them, resolving a conflict is a mechanical, low-drama process almost every time.

Why a conflict happens

Git merges automatically whenever it can - it only stops and asks you to resolve something when it genuinely can't decide on its own, which almost always means the same lines of the same file were changed differently on the two branches being combined (or one side edited a file the other side deleted). Git is deliberately conservative here: it would rather stop and ask than silently guess wrong about which version you meant to keep.

Reading the conflict markers

When a conflict happens, Git writes both versions directly into the file, wrapped in markers:

<<<<<<< HEAD
const greeting = "Hello there";
=======
const greeting = "Hi, welcome!";
>>>>>>> feature/greeting-update

Everything between <<<<<<< HEAD and the ======= divider is your current branch's version. Everything between the divider and >>>>>>> branch-name is the incoming branch's version. Git hasn't decided anything for you - it's handed you both options, in place, and is waiting for you to edit the file into what it should actually say.

The resolution process

  1. Run git status - it lists every file with unresolved conflicts.
  2. Open each conflicted file and find the marker blocks. For each one, decide: keep your version, keep the incoming version, or write something that combines both.
  3. Delete the <<<<<<<, =======, and >>>>>>> lines themselves - they're not part of either version and will break your code if left in.
  4. Save the file, then git add it to mark that specific conflict as resolved.
  5. Once every conflicted file is staged, finish with git commit (for a merge) or git rebase --continue (if the conflict came up during a rebase).
Changed your mind partway through? git merge --abort or git rebase --abort backs out completely and returns everything to exactly how it was before you started - there's no penalty for bailing out and trying again once you've had a closer look.

Tools that make this easier

Most code editors (VS Code included) detect conflict markers automatically and show clickable "Accept Current / Accept Incoming / Accept Both" options right above each block, which is usually faster than hand-editing the markers for anything beyond a one-line conflict. git mergetool launches a dedicated three-way merge tool if you have one configured, useful for conflicts across many files at once.

Reducing how often this happens

Conflicts scale with how long branches live and how large they get before merging - a branch that's three days old and touches one file will almost never conflict; a branch that's three weeks old and touches forty files, almost certainly will. Pulling the target branch into your feature branch regularly while you work (rather than only at the very end) surfaces small conflicts early, when they're easy, instead of one large one at the end, when they're not.

Next up: conflicts are one kind of mistake you fix by editing forward. The next guide covers the other kind - undoing something that's already happened, and the three very different commands people use for it.
Share this guide

Was this guide helpful?

Thanks for the feedback!

Want more hands-on AI builds like this?

APA Mastery runs live, practical sessions on working with modern AI tools - not just theory.

See What's On →