How do you resolve a merge conflict in Git?
Run git status to see the conflicted files, open each one and find the markers <<<<<<<, ======= and >>>>>>>. Edit the code to the correct final version, delete the markers, then git add the file and run git commit (or git rebase --continue during a rebase). Test before you push.
Explain it simply
A merge conflict happens when two branches change the same lines of the same file, or one branch edits a file that the other deleted. Git can combine changes in different places by itself, but when both sides touched the same spot it does not know which version is right. So it stops and asks you to decide.
A conflict is not an error or a sign that something broke. It is Git saying "a human needs to look at this".
Example
You are on main and merge feature/discount. Both changed the same line in cart.js.
git merge feature/discountAuto-merging cart.js
CONFLICT (content): Merge conflict in cart.js
Automatic merge failed; fix conflicts and then commit the result.Open cart.js:
<<<<<<< HEAD
const DELIVERY_FEE = 40;
=======
const DELIVERY_FEE = 0; // free delivery during sale
>>>>>>> feature/discount- Between
<<<<<<< HEADand=======is your current branch (main). - Between
=======and>>>>>>> feature/discountis the incoming branch.
Decide the correct result. Maybe the team agreed free delivery only above a cart value, so you write:
const DELIVERY_FEE = cartTotal >= 499 ? 0 : 40;Then finish the merge:
git add cart.js
git commitHow it works
Step by step:
- Run
git status. Files under "Unmerged paths" have conflicts. - Open each file and search for
<<<<<<<. - Understand both changes. Read the commit messages or ask the teammate who made the other change. Do not just pick your own side.
- Edit to the final version and remove all three marker lines.
- Run the tests or the app to make sure the combined code works.
git addeach resolved file. This tells Git the conflict is fixed.git committo complete the merge. During a rebase, usegit rebase --continueinstead.
If things get messy, git merge --abort returns the branch to how it was before the merge.
Real-world use
On a team project, conflicts are common in files many people touch: routes, config files, package.json and lock files. VS Code shows "Accept Current", "Accept Incoming" and "Accept Both" buttons above each conflict, which is handy, but you still need to read the result. For lock files, it is usually safer to take one side and regenerate the file with the package manager.
Common mistakes
- Leaving a
=======or>>>>>>>line in the file and committing it. The build breaks. - Clicking "Accept Current" on everything to make the conflict go away, which silently drops a teammate's work.
- Forgetting
git addand wondering whygit commitrefuses. - Not testing after resolving. Code can be free of markers and still be wrong.
- Letting a feature branch drift for weeks. Merging
maininto your branch often keeps conflicts small.
What to say in the interview
"A conflict happens when both branches change the same lines. I run git status to find the conflicted files, open each one, and look at the section between the conflict markers. I talk to the other developer if I am not sure about their change, then edit the code to the correct combined version and delete the markers. After running the tests, I git add the files and commit, or continue the rebase. If needed, git merge --abort gets me back to a clean state. To avoid big conflicts, I keep branches short-lived and sync with main often."
Follow-up questions
- What does
HEADmean in the conflict markers? - How is resolving a conflict during a rebase different from during a merge?
- How do you resolve a conflict in a pull request on GitHub?
- How can a team reduce merge conflicts?
Go deeper
Read these once the basics above feel easy.
You can take one side for a whole file without editing by hand: git checkout --ours cart.js keeps your branch's version and git checkout --theirs cart.js keeps the incoming version. Be careful: during a rebase the meanings flip, because "ours" is the branch you are rebasing onto. git config --global merge.conflictstyle diff3 adds a third section showing the original common version, which makes it much easier to see what each side actually changed.