A merge conflict looks scarier than it is — Git is just asking you to pick a winner when two branches changed the same lines. Here's the process, step by step.
Merge conflicts are a normal part of working with a shared codebase — they're not a sign something went wrong, just Git flagging that a decision needs a human. A few habits make them far less painful.
Pull/rebase from the main branch frequently instead of letting a feature branch drift for weeks — the longer two branches diverge, the more likely they are to touch overlapping lines. Keep pull requests small and focused on one concern, since large sprawling changes touch more files and increase conflict surface area. Communicate with teammates when working in the same file simultaneously.
Most code editors (VS Code, IntelliJ, etc.) render conflict markers with inline "Accept Current," "Accept Incoming," and "Accept Both" buttons instead of requiring manual editing of the raw markers — this is usually faster and less error-prone than editing the text by hand, especially for conflicts touching many lines.
For an entire file (not a partial conflict), `git checkout --ours <file>` or `git checkout --theirs <file>` keeps one side's full version and discards the other — useful for generated files, lock files, or cases where you know one branch's version should simply win outright, rather than manually merging line by line.
A merge conflict happens when Git can't automatically combine changes from two branches because both branches modified the same lines of the same file (or one branch deleted a file the other modified). Git can merge non-overlapping changes automatically; overlapping changes require a human to decide the correct outcome.
<<<<<<< HEAD marks the start of your current branch's version of the conflicting lines. ======= separates your version from the incoming version. >>>>>>> branch-name marks the end of the incoming branch's version. You edit the file to keep whichever content is correct (yours, theirs, a combination, or something new entirely) and delete all three marker lines.
Run `git merge --abort` to cancel the merge and return to the exact state before you started it. This is safe to do at any point before you run `git commit` to finalize the merge — it discards nothing except the in-progress merge attempt itself.
Yes. After manually editing a conflicted file to remove the conflict markers and keep the correct content, run `git add <filename>` to tell Git the conflict is resolved for that file. Once every conflicted file has been added, run `git commit` to complete the merge (Git pre-fills a merge commit message you can usually accept as-is).
The mechanics of resolving the conflict (editing the markers, then git add) are the same either way. The difference is what happens next: during a merge, you finish with `git commit`. During a rebase, you finish with `git rebase --continue` instead, and this may repeat multiple times if several commits in the rebase each hit a conflict — one commit at a time.