ब्लॉग पर वापस

Git Revert vs Reset: आपका history कौन बचाता है?

15 सितंबर 2026

TL;DR: git revert एक नया commit जोड़ता है जो पुराने को उलट देता है — history सुरक्षित रहती है, उन branches पर सुरक्षित जिन्हें दूसरे लोग pull कर चुके हैं। git reset branch pointer को पीछे खिसका देता है — history फिर लिख दी जाती है, सिर्फ़ उन commits पर सुरक्षित जिन्हें आपने push नहीं किया। Shared branches पर revert, लोकल सफ़ाई के लिए reset। reset --hard बिना commit किए रखे working-tree बदलाव भी मिटा देता है; असली काम वही निगल जाता है।

git revert और git reset में फ़र्क़ क्या है?

दोनों आपके project को वैसा दिखाते हैं मानो कोई पुराना commit कभी हुआ ही नहीं। बहस सिर्फ़ तरीक़े पर है:

  • git revert <sha> किसी commit का उलटा patch निकालकर उसे commit कर देता है। आपकी history में एक commit जुड़ता है जो कहता है “उस एक को उलट दो”। ग़लत commit log में अपनी जगह रहता है, उसके बाद उसका खंडन। बाक़ी सबके SHAs अछूते रहते हैं।
  • git reset <sha> मौजूदा branch का pointer <sha> पर खिसका देता है। उसके बाद के commits कट जाते हैं — 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 में दोनों commits रहते हैं, साथ में तीसरा जो "two" उलट देता है
git revert --no-edit HEAD
git log --oneline        # 3 commits: revert, two, one

# Reset: branch pointer पीछे खिसकता है, "two" log से ग़ायब
git reset --hard HEAD~1
git log --oneline        # 1 commit: one

दोनों चलाएँ और git log देखें — पूरा जवाब इसी असमानता में है।

git reset —soft, —mixed और —hard असल में क्या करते हैं?

तीनों modes तय करते हैं कि pointer खिसकने के बाद आपके बदलाव कहाँ बचे रहेंगे:

ModeBranch pointerStaging areaWorking treeआपके edits
--softपीछे खिसकता हैstaged रहते हैंअछूतेपूरी तरह बचे
--mixed (डिफ़ॉल्ट)पीछे खिसकता हैunstagedअछूतेबचे, unstaged
--hardपीछे खिसकता हैresetresetमिट जाते हैं

इस तालिका के सटीक मतलब:

  • git reset --soft HEAD~1 — “मैंने बहुत जल्दी commit कर दिया।” सब कुछ staged अवस्था में लौट जाता है, फिर से commit करने को तैयार — शायद कुछ और काम जोड़कर।
  • git reset HEAD~1 (mixed) — “ग़लत फ़ाइलें stage कर लीं।” Edits working tree में बचे रहते हैं, कुछ भी staged नहीं। अगर बिखरी फ़ाइलें भी हटानी हों तो इसे git remove untracked files के साथ जोड़ें।
  • git reset --hard HEAD~1 — “यह commit और मेरे बिना commit वाले edits दोनों कचरा हैं।” Git दो बार नहीं पूछता; working-tree वाले हिस्से का कोई undo नहीं — जब तक आपने पहले stash या commit न किया हो।

revert के कोई modes नहीं, क्योंकि वह कभी कुछ मिटाता नहीं — बस एक प्रतिकूल commit जोड़ता रहता है।

git reset की जगह git revert कब इस्तेमाल करें?

एक सवाल पूछें: क्या इस commit को किसी और ने pull किया है? अगर हाँ, तो reset बात ही नहीं बनती।

जिस branch पर दूसरों ने काम बनाया है उसे reset करना shared history को फिर लिखना है। उनका अगला pull divergent branches से टकराएगा, और उस “इलाज” के लिए आमतौर पर force-push करना पड़ता है — आपकी चूक सबकी समस्या बन जाती है। Revert एक साधारण commit जोड़ देता है, इसलिए सादा git pull सबके लिए साफ़ merge हो जाता है — इसीलिए main पर और GitHub pull requests पर जवाब revert ही है; “Revert” बटन तबही मौजूद है क्योंकि merge हुए PR की history फिर लिखना कोई विकल्प नहीं है।

Reset शेयर होने से पहले की खिड़की के लिए है: तीस सेकंड पहले किया गया commit, staging की चूक, लोकल प्रयोग वाली branch। अगर काम की इकलौती copy आपकी machine पर है, तो history फिर से सजाने में आप आज़ाद हैं — pre-push खिड़की का पूरा मतलब यही है।

एक बीच का मामला भी है: आपने अपनी feature branch पर push किया है और उस पर कोई और नहीं बन रहा। वहाँ reset के बाद force-push सामाजिक रूप से चल जाता है, पर फिर भी revert समन्वय का कम ख़र्च करता है। Force-push उन्हीं branches के लिए बचाकर रखें जो अकेले आपकी हैं।

क्या shared branches के लिए git revert, git reset से सुरक्षित है?

हाँ, ढाँचे की दृष्टि से — सिर्फ़ रिवायत की बात नहीं:

  • Revert एक मामूली commit बनाता है; उस पर CI चलता है, diff review हो सकता है, और git log भविष्य के आपको समझा देता है कि वह बदलाव ग़ायब क्यों हुआ।
  • Reset बीच की अवस्था चुपचाप फेंक देता है। बाद में review करने वाला नहीं देख सकता कि क्या उलटा गया और कब, क्योंकि log एक सीधी रेखा दिखाती है जिसमें वह कभी था ही नहीं।

दो व्यावहारिक धारदार किनारे:

  • Merge commit को revert करने के लिए git revert -m 1 <sha> चाहिए (पहले parent की रेखा रखें)। -m के बिना git मना कर देता है और error पढ़ने का काम आप पर छोड़ देता है।
  • Revert कोई time machine नहीं: वह एक commit का diff उलटता है। अगर बाद के commits ने वही लाइनें छेड़ी हैं, तो conflicts सुलझाने पड़ सकते हैं — git यही कह रहा होता है कि undo उलझा हुआ है; यह उपयोगी जानकारी है, कोई ख़राबी नहीं।

सिर्फ़ आख़िरी commit उलटने के लिए — उसके बदलाव रखने हों या फेंकने — पूरे विकल्प git undo last commit: keep the changes में गिने गए हैं।

git restore का क्या — वह कहाँ फ़िट होता है?

git restore (और उसकी जोड़ी git switch) git 2.23 में आए, उन कामों को लेने जो reset नामों के बोझ तले बुरी तरह कर रहा था:

कामपुराना तरीक़ासाफ़ तरीक़ा
फ़ाइल के working-tree edits रद्द करना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 branches खिसकाता है, revert publish हुए commits उलटता है। Autocomplete बताता है कि लोग “git revert vs reset vs restore” साथ खोजते हैं — और ठीक ही करते हैं, क्योंकि यह एक ही सोच है जो तीन कमांडों में बँटी है। पुराने git checkout रूप हर जगह अब भी चलते हैं; नए रूप बस यह रोकते हैं कि एक फ़ाइल unstage करने के चक्कर में आप पूरी branch कुटलते न निकल जाएँ।

अगर मक़सद किसी अच्छे commit को आगे ले जाना है, न कि बुरे को मिटाना, तो वह cherry-pick का काम है — देखें git cherry-pick: multiple commits, branches, conflicts

फ़ौरन फ़ैसला: एक नज़र में

  1. Commit public है (pushed, दूसरों ने pull किया) → git revert <sha>
  2. Commit सिर्फ़ लोकल है, दोबारा बनाना है → git reset --soft या --mixed, फिर recommit।
  3. सिर्फ़ लोकल है, बिना commit वाले बिखरे हालात समेत विदा करना है → git reset --hard, पहले ईमानदारी से देख लें कि working tree में और क्या पड़ा है।
  4. एक फ़ाइल बिगड़ गई → git restore <file> करें और branch से हाथ रखें।

इस सूची में असल में ख़तरनाक एक ही एंट्री है — --hard; बाक़ी सब git reflog से वापस बुलाए जा सकते हैं। Git में स्थायी नुक़सान का दायरा सँकरा है और ज़्यादातर हालातों में आपको उसे साफ़ शब्दों में टाइप करना पड़ता है; बनाने लायक़ आदत यह है कि --hard से आधा सेकंड पहले रुक जाएँ — git के नुकीले औज़ारों से परहेज़ करना नहीं।

— mrsaynothing

Get the next one by email

One email per post. No spam, no algorithms.

self-hosted · no third parties · one-click unsubscribe

what is this?

Systemd service start नहीं हो रही? इसे ठीक कैसे करें

लेख पसंद आए? मैं पेशेवर रूप से ऐसे ही काम करता हूँ। मुझे हायर करें