Git-এ Branch আসলে কী?
সবচেয়ে অবাক করা সত্যটা আগে বলি: একটা branch আসলে শুধুই একটা ফাইল, যার ভেতরে ৪০ অক্ষরের একটা commit hash লেখা থাকে। এর বেশি কিছু না।
ভেতরে কী ঘটে
Git-এর সবকিছু commit-কে ঘিরে। প্রতিটা commit-এর একটা SHA-1 hash থাকে, আর প্রতিটা commit তার parent commit-কে point করে। ফলে commit-গুলো মিলে একটা chain বা graph তৈরি হয় (DAG — Directed Acyclic Graph)।
Branch হলো এই graph-এর কোনো একটা commit-এর দিকে তাক করা একটা movable pointer বা লেবেল মাত্র। আপনি নিজেই দেখতে পারেন:
cat .git/refs/heads/main
# আউটপুট: a3f5c9d2e8b1... (একটা commit hash)
ব্যস, এটাই আপনার main branch। একটা ৪১ বাইটের ফাইল।
নতুন branch বানালে কী হয়
git branch feature-x
Git শুধু .git/refs/heads/feature-x নামে একটা নতুন ফাইল বানায়, আর তাতে বর্তমান commit-এর hash লিখে দেয়। কোনো ফাইল কপি হয় না, কোনো ডিরেক্টরি duplicate হয় না। এজন্যই Git-এ branch বানানো instant — SVN-এর মতো পুরোনো সিস্টেমে যেখানে branch মানে ছিল পুরো codebase কপি করা।
HEAD-এর ভূমিকা
তাহলে Git কীভাবে জানে আপনি এখন কোন branch-এ আছেন? সেটার জন্য আছে HEAD:
cat .git/HEAD
# আউটপুট: ref: refs/heads/main
HEAD হলো pointer-এর pointer — এটা branch-কে point করে, আর branch commit-কে point করে। git checkout feature-x করলে Git শুধু HEAD ফাইলটা আপডেট করে আর working directory-র ফাইলগুলো ওই commit-এর snapshot অনুযায়ী সাজিয়ে দেয়।
Commit করলে কী হয়
আপনি যখন কোনো branch-এ থেকে commit করেন:
- Git নতুন commit object বানায় (যার parent হলো আগের commit)
- বর্তমান branch-এর pointer-টা নতুন commit-এ এগিয়ে নেয়
অর্থাৎ branch "grow" করে না — pointer-টা শুধু সামনে সরে যায়। অন্য branch-গুলো যেখানে ছিল সেখানেই থাকে। দুটো branch আলাদা দিকে এগোলেই graph-এ divergence তৈরি হয়, আর তখনই merge বা rebase-এর প্রশ্ন আসে।
একটা মজার প্রমাণ
Branch যে শুধু pointer, তার প্রমাণ হলো "detached HEAD" state। আপনি সরাসরি কোনো commit hash-এ checkout করলে HEAD আর কোনো branch-কে point করে না, সরাসরি commit-কে করে। তখনো Git পুরোপুরি কাজ করে — কারণ আসল ডেটা তো commit graph-এ, branch শুধু সুবিধার জন্য দেওয়া নাম।
সংক্ষেপে: commit-রাই আসল জিনিস, branch হলো সেগুলোর গায়ে লাগানো স্টিকি নোট। এই মানসিক মডেলটা মাথায় থাকলে merge, rebase, cherry-pick, reset — সবকিছু হঠাৎ অনেক সহজ মনে হবে, কারণ এগুলো সবই আসলে হয় নতুন commit বানানো, নয়তো pointer এদিক-ওদিক সরানো।