Conflict. The very word makes developers flinch. In Git, conflicts aren’t disasters—they’re conversations. They happen when two branches edit the same lines, or when history collides. Git can’t guess which change to keep, so it asks you. Resolving conflicts is not about fighting Git; it’s about making peace between divergent edits. This chapter teaches you how to approach conflicts with calm, skill, and even creativity.
Why Conflicts Happen
Conflicts occur when:
- Two branches edit the same line differently.
- One branch deletes a file another edits.
- Renames clash or files move in incompatible ways.
Visualization of conflict scenario:
gitGraph
commit id: "A"
branch feature1
checkout feature1
commit id: "Edit line X"
checkout main
branch feature2
checkout feature2
commit id: "Edit same line X differently"
checkout main
merge feature1
merge feature2
When merging, Git doesn’t know which edit wins. That’s your job.
Recognizing a Conflict
During merge or rebase, Git stops and marks files as conflicted:
git merge feature
Output:
Auto-merging app.py
CONFLICT (content): Merge conflict in app.py
Automatic merge failed; fix conflicts and then commit the result.
git status shows conflicted files clearly.
Conflict Markers
Inside the file, Git inserts markers:
<<<<<<< HEAD
print("Hello from main")
=======
print("Hello from feature")
>>>>>>> feature
Your job is to edit until it makes sense.
Resolving Conflicts Manually
Steps:
- Open conflicted file.
- Edit markers away, keeping correct code.
- Stage the file:
git add app.py. - Complete merge:
git commit.
Example resolution:
print("Hello from both worlds")
Tools for Conflict Resolution
Manual editing works, but tools help:
- VS Code: offers buttons to accept current, incoming, or both.
- GitKraken / Sourcetree: visual merge tools.
- vimdiff / meld: classic diff tools.
Configure your favorite as Git’s mergetool:
git config --global merge.tool vimdiff
git mergetool
Aborting and Restarting
If conflict resolution spirals out of control, you can abort:
git merge --abort
git rebase --abort
This resets to before the merge or rebase attempt. Start fresh.
Conflict Resolution Workflow
Visualization of process:
flowchart TD
Start[Merge starts] --> Conflict{Conflict detected?}
Conflict -->|Yes| Edit[Manual edit / mergetool]
Edit --> Stage[git add]
Stage --> Commit[git commit completes merge]
Conflict -->|No| Done[Merge succeeds automatically]
Solo Workflow Example
As a solo dev, conflicts usually happen when rebasing or merging experimental branches into main. Resolving them is straightforward—you choose which version of your own code wins.
Example:
git checkout main
git merge experiment
# resolve conflicts
git add .
git commit
Team Workflow Example
On a team, conflicts are inevitable. Two developers edit the same function differently. During pull request merge, Git surfaces the conflict. The team discusses, decides the right approach, and resolves.
Visualization:
flowchart LR
DevA[Dev A change] --> Conflict
DevB[Dev B change] --> Conflict
Conflict --> Resolution[Team resolves together]
Resolution --> MergeCommit[Final merged history]
Conflict resolution becomes collaboration, not just editing.
Strategies to Minimize Conflicts
- Pull frequently to stay updated.
- Communicate with teammates about hot spots.
- Break large changes into smaller commits.
- Use feature flags to integrate early.
Conflicts can’t be eliminated, but they can be reduced.
Think Different Mindset
Conflicts aren’t bugs—they’re conversations between branches. They remind us that code is shared, history is shared, and choices matter. Resolving conflicts is less about fixing code and more about reconciling perspectives. It’s Git teaching us collaboration through friction.
Conflicts are inevitable in Git, but they’re not enemies. They’re invitations to clarity. With practice, you’ll move from panic to patience, resolving conflicts quickly and even appreciating them as moments of collaboration. In the next chapter, we’ll explore tags and versioning—how to mark milestones in history and give releases names.