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-এ।"

Share