4.5.8 · Coding › Software Engineering
Intuition Git ke peeche ek hi idea hai
Ek Git repository commits ka Directed Acyclic Graph (DAG) hoti hai. Har commit ek immutable snapshot hai jo apne parent(s) ki taraf point karta hai. Jo bhi tum karte ho — branching, merging, rebasing — sab sirf naye commits banana aur pointers ko move karna hai. Kuch bhi "lost" nahi hota; tum sirf graph pe labels idhar-udhar karte ho.
YE KYUN MATTER KARTA HAI: jab commits ko nodes aur branches ko sticky-notes (jo nodes pe point karti hain) ki taraf se dekho, to har "darawana" command obvious ho jaata hai.
Commit ::: poore tree ka ek immutable snapshot + metadata (author, message, parent SHA(s)).
Branch ::: ek movable pointer (ek 41-byte file) jo ek commit ki taraf point karta hai. Ek banana O(1) hai.
HEAD ::: ek pointer jo batata hai tum abhi kahan ho — usually kisi branch ki taraf.
Working tree / staging area (index) ::: tumhare editable files / wo snapshot jo next commit ke liye tayaar ho raha hai.
Intuition Branches saste KYUN hote hain
Ek branch literally .git/refs/heads/ mein ek file hai jisme ek SHA hota hai. Branch banana = 41 bytes likhna. Yahi poora raaz hai kyun Git branching ke liye encourage karta hai.
Branch ek named, movable pointer hai jo kisi commit ki taraf point karta hai; "us pe" banaye gaye naye commits pointer ko aage badhate hain.
HOW (commands):
git branch feature # create pointer, stay on current branch
git switch feature # move HEAD to feature (old: git checkout feature)
git switch -c feature # create + switch in one go
Intuition "Current branch" ka MATLAB kya hai
Jab tum commit karte ho, Git: (1) snapshot likhta hai, (2) uska parent = current commit set karta hai, (3) branch pointer jo HEAD point karta hai use naye commit pe update karta hai . Teesra step yahi wajah hai ki tumhari branch "aage badhti" hai.
Merging do branches ko combine karta hai ek naya merge commit banakar jiske two parents hote hain, dono histories preserve karte hue.
Fast-forward (FF): agar target branch ek direct ancestor hai, to Git sirf pointer ko aage slide kar deta hai — koi naya commit nahi chahiye. KYU: koi divergence nahi hai jise reconcile karna pade.
Three-way merge: branches diverge ho gayi hain. Git merge base (common ancestor) dhundh ke base → ours aur base → theirs ko combine karta hai.
Worked example Conflict ke saath Merge
git switch main
git merge feature
# CONFLICT in app.js
Ye step kyun? main aur feature dono ne apne last common ancestor ke baad line 10 edit ki → upar wale CONFLICT case mein aata hai.
Fix: <<<<<<< ======= >>>>>>> markers edit karo, phir git add app.js && git commit.
Rebasing tumhare commits leta hai, target ke saath unka merge base dhundha hai, aur har ek ko target tip ke upar brand-new commit ke roop mein re-apply karta hai — ek linear history produce karta hai.
Intuition Rebase ≠ merge KYU
Merge record karta hai ki do lines saath aayi (extra merge commit, sachi history). Rebase tumhare commits ko rewrite karta hai jaise tum latest base se shuru hue ho (clean, linear, lekin naye SHAs ).
Golden rule: un commits ko kabhi rebase mat karo jo tum already push/share kar chuke ho — tum aisi history rewrite kar doge jis par doosre depend karte hain.
Andar se HOW kaam karta hai (derivation):
git switch feature
git rebase main
feature aur main ka merge base M dhundho.
M ke baad har feature commit C 1 , … , C n ke diffs save karo.
feature ko main ke tip pe move karo.
Har diff ko order mein re-apply karo, naye commits C 1 ′ , … , C n ′ banate hue.
Worked example Interactive rebase (3 commits → 1 mein squash karo)
git rebase -i HEAD~3
# mark commits 2 and 3 as 'squash'
Ye step kyun? HEAD~3 base hai; editor tumhe reorder/squash/drop karne deta hai. Result hai kam, cleaner commits.
Cherry-picking ek single commit ka diff tumhari current branch pe naye commit ke roop mein re-apply karta hai (naya SHA).
Tum poora merge kiye bina doosri branch se ek fix chahte ho. Ye parent(C) → C ko patch ke roop mein compute karta hai aur jahan tum ho wahan apply karta hai.
git switch main
git cherry-pick a1b2c3d
Ye step kyun? a1b2c3d dwara introduce ki gayi change ko leta hai aur main pe laata hai. Agar surrounding code alag hai → conflict, merge jaisi tarah resolve karo.
Stashing tumhara dirty working tree + index ek stack pe save karta hai aur tumhe clean HEAD pe revert karta hai, taaki tum context switch kar sako.
Git branches switch karne se mana karta hai agar changes overwrite ho jaate. Stash = temporary commit jise tum baad mein pop kar sakte ho.
git stash # shelve changes
git switch hotfix # now clean, can switch
...fix...
git switch feature
git stash pop # reapply + drop from stack
Ye step kyun? pop = apply + stack se remove karo; agar stack pe rakhna hai to git stash apply use karo.
Bisect commit history par ek binary search perform karta hai wo pehla commit dhundne ke liye jisne bug introduce kiya, "good/bad" answers use karke.
git bisect start
git bisect bad # current is broken
git bisect good v1.0 # this old tag worked
# Git checks out a midpoint; you test & say:
git bisect good (or) git bisect bad
# repeat ~log2(N) times
git bisect reset # back to where you started
Ye step kyun : har answer commits ka aadha eliminate karta hai → logarithmic time mein culprit ko pinpoint karta hai.
Common mistake "Merge aur rebase ek hi kaam karte hain, isliye main shared branches rebase karunga."
Ye sahi kyun lagta hai: dono main ko tumhare kaam mein integrate karte hain aur result up-to-date code hota hai.
Ye galat kyun hai: rebase SHAs rewrite karta hai . Teammates jo tumhare purane commits pe kaam kar rahe the unke paas ab orphaned history hai → painful conflicts.
Fix: sirf local, unpushed branches rebase karo; shared/public branches ke liye merge use karo.
Common mistake "Cherry-pick ek commit ke liye merge jaisa hi hai."
Ye sahi kyun lagta hai: dono ek change laate hain.
Ye galat kyun hai: cherry-pick change ko naye commit ke roop mein duplicate karta hai. Agar baad mein us branch ko merge karo, toh ek hi change do baar exist karta hai → possible conflicts.
Fix: integration ke liye merge/rebase prefer karo; cherry-pick sirf isolated hot-fixes ke liye use karo.
git stash pop hamesha sab kuch restore karta hai."
Ye sahi kyun lagta hai: usually karta hai.
Ye galat kyun hai: agar reapplying mein conflicts hain, pop stash entry rakhta hai (achhi baat!) lekin conflict markers chod deta hai; log phir git stash drop karte hain aur kaam kho dete hain.
Fix: pehle conflicts resolve karo; stash sirf clean pop pe auto-drop hota hai.
Common mistake "Fast-forward merge ek merge commit banata hai."
Ye sahi kyun lagta hai: "merge" sunne se lagta hai ye hamesha ek commit banata hai.
Ye galat kyun hai: FF sirf pointer move karta hai — koi naya commit nahi. Agar tum chahte ho ki merge commit record ho, to git merge --no-ff use karo.
Recall Feynman: ek 12-saal ke bacche ko explain karo
Socho tumhara project history LEGO photos ki ek chain hai. Branch ek sticky-note hai jo ek photo pe label lagata hai. Committing = nayi photo lena aur apna sticky-note uspe move karna. Merge = do chains ko ek special "hum yahan mile" wali photo se glue karna. Rebase = apni recent photos ko peel off karna aur unhe newest chain ke upar phir se lena taaki ek seedhi line jaisi lage. Cherry-pick = sirf ek achhi photo apne album mein copy karna. Stash = apna adha-bana LEGO ek box mein rakhna taaki table clean ho. Bisect = ek guessing game: "kya LEGO aadhe mein toota hai? haan? to break pehle aadhe mein hai" — tab tak aadha karte raho jab tak exact bura brick na mil jaye.
"Big Monkeys Really Crave Sweet Bananas" → B ranch, M erge, R ebase, C herry-pick, S tash, B isect.
Aur golden rule ke liye: "Rebase Local, Merge Shared."
Recall Active recall — note band karo aur answer karo
Commit hamesha kya do cheezein point karta hai? (snapshot + parent SHA)
Merge kab koi naya commit produce NAHI karta?
Ek pushed branch kabhi rebase na karne ki ek wajah?
Bisect ko 1024 commits ke liye kitne tests chahiye?
Git branch physically kya hai? Ek movable pointer (.git/refs/heads/ mein ek chhoti file) jisme ek commit ka SHA hota hai.
HEAD kya point karta hai? Tumhari current location — usually ek branch (jo badle mein ek commit ko point karti hai).
Git fast-forward merge kab karta hai? Jab target branch source ki direct ancestor ho, to ye sirf pointer ko aage slide karta hai bina merge commit ke.
Ek (three-way) merge commit ke kitne parents hote hain? Do.
Merge base kya hota hai? Merge ho rahi do branches ka most recent common ancestor.
Merge conflict exactly kab hota hai (per region)? Jab dono sides ne base ke relative ek hi region ko alag-alag change kiya ho (O = B , T = B , O = T ).
Rebase commit SHAs ke saath kya karta hai? Ye brand-new commits banata hai naye SHAs ke saath (history rewrite hoti hai).
Rebasing ka golden rule batao. Un commits ko kabhi rebase mat karo jo already push/share ho chuke hain.
Merge aur rebase ke outcome mein kya fark hai? Merge ek merge commit record karta hai (sachi, branched history); rebase replayed commits ki linear history produce karta hai.
Cherry-pick kya apply karta hai? Ek single commit ka diff (parent→commit) current branch pe naye commit ke roop mein re-apply kiya jaata hai.
Cherry-pick karne ke baad usi branch ko merge karne ka risk kya hai? Change do baar appear hoti hai (duplicate commits) → potential conflicts.
Git stash kya karta hai? Dirty working tree + index ko ek stack pe save karta hai aur clean HEAD pe revert karta hai.
Stash pop aur stash apply mein kya fark hai? pop = apply phir stack se remove karo; apply entry stack pe rakhta hai.
Git bisect kaunsa algorithm use karta hai? Commit history par binary search.
Bisect ko N commits ke liye kitne tests chahiye? Lagbhag ⌈log₂ N⌉.
Bisect session abandon karne ka command kya hai? git bisect reset.
FF possible hone ke bawajood merge commit force kaise karo? git merge --no-ff.
Directed Acyclic Graph — commit history ki underlying data structure
Binary Search — git bisect ke andar ka engine
Three-way merge algorithm
Trunk-based vs GitFlow — in operations pe bane workflows
Conflict resolution aur Diff and patch (Myers algorithm)
Immutability and content-addressable storage — commits mein SHAs kyun hote hain
advanced by new commit on