Interactive Rebase: নিজের History-র সম্পাদক
সাধারণ git rebase main করে branch-এর ভিত সরানো — সেটা আগে দেখেছি। Interactive rebase (git rebase -i) সেই একই replay-যন্ত্র, কিন্তু replay-এর আগে Git আপনাকে একটা স্ক্রিপ্ট ধরিয়ে দেয়: "এই commit-গুলো এই ক্রমে চালাবো — কোনটার সাথে কী করবো, বলুন।"
অর্থাৎ এটা history-র টেক্সট এডিটর: commit মেশানো, ভাঙা, নাম বদলানো, ফেলে দেওয়া, ক্রম পাল্টানো — সব এক জায়গায়।
চালু করা
git rebase -i HEAD~4 # শেষ ৪টা commit সম্পাদনা
git rebase -i main # main-এর পর থেকে আপনার সব commit
এডিটরে খুলবে এমন কিছু (খেয়াল করুন — পুরোনো-থেকে-নতুন, git log-এর উল্টো ক্রম):
pick a1b2c3d Add discount service
pick e4f5g6h WIP
pick i7j8k9l fix typo
pick m0n1o2p Add discount tests
# Rebase instructions...
# p, pick / r, reword / e, edit / s, squash / f, fixup / d, drop ...
প্রতিটা লাইনের প্রথম শব্দটা বদলে দিন, ফাইল সেভ করে বন্ধ করুন — Git উপর থেকে নিচে নির্দেশগুলো execute করবে। লাইনগুলোর জায়গা বদলালে commit reorder হয়, আর কোনো লাইন মুছে দিলে সেই commit বাদ (এজন্যই ভুলে লাইন ডিলিট করা বিপজ্জনক)।
মূল অপারেশনগুলো
pick — যেমন আছে তেমন
ডিফল্ট। Commit-টা অপরিবর্তিত replay হবে।
reword — শুধু message বদলানো
কোড একই থাকবে, replay-এর সময় Git থেমে message এডিট করতে দেবে। "fix bug"-জাতীয় অর্থহীন message-কে PR পাঠানোর আগে "Fix rounding error in discount calculation (JIRA-421)" বানানোর অস্ত্র।
squash — নিচের commit-কে উপরেরটার সাথে মেশানো
Commit-টা তার ঠিক আগের commit-এর সাথে মিশে যাবে; Git থামবে এবং দুটো message-ই এডিটরে দেবে — মিলিয়ে নতুন message লিখবেন।
fixup — squash-এর নীরব ভাই
একই মেশানো, কিন্তু মেশানো commit-এর message ফেলে দেয় — আগের commit-এর message-ই থাকে। "fix typo", "oops", "address review comments" — এসবের জন্য নিখুঁত, কারণ ওই message-গুলোর কোনো ঐতিহাসিক মূল্য নেই।
drop — commit বাদ
Commit-টা replay-ই হবে না — যেন কখনো ছিলই না। ভুলে ঢুকে পড়া debug logging, পরীক্ষামূলক কোড ঝেড়ে ফেলতে।
edit — মাঝপথে থামা (বোনাস, কিন্তু জানা জরুরি)
Replay ওই commit-এ পৌঁছে থেমে যাবে — আপনি কোড বদলাতে, commit-টা --amend করতে, এমনকি git reset HEAD^ দিয়ে একটা বড় commit ভেঙে কয়েকটা ছোট commit বানাতে পারবেন। তারপর git rebase --continue।
উদাহরণ: এলোমেলো branch → পরিপাটি PR
উপরের চারটা commit-কে গুছাই:
pick a1b2c3d Add discount service
fixup e4f5g6h WIP
fixup i7j8k9l fix typo
reword m0n1o2p Add discount tests
ফলাফল: চারটার জায়গায় দুটো পরিষ্কার commit —
x9y8z7w Add discount service (তিনটা মিশে এক, প্রথম message-এ)
q5r4s3t Add tests for discount edge cases (reword করা)
Reviewer এখন দেখবে দুটো অর্থবহ, self-contained commit — আপনার "চিন্তার খসড়া" নয়, "চিন্তার পরিণত রূপ"।
সোনার টিপ: --autosquash
Review-এর ফিডব্যাক ঠিক করার সময় এভাবে commit করুন:
git commit --fixup a1b2c3d # message হবে "fixup! Add discount service"
পরে:
git rebase -i --autosquash main
Git নিজেই fixup commit-গুলোকে সঠিক commit-এর নিচে বসিয়ে fixup mark করে দেবে — আপনার শুধু সেভ করা বাকি। git config rebase.autosquash true করে রাখলে সবসময় চালু। এটা জানা থাকলে সিনিয়র-লেভেল দৈনন্দিন workflow অনেক মসৃণ হয়।
কেন এটা এত মূল্যবান
দর্শনটা হলো: কাজ করার সময় যত খুশি এলোমেলো commit করুন — ঘন ঘন সেভ করা ভালো অভ্যাস — কিন্তু publish করার আগে গল্পটা সম্পাদনা করুন। লেখকের খসড়া আর প্রকাশিত বই যেমন এক জিনিস না।
পরিপাটি history-র সুফল আগের আলোচনাগুলোর সাথেই জোড়ে:
- প্রতিটা commit self-contained ও compile-যোগ্য হলে
git bisectনিখুঁত কাজ করে git revertদিয়ে নির্দিষ্ট logical change আলাদাভাবে ফেরানো যায়- Code review commit-ধরে-commit পড়া যায়
- ছয় মাস পরে
git blame-এ "WIP" নয়, আসল কারণ পাওয়া যায়
সতর্কতা — সেই একই সোনালি নিয়ম
Interactive rebase-ও rebase: প্রতিটা ছোঁয়া commit নতুন hash পায়। তাই আগের আলোচনার পুরো সতর্কবার্তা এখানে অক্ষরে অক্ষরে প্রযোজ্য — শুধু নিজের unpushed/প্রাইভেট branch-এ, push-করা PR branch হলে --force-with-lease, আর shared branch-এ কখনোই না।
আর যদি মাঝপথে জট পাকে: git rebase --abort সব আগের অবস্থায় ফেরায়, আর সত্যিই কিছু "হারালে" git reflog তো আছেই।
এক লাইনে
"Interactive rebase হলো publish-এর আগে নিজের commit history সম্পাদনার টুল — pick/reword/squash/fixup/drop/edit দিয়ে এলোমেলো খসড়া-commit-গুলোকে অর্থবহ, self-contained গল্পে সাজানো; workflow হলো 'কাজের সময় নোংরা commit, PR-এর আগে rebase -i দিয়ে পরিষ্কার' — তবে যেহেতু এটা hash বদলায়, সোনালি নিয়ম এখানেও: শুধু নিজের প্রাইভেট branch-এ।"