How to handle merge conflicts in a pull request
conflict markers, git merge vs git rebase, resolving conflicts in editor, git mergetool, force push after rebase, conflict prevention strategies
What Causes Merge Conflicts
A merge conflict occurs when two branches modify the same lines of a file. Git cannot automatically decide which version wins, so it stops and asks you to decide.
Reading Conflict Markers
<<<<<<< HEAD (your branch)
const timeout = 5000;
=======
const timeout = 3000;
>>>>>>> upstream/mainEverything between HEAD and ======= is your version. Everything between ======= and the closing marker is the incoming version. Delete the markers and keep the correct code.
Resolving a Conflict
# Fetch upstream changes
git fetch upstream
# Rebase your branch onto upstream/main
git rebase upstream/main
# Git pauses at each conflict -- resolve, then:
git add src/config.js
git rebase --continue
# Push with force (required after rebase)
git push origin fix/your-branch --force-with-leaseUse --force-with-lease, not --force. It fails safely if someone else pushed to your branch since your last pull.
Conflict Prevention
Sync with upstream before starting work. Keep PRs small and focused -- large PRs touch more files and generate more conflicts. The more often you sync, the smaller and easier conflicts become.
Using a Merge Tool
For complex conflicts across many files, a visual merge tool is faster than editing raw conflict markers. Configure one with: git config --global merge.tool vimdiff or use VS Code as the merge editor: git config --global merge.tool vscode. Run git mergetool after a failed rebase to open each conflicted file in the configured tool. Most modern editors have built-in merge conflict UIs that highlight the three versions -- yours, theirs, and the common ancestor -- side by side.
