Merge Conflicts
Understanding and Resolving Merge Conflicts in Git
Handling Merge Conflicts
When working with Git in collaborative projects, you will eventually face a merge conflict.
A merge conflict happens when Git cannot automatically reconcile differences between two commits that touch the same file(s). Knowing how to handle them is an essential Git skill.
What is a Merge Conflict?
A merge conflict occurs when Git doesn’t know how to combine changes from different branches.
This usually happens when:
- Two branches edited the same line in a file.
- One branch changed a file while another branch deleted it.
- Divergent histories exist, making automatic merging ambiguous.
When this happens, Git pauses the merge and asks you to resolve conflicts manually.
Example: Creating a Merge Conflict
Try this demo to reproduce a merge conflict:
# start fresh
mkdir git-conflict-demo && cd git-conflict-demo
git init
# create file with two lines
echo "Line 1" > file.txt
echo "Line 2" >> file.txt
git add file.txt
git commit -m "A: initial commit"
# create a feature branch and change Line 2
git checkout -b feature
echo "Line 1" > file.txt
echo "Feature edit" >> file.txt
git add file.txt
git commit -m "B: feature edits Line 2"
# switch back to main and edit Line 2 differently
git checkout main
echo "Line 1" > file.txt
echo "Main edit" >> file.txt
git add file.txt
git commit -m "C: main edits Line 2"
# try to merge main into feature (conflict will occur)
git checkout feature
git merge main
You will see Git reporting a conflict. Check with:
git status
How to Resolve Conflicts (CLI Steps)
-
Check conflicted files:
git status
-
Open the conflicted file. You’ll see conflict markers like this:
<<<<<<< HEAD Feature edit ======= Main edit >>>>>>> main
-
Edit the file to keep the correct/combined content (your decision).
-
Stage the resolved file:
git add file.txt
-
Complete the merge:
-
If merging:
git commit -m "Resolve conflict in file.txt"
-
If rebasing:
git rebase --continue
-
-
If you want to cancel:
git merge --abort git rebase --abort
Resolving Conflicts in VS Code (GUI)
-
Open your repo in VS Code.
-
Conflicted files will be highlighted in Source Control.
-
You’ll see options:
- Accept Current Change (keep your version)
- Accept Incoming Change (use the other branch’s version)
- Accept Both Changes (combine)
- Compare Changes
-
After resolving, save the file →
git add <file>
→git commit
(orgit rebase --continue
).
Useful Commands & Tips
-
Check conflicts:
git status git diff
-
Open external merge tool (if configured):
git mergetool
-
Keep only one side:
# Keep your branch git checkout --ours file.txt && git add file.txt # Keep incoming branch git checkout --theirs file.txt && git add file.txt
-
Abort if stuck:
git merge --abort git rebase --abort
Best Practices to Avoid Painful Conflicts
- Frequently sync your branch with
main
(merge or rebase). - Keep changes small and focused.
- Use clear branch names (
feat/login
,fix/api-error
). - Communicate with teammates when editing shared files (schemas, configs, APIs).
- Review PRs early to catch conflicts sooner.
Hands-On Exercise (Workshop Idea)
- Instructor provides a starter repo.
- Each student creates a feature branch and edits the same line in a shared file.
- Push changes and open a PR → trigger a merge conflict.
- Students resolve the conflict both via CLI and VS Code.
- Push the resolved branch and merge successfully.
Branching & Pull Requests
Why Branches?
Branches let you isolate work on new features or fixes without affecting the main code. They are the foundation of collaboration in Git.
Basic Branching Commands
# create and switch to new branch
git checkout -b feature/awesome-button
# make changes, stage, and commit
git add .
git commit -m "feat: add awesome button"
# push branch to remote
git push -u origin feature/awesome-button
Typical Pull Request Workflow
- Developer creates a new branch locally.
- Push branch to GitHub.
- Open a Pull Request (PR).
- Reviewers check code, suggest changes.
- Developer commits fixes and pushes again.
- After approval, PR is merged using repo’s merge policy.
Merge Strategies
- Merge Commit → Preserves full branch history.
- Squash and Merge → Combines all commits into one. Clean history.
- Rebase and Merge → Rewrites commits on top of main, no merge commit.
View history with:
git log --oneline --graph
PR Best Practices
- Keep PRs small & focused.
- Use meaningful branch names (
feat/
,fix/
,chore/
). - Write a clear PR description: what, why, how to test.
- Link related issues (
Fixes #123
). - Pull/rebase
main
before final merge to reduce conflicts. - Request reviewers and respond to feedback quickly.
Example PR Workflow
# make changes locally
git add .
git commit -m "fix: handle null user"
git push
# open PR on GitHub
After review & approval:
- Merge the PR according to repo policy.
- Optionally delete the feature branch.
Summary
- Merge conflicts happen when Git cannot auto-merge changes.
- Resolve them by editing files, staging, and committing.
- Use CLI (
git status
,git diff
,git add
,git commit
) or tools like VS Code. - Avoid conflicts by syncing often, keeping changes small, and communicating with your team.
- Branching + PR workflow ensures controlled, reviewed, and conflict-free collaboration.