ভুল Branch-এ Commit: উদ্ধার অভিযান
খুবই সাধারণ দুর্ঘটনা — main-এ আছেন ভুলে গেছেন, কাজ শেষ করে commit-ও দিয়ে ফেলেছেন। সুখবর: আগের আলোচনাগুলোর অস্ত্রগুলো দিয়েই এটা মেটে, আর সমাধানটা নির্ভর করে তিনটা প্রশ্নের উত্তরে:
- Push হয়ে গেছে কি?
- যে branch-এ যাওয়ার কথা ছিল সেটা আছে, নাকি বানাতে হবে?
- কয়টা commit?
দৃশ্য ১: Push হয়নি, সঠিক branch এখনো নেই (সবচেয়ে সহজ)
আপনি main-এ commit করেছেন, আসলে চেয়েছিলেন নতুন feature branch। মজার ব্যাপার — কাজ ইতিমধ্যেই সঠিক জায়গায় আছে, শুধু ভুল লেবেল লাগানো। প্রথম আলোচনা মনে করুন: branch তো স্রেফ pointer।
git branch feature-x # এখানেই নতুন pointer — commit-টা এখন দুই নামে
git reset --hard HEAD~1 # main-কে এক ধাপ পেছনে টানুন
git checkout feature-x # কাজ চালিয়ে যান
ছবিতে:
আগে: A---B---C main (C ভুল জায়গায়)
পরে: A---B main
\
C feature-x (C এখন সঠিক ঘরে)
--hard এখানে নিরাপদ কারণ C-এর দিকে feature-x pointer তাক করা আছে — commit পরিত্যক্ত হচ্ছে না। তবে reset-আলোচনার সতর্কতা মনে রাখুন: working directory-তে uncommitted কাজ থাকলে আগে git stash, নয়তো সেটা হারাবে।
আরো ছোট সংস্করণ (নতুন Git-এ):
git switch -c feature-x # commit সহই নতুন branch-এ চলে গেলেন
git branch -f main HEAD~1 # main-কে পেছনে বসিয়ে দিন
দৃশ্য ২: Push হয়নি, সঠিক branch আগে থেকেই আছে
এবার শুধু pointer সরালে হবে না — commit-টাকে অন্য branch-এর মাথায় replay করতে হবে। চেনা লাগছে? এটাই cherry-pick-এর আরেকটা ক্লাসিক ব্যবহার (সেই আলোচনায় এক লাইনে বলেছিলাম):
git log -1 # ভুল commit-এর hash টুকে নিন (ধরুন c3d4e5f)
git checkout feature-x
git cherry-pick c3d4e5f # সঠিক branch-এ কপি (নতুন hash-এ)
git checkout main
git reset --hard HEAD~1 # ভুল জায়গা থেকে সরান
আগে: A---B---C main D---E feature-x
পরে: A---B main D---E---C' feature-x
খেয়াল করুন C আর C′ — cherry-pick-আলোচনার সেই সত্য: এটা কপি নয়, নতুন commit, কারণ parent বদলেছে।
একাধিক commit হলে:
git cherry-pick <প্রথম-hash>^..<শেষ-hash> # range
git checkout main
git reset --hard HEAD~3 # তিনটা হলে তিন ধাপ
ক্রম গুরুত্বপূর্ণ: আগে cherry-pick, পরে reset। উল্টো করলে সাময়িকভাবে commit-গুলো pointer-হীন হয়ে যায় — reflog থেকে উদ্ধারযোগ্য ঠিকই, কিন্তু অকারণ ঝুঁকি কেন নেবেন।
দৃশ্য ৩: Push হয়ে গেছে ⚠️
এখানেই আগের দুই আলোচনার সেই সোনালি নিয়ম সিদ্ধান্ত নিয়ে নেয়। প্রশ্ন করুন: branch-টা কি shared/protected?
ক) Shared branch (যেমন main) — revert-এর রাস্তা:
# ১. কাজটা সঠিক branch-এ নিন
git checkout feature-x
git cherry-pick c3d4e5f
# ২. ভুল branch-এ reset নয় — revert
git checkout main
git revert c3d4e5f
git push
main-এর history-তে থাকবে: ভুল commit + তার revert — দেখতে একটু অগোছালো, কিন্তু কারো লোকাল ভাঙে না, force-push নেই, CI/PR flow অক্ষত। Reset + force-push করলে রাফি-দুর্ঘটনার পুরো চিত্রনাট্য আবার — আর protected branch হলে সে দরজা এমনিতেই বন্ধ।
খ) নিজের প্রাইভেট branch-এ push করেছেন (যেমন নিজের PR branch, কেউ ছোঁয়নি): দৃশ্য ১/২-এর মতোই reset করে
git push --force-with-lease
— rebase-আলোচনার সেই সিটবেল্ট সহ।
বোনাস: commit-ই করেননি, শুধু ভুল branch-এ এডিট করছেন
সবচেয়ে মধুর সংস্করণ — কিছুই করতে হয় না প্রায়:
git switch -c feature-x # অথবা বিদ্যমান branch হলে: git switch feature-x
Uncommitted পরিবর্তন সাধারণত switch-এর সাথেই যায়। Git বাধা দিলে (conflict-এর সম্ভাবনায়):
git stash
git switch feature-x
git stash pop
ভবিষ্যতে যেন না হয়
সিনিয়র উত্তরের শেষাংশ — প্রতিরোধ:
- Shell prompt-এ branch-এর নাম (Starship, oh-my-zsh, বা IntelliJ-র status bar) — অর্ধেক দুর্ঘটনা এখানেই শেষ
- Branch protection:
main-এ সরাসরি push নিষিদ্ধ করলে ভুল commit push-ই হতে পারবে না — CI-ও ধরবে - অভ্যাস: কাজ শুরুর আগে
git status-এ এক পলক — কোথায় আছি?
এক লাইনে (interview-সংস্করণ)
"মূলনীতি: commit তো graph-এ ঠিকই আছে, শুধু pointer-গুলো ঠিক করতে হবে — branch না থাকলে ওখানেই git branch বানিয়ে ভুল branch-কে reset; branch থাকলে সঠিকটায় cherry-pick করে ভুলটায় reset; আর push হয়ে গেলে সোনালি নিয়ম — নিজের branch হলে reset + --force-with-lease, shared branch হলে reset ছুঁয়েও দেখা নয়, revert।"