Reading Conflict Markers
Markers padho, dono side samjho, sahi choose karo, aur markers HATAO! Commit mein markers reh jaana badi galti hai.
<<<<<<< HEAD — Marks the beginning of the conflict. Lines below this are YOUR current branch's version.
======= — The separator. Divides your changes from their changes.
>>>>>>> branch-name — Marks the end of the conflict. Lines above this (after =======) are the INCOMING branch's version.
These markers are inserted directly into your file by Git. You must remove these markers and choose the correct code before committing. Leaving markers in a committed file is a serious mistake.
# What a conflict looks like in your file:
function getConfig() {
<<<<<<< HEAD
return { port: 3000 }; // YOUR version (current branch)
=======
return { port: 8080 }; // THEIR version (incoming branch)
>>>>>>> feature/api-port
}
# Resolution options:
# 1. Keep yours: return { port: 3000 };
# 2. Keep theirs: return { port: 8080 };
# 3. Combine: return { port: process.env.PORT || 3000 };
# 4. Write new: return { port: 3000, host: "localhost" };
HEAD = the branch you are currently ON (where you ran git merge).
branch-name (after >>>>>>>) = the branch you are merging IN.
If you're on main merging feature: HEAD = main's version, feature = incoming version.
If you're on feature rebasing onto main: HEAD = main's version (rebase reverses the perspective!).
Understanding which side is which is crucial for making the right choice.
# Scenario: On main, merging feature
git checkout main
git merge feature
# <<<<<<< HEAD -> main's version
# =======
# >>>>>>> feature -> feature's version
# Scenario: On feature, rebasing onto main (perspective flips!)
git checkout feature
git rebase main
# <<<<<<< HEAD -> main's version (because rebase applies ON main)
# =======
# >>>>>>> feature -> your feature's version
# Always read the branch name after >>>>>>> to confirm!
A single file can have MULTIPLE conflict sections.
Each conflict has its own set of <<<<<<<, =======, >>>>>>> markers.
You must resolve EACH conflict individually.
Search for <<<<<<< in your editor to find all conflicts.
Don't assume resolving one conflict fixes the whole file.
After resolving, search again for <<<<<<< to verify none were missed.
# File with multiple conflicts:
const config = {
<<<<<<< HEAD
port: 3000,
=======
port: 8080,
>>>>>>> feature
host: "localhost",
};
function start() {
<<<<<<< HEAD
console.log("Starting...");
=======
console.log("Bootstrapping...");
>>>>>>> feature
}
# Two separate conflicts! Resolve each one independently.
grep -n "<<<<<<<" file.js or your IDE's search to find ALL conflict markers before you start resolving. Count them. After resolving, search again and verify the count is zero. Missing even one conflict marker means broken code in production.git status — lists all conflicted files and their conflict type.
git diff — shows only the conflicting sections (during a merge).
git diff --name-only --diff-filter=U — lists only unmerged (conflicted) file names.
git ls-files -u — lists unmerged files with stage numbers (1=common, 2=ours, 3=theirs).
These commands help you understand the scope of conflicts before diving into resolution.
# List all conflicted files
git status
# Unmerged paths:
# both modified: app.js
# added by them: new-module.js
# Quick list of just the filenames
git diff --name-only --diff-filter=U
# app.js
# new-module.js
# See the conflicting sections
git diff
# Shows only the parts that Git couldn't auto-merge
# Detailed unmerged file info
git ls-files -u
# 100644 abc123 1 app.js (common ancestor)
# 100644 def456 2 app.js (ours - HEAD)
# 100644 ghi789 3 app.js (theirs - merging branch)
git ls-files -u correspond to the three-way merge: stage 1 = common ancestor (base), stage 2 = ours (HEAD), stage 3 = theirs (incoming). You can extract each version using git show :1:filename, git show :2:filename, git show :3:filename.Keep yours: Your change is correct, discard theirs.
Keep theirs: Their change is correct, discard yours.
Keep both: Combine the changes if they're complementary.
Write new: Neither side is fully correct, write a new solution.
Most conflicts are resolved by combining or rewriting, not simply choosing one side.
Always understand WHY both sides made their changes before choosing.
# Strategy 1: Keep yours
# <<<<<<< HEAD
console.log("v2"); # Keep this
# =======
console.log("v1"); # Discard this
# >>>>>>> feature
# Result: console.log("v2");
# Strategy 2: Combine both
# <<<<<<< HEAD
function login() {}
# =======
function logout() {}
# >>>>>>> feature
# Result:
function login() {}
function logout() {}
# Strategy 3: Write new
# <<<<<<< HEAD
port = 3000
# =======
port = 8080
# >>>>>>> feature
# Result:
port = process.env.PORT || 3000
Lo kar liya — Key Points:
- ✅ <<<<<<< HEAD marks the start of your current branch's version
- ✅ ======= separates your version from the incoming version
- ✅ >>>>>>> branch-name marks the end of the incoming branch's version
- ✅ HEAD = the branch you're ON, branch-name = the branch you're merging IN
- ✅ A single file can have multiple conflicts, each with its own set of markers
- ✅ You MUST remove all conflict markers before committing; leaving them in is a critical error
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login