ব্লগে ফিরুন

Git Revert vs Reset: কোনটি আপনার history বাঁচায়?

১৫ সেপ্টেম্বর, ২০২৬

TL;DR: git revert পুরনো একটি commit বাতিল করতে নতুন একটি commit যোগ করে — history অটুট থাকে, অন্যরা pull করা branch-এও নিরাপদ। git reset branch pointer পেছনে সরায় — history পুনর্লিখিত হয়, শুধু এমন commit-এ নিরাপদ যা আপনি এখনো push করেননি। shared branch-এ revert, স্থানীয় পরিষ্কার-পুটে reset। reset --hard আনকমিটেড working-tree পরিবর্তনও মুছে দেয়; আসল কাজ খেয়ে ফেলে এটাই।

git revert আর git reset-এর পার্থক্য কী?

দুটোই আপনার প্রজেক্টকে এমন দেখায় যেন পুরনো একটি commit কখনোই ঘটেনি। অসম্মতি শুধু কীভাবে তা হয় সেখানে:

  • git revert <sha> একটি commit-এর বিপরীত patch হিসেব করে সেটাকে commit করে। আপনার history একটি commit বেড়ে যায়, যেটা বলে “ওইটা বাতিল”। খারাপ commit লগেই থাকে, পেছনে তার বাতিল। বাকি সবকিছুর SHA অবিকৃত থাকে।
  • git reset <sha> বর্তমান branch-এর pointer-কে <sha>-তে সরায়। এর পরের commit-গুলো বিচ্ছিন্ন হয়ে যায় — garbage collection পর্যন্ত object database-এ থাকে, কিন্তু কোনো branch বা git log থেকে আর পৌঁছানো যায় না।

একটি কিছুই পুনর্লিখন করে না, অন্যটি নাটক করে কিছুই ঘটেনি। এই একটি বৈশিষ্ট্যই ঠিক করে দেয় কোন পরিস্থিতিতে কোনটি লাগবে:

# ডেমো: চালানো যায় এমন একটা ফেলে দেওয়ার repo
git init /tmp/revert-vs-reset && cd /tmp/revert-vs-reset
echo one > file.txt && git add . && git commit -m "one"
echo two > file.txt && git add . && git commit -m "two"

# Revert: history-তে দুটো commit-ই থাকে, সঙ্গে তৃতীয়টি যেটা "two" বাতিল করে
git revert --no-edit HEAD
git log --oneline        # 3টি commit: revert, two, one

# Reset: branch pointer পেছনে যায়, লগ থেকে "two" মিলিয়ে যায়
git reset --hard HEAD~1
git log --oneline        # 1টি commit: one

দুটোই চালিয়ে git log দেখুন — অসমতাটাই পুরো উত্তর।

git reset —soft, —mixed, —hard আসলে কী করে?

তিনটি মোড নিয়ন্ত্রণ করে pointer সরার পরে আপনার পরিবর্তনগুলো কোথায় বেঁচে থাকবে:

মোডBranch pointerStaging areaWorking treeআপনার সম্পাদনা
--softপেছনে যায়staged থাকেঅস্পৃষ্টপুরোপুরি অটুট
--mixed (ডিফল্ট)পেছনে যায়unstagedঅস্পৃষ্টঅটুট, unstaged
--hardপেছনে যায়resetresetমুছে যায়

টেবিলটার বাস্তব পাঠ:

  • git reset --soft HEAD~1 — “খুব তাড়াতাড়ি commit করে ফেলেছি।” সবকিছু staged-এ ফিরে যায়, recommit-এর জন্য তৈরি — হয়তো নতুন কাজসহ।
  • git reset HEAD~1 (mixed) — “ভুল ফাইল stage করেছি।” সম্পাদনাগুলো working tree-তে বেঁচে থাকে, কিছুই staged থাকে না। এলোমেলো ফাইলও সরাতে চাইলে জুড়ে নিন git remove untracked files
  • git reset --hard HEAD~1 — “এই commit আর আমার আনকমিটেড সম্পাদনা সব আবর্জনা।” Git দ্বিতীয়বার জিজ্ঞেস করবে না; working-tree অংশের কোনো undo নেই — আগে stash বা commit না করে থাকলে।

revert-এর কোনো মোড নেই, কারণ সে কিছুই ধ্বংস করে না — শুধু ক্ষতিপূরক একটি commit যোগ করে।

git reset-এর বদলে git revert কখন ব্যবহার করবেন?

একটাই প্রশ্ন করুন: এই commit অন্য কেউ কি pull করেছে? হ্যাঁ হলে reset বাদ।

অন্যরা যার ওপর কাজ ভিত্তি করেছে এমন branch reset করা shared history পুনর্লিখন করে। তাদের পরের pull বিভক্ত branch-এর মুখোমুখি হয়, আর সেই “সমাধান” সাধারণত একটা force-push — আপনার ভুল সবার সমস্যা হয়ে যায়। revert একটা সাধারণ commit জোড়া লাগায়, তাই সাদামাটা git pull সবার জন্য পরিষ্কারভাবে merge হয় — এ কারণেই main আর GitHub pull request-এ revert-ই ডিফল্ট উত্তর; সেখানে “Revert” বোতামটা ঠিক এই জন্যই আছে যে merged PR-এর history পুনর্লিখন কোনো অপশন নয়।

reset হলো শেয়ারের আগের সময়টার জন্য: ত্রিশ সেকেন্ড আগে করা commit, stage করার ভুল, স্থানীয় পরীক্ষার branch। কাজের একমাত্র কপি যদি আপনার মেশিনেই থাকে, history এলোমেলো করার স্বাধীনতা আপনার — pre-push সময়টার পুরো মর্ম এটাই।

একটা মাঝামাঝি কেস আছে: নিজের feature branch-এ push করেছেন আর তার ওপর অন্য কেউ বাঁধে না। সেখানে reset-এর পরে force-push সামাজিকভাবে গ্রহণযোগ্য, তবু revert-ই কম coordination খায়। force-push রাখুন শুধু একা-মালিকানার branch-এর জন্য।

shared branch-এ git revert কি git reset-এর চেয়ে নিরাপদ?

হ্যাঁ, কাঠামোগতভাবে — শুধু রেওয়াজে নয়:

  • revert একটা সাধারণ commit তৈরি করে; তার ওপর CI চলে, diff রিভিউযোগ্য, আর git log ভবিষ্যত-আপনাকে বোঝায় পরিবর্তনটা কেন অদৃশ্য হলো।
  • reset মাঝের অবস্থাটা নিঃশব্দে ফেলে দেয়। পরে রিভিউ করতে এসে কেউ দেখবে না কী বাতিল হলো, কখন হলো — লগ একটা সরলরেখা দেখায় যেখানে সেটা কখনোই ছিলই না।

দুটো বাস্তব ঝুঁকির জায়গা:

  • merge commit revert করতে লাগে git revert -m 1 <sha> (প্রথম parent-এর ধারা ধরে রাখুন)। -m ছাড়া git অস্বীকার করবে, আর ভুলটা পড়ে বোঝার ভার আপনার।
  • revert টাইম মেশিন নয়: সে বাতিল করে একটি commit-এর diff। পরের commit-গুলো একই লাইন ছুঁয়ে থাকলে conflict মেটাতে হতে পারে — git তখন জানাচ্ছে undo-টা জটপাকানো, যা দরকারি তথ্য, কোনো ত্রুটি নয়।

শুধু একেবারে শেষ commit বাতিল করা — পরিবর্তন রেখে বা ফেলে দিয়ে — সেই অপশনগুলো গুছিয়ে আছে git undo last commit: keep the changes-এ।

git restore-এর ভূমিকা কী — এটা কোথায় বসে?

git restore (আর তার জুটি git switch) এসেছে git 2.23-এ, reset-এর নামের ওভারলোডে খারাপভাবে চালানো কাজগুলো নিতে:

কাজপুরনো পথপরিষ্কার পথ
একটি ফাইলের working-tree সম্পাদনা ফেলে দেওয়াgit checkout -- file / git reset --hardgit restore file
একটি ফাইল unstage করাgit reset HEAD filegit restore --staged file
branch-কে অন্য commit-এ নেওয়াgit reset <sha>git reset <sha> (বিকল্প নেই — এটা থেকেই যায়)

তাহলে আধুনিক ভাগ: restore ফাইল ঠিক করে, reset branch সরায়, revert প্রকাশিত commit বাতিল করে। autocomplete বলছে মানুষ “git revert vs reset vs restore” একসঙ্গেই খোঁজে, যৌক্তিক কারণেই — তিনটি কমান্ডে ভাগ করা একটাই মানসিক মডেল ওরা। পুরনো git checkout রূপগুলো সব জায়গায় এখনো চলে; নতুন রূপগুলো শুধু আটকায় — একটা ফাইল unstage করতে এসে আপনি গোটা branch-টা কাগুজে কাটায় ফেলতে পারেন না।

খারাপ একটা মুছে ফেলার বদলে ভালো একটা commit সামনে এঁকে আনাই উদ্দেশ্য হলে, সেটা cherry-pick-এর কাজ — দেখুন git cherry-pick: multiple commits, branches, conflicts

দ্রুত সিদ্ধান্তের সারসংক্ষেপ

  1. commit প্রকাশিত (push করা, অন্যরা pull করেছে) → git revert <sha>
  2. commit শুধু স্থানীয়, আবার করতে চান → git reset --soft বা --mixed, তারপর recommit।
  3. শুধু স্থানীয়, আনকমিটেড এলোমেলোসহ সব চলে যাক → git reset --hard, working tree-তে আর কী আছে একবার সৎ দৃষ্টিতে দেখার পরে।
  4. একটা ফাইল নষ্ট হয়েছে → git restore <file>, branch নিয়ে মাথা না ঘামান।

ওই তালিকার একমাত্র সত্যিকারের বিপজ্জনক সদস্য --hard — বাকি সব git reflog দিয়ে ফিরিয়ে আনা যায়। git-এ স্থায়ী ক্ষতির পরিসর সরু, আর বেশিরভাগ ক্ষেত্রেই সেটা টাইপ করে স্পষ্টভাবে চেয়ে নিতে হয়; গড়ে তোলার মতো অভ্যাস একটাই — --hard-এর আগে আধো সেকেন্ড থামা, git-এর ধারালো টুল এড়িয়ে চলা নয়।

— mrsaynothing

— mrsaynothing

AI, Linux ও self-hosting নিয়ে ফিল্ড নোটস।

পোস্টটি নিয়ে dev.to-তে আলোচনা করুন dev.to ↗

পরের হাউ-টু ইমেইলে পান

প্রতি পোস্টে একটি ইমেইল। সমাধান করুন, এগিয়ে যান।

self-hosted · কোনো তৃতীয় পক্ষ নেই · এক ক্লিকে আনসাবস্ক্রাইব

এটা কী?

Systemd Service চালু হচ্ছে না? ঠিক করার উপায়

লেখাগুলো ভালো লাগছে? এমন জিনিস বানানোই আমার পেশা। আমাকে নিন