यदि किसी पुराने कमिट में किसी एक फ़ाइल में कोई अवांछित बदलाव शामिल है, तो आप अपनी वर्तमान ब्रांच के विरुद्ध उस फ़ाइल के बदलाव को उलट (reverse) सकते हैं और परिणाम को एक नए कमिट में सहेज सकते हैं। यह बाद के कमिट को बनाए रखता है और जब रिवर्स पैच ठीक से फिट बैठता है तो उनके संपादनों को सुरक्षित रखता है। macOS पर, रिपॉजिटरी से Terminal का उपयोग करें; पैच की पहले समीक्षा करें, विशेष रूप से तब जब बाद के काम ने उन्हीं पंक्तियों को छुआ हो।
सही इतिहास बदलाव चुनें
यह प्रक्रिया एक ऐसा कमिट जोड़ती है जो किसी एक पाथ (path) में लक्षित कमिट के बदलाव को रद्द कर देता है। यह पुराने कमिट से उस फ़ाइल को मिटाता नहीं है, इसलिए पुराना संस्करण इतिहास में बना रहता है। यह तरीका ब्रांच के इतिहास को फिर से लिखने (rewriting) से बचाता है और आमतौर पर तब उपयुक्त होता है जब कमिट पहले ही साझा किया जा चुका हो या बाद के कमिट उस पर निर्भर हों। Git git revert को एक ऐसे नए कमिट को रिकॉर्ड करने के रूप में वर्णित करता है जो किसी पुराने कमिट को उलट देता है, लेकिन यह किसी मौजूदा कमिट से केवल एक पाथ को रिवर्ट करने का कोई इन-बिल्ट विकल्प प्रदान नहीं करता है। इसके बजाय, नीचे दिए गए चरण उस पाथ का पैच उत्पन्न करते हैं और उसे उल्टे क्रम में लागू करते हैं। Git: git-revert Documentation
यदि फ़ाइल के बदलाव को ऐतिहासिक कमिट से ही हटाया जाना अनिवार्य है, तो यह इतिहास को फिर से लिखने (history-rewrite) का कार्य है, जिसे आमतौर पर एक इंटरैक्टिव रीबेस (interactive rebase) के साथ संभाला जाता है। इतिहास को फिर से लिखने से कमिट की पहचान (commit identities) बदल जाती है और यह उन सहयोगियों के काम में बाधा डाल सकता है जिन्होंने पुराने कमिट पर अपना काम आधारित किया है। यह गाइड सुरक्षित, एडिटिव (additive) तरीके को कवर करती है।
किसी एक फ़ाइल में लक्षित कमिट के बदलाव को उलटें
Terminal खोलें, रिपॉजिटरी में जाएं, और कुछ भी बदलने से पहले वर्किंग ट्री की जांच करें। TARGET को कमिट आईडी से और path/to/file को रिपॉजिटरी रूट के सापेक्ष पाथ से बदलें। यह उदाहरण macOS की /tmp डायरेक्टरी में एक अस्थायी पैच फ़ाइल का उपयोग करता है; यदि वह फ़ाइल पहले से मौजूद है तो कोई भिन्न अस्थायी नाम चुनें।
git status --short
git show --stat --oneline TARGET
git diff TARGET^ TARGET -- "path/to/file" > /tmp/remove-file-change.patch
यह diff लक्षित कमिट की तुलना उसके पहले पैरेंट से करता है और परिणाम को निर्दिष्ट पाथ तक सीमित करता है। एक सामान्य, गैर-मर्ज कमिट के लिए, यह फ़ाइल में उस कमिट के बदलाव का प्रतिनिधित्व करता है। पुष्टि करें कि सारांश इच्छित कमिट की पहचान करता है और पैच खाली नहीं है। आप less /tmp/remove-file-change.patch से इसका निरीक्षण कर सकते हैं; बाहर निकलने के लिए q दबाएं। Git वैकल्पिक पाथ सीमा के साथ कमिट-टू-कमिट diffs का दस्तावेजीकरण करता है। Git: git-diff Documentation
इसे लागू करने से पहले, सुनिश्चित करें कि लक्षित फ़ाइल में कोई भी असंबंधित स्टेज्ड या अनस्टेज्ड संपादन न हो। रिवर्स पैच वर्किंग कॉपी को बदलता है, इसलिए एक स्वच्छ (clean) वर्किंग ट्री सबसे सरल प्रारंभिक बिंदु है। यदि आपके पास उपयोगी स्थानीय काम है, तो पहले उसे कमिट करें या सुरक्षित रूप से अलग रख लें; रिस्टोर कमांड से उस पर ओवरराइट न करें।
जांचें कि क्या रिवर्स पैच ठीक बैठता है, फिर उसे लागू करें:
git apply --reverse --check /tmp/remove-file-change.patch
git apply --reverse /tmp/remove-file-change.patch
--reverse diff को उल्टे क्रम में लागू करता है, जबकि --check यह जांचता है कि क्या यह फ़ाइलों को बदले बिना लागू होता है। डिफ़ॉल्ट रूप से, यदि कुछ हंक्स (hunks) फिट नहीं बैठते हैं, तो केवल फिट होने वाले हिस्सों को लागू करने के बजाय git apply पूरे पैच को विफल कर देता है। यदि चेक विफल हो जाता है, तो रुकें और फ़ाइल तथा पैच का निरीक्षण करें। बाद के संपादन लक्षित बदलाव के साथ ओवरलैप हो सकते हैं, इसलिए Git सुरक्षित रूप से यह निर्धारित नहीं कर सकता कि क्या हटाया जाना चाहिए। इच्छित सामग्री को मैन्युअल रूप से हल करें, या यदि सटीक रूप से संपादित ऐतिहासिक क्रम को संरक्षित करना आवश्यक है तो इतिहास-पुनर्लेखन वर्कफ़्लो का उपयोग करें। लापरवाही से --reject न जोड़ें: यह केवल मेल खाने वाले टुकड़ों को लागू कर सकता है और अस्वीकृत हंक्स को छोड़ सकता है। Git: git-apply Documentation
परिणाम की समीक्षा करें और कमिट करें
स्टेज करने से पहले बिल्कुल वही जांचें जो बदला है। git diff वर्किंग-ट्री के संपादनों को दिखाता है; समीक्षा पर ध्यान केंद्रित करने के लिए फिर से पाथ का उपयोग करें। यदि परिणाम सही है, तो उस फ़ाइल को स्टेज करें और नया कमिट बनाने से पहले स्टेज किए गए diff की जांच करें।
git diff -- "path/to/file"
git add -- "path/to/file"
git diff --cached -- "path/to/file"
git status --short
git commit -m "Remove file change from earlier commit"
उद्धरण चिह्न (quotes) पाथ को शेल इंटरप्रिटेशन से बचाते हैं, और -- विकल्पों के अंत को चिह्नित करता है। वे विशेष रूप से उन नामों के लिए उपयोगी हैं जिनमें स्पेस या शेल मेटाकैरेक्टर शामिल हैं। कमिट स्टेज किए गए इंडेक्स को रिकॉर्ड करता है; git diff --cached की समीक्षा करने से उस सटीक सामग्री की पुष्टि होती है जिसे कमिट किया जाने वाला है। Git: git-commit Documentation
कमिट करने के बाद, git status --short की जांच करें और git show --stat --oneline HEAD के साथ नए कमिट का निरीक्षण करें। यदि मूल कमिट ने फ़ाइल को जोड़ा था, तो उसके पैच को उलटने से वह हट सकती है—यदि बाद की किसी सामग्री को बनाए रखने की आवश्यकता नहीं है तो यह अपेक्षित है। यदि बाद के कमिटों ने उस फ़ाइल में उपयोगी सामग्री जोड़ी है, तो रिवर्स पैच के सुचारू रूप से लागू होने पर वे जोड़ बने रहने चाहिए; पुष्टि करने के लिए अंतिम फ़ाइल और diff की समीक्षा करें।
वे मामले जिनमें अतिरिक्त सावधानी की आवश्यकता होती है
मर्ज कमिट के कई पैरेंट होते हैं, और इसका बदलाव इस बात पर निर्भर करता है कि आप किस पैरेंट से तुलना करते हैं। TARGET^ का अर्थ पहला पैरेंट है; यह उस बदलाव का प्रतिनिधित्व नहीं भी कर सकता है जिसे आप हटाना चाहते थे। सही पैरेंट की पहचान करें और कुछ भी लागू करने से पहले स्पष्ट रूप से इसके विरुद्ध तुलना करें। रीनेम की गई फ़ाइलें, बाइनरी फ़ाइलें, और वे फ़ाइलें जो स्थानांतरित हो चुकी हैं, वे भी पाथ-सीमित पैच को अनुपयुक्त बना सकती हैं; diff की जांच करें और यदि यह इच्छित फ़ाइल बदलाव का वर्णन नहीं करता है तो रुक जाएं। मर्ज-विशिष्ट उत्क्रमण (reversals) के लिए, Git का रिवर्ट दस्तावेज़ मुख्य लाइन (mainline) पैरेंट विकल्प और उसके परिणामों की व्याख्या करता है। Git: git-revert Documentation
विश्वसनीय चेकपॉइंट समीक्षित पैच है: इसे इच्छित पाथ पर केवल लक्षित कमिट के बदलाव को दिखाना चाहिए। यदि यह आज की फ़ाइल पर सुचारू रूप से लागू नहीं हो सकता है, तो इसे जबरन लागू न करें। वांछित वर्तमान फ़ाइल को सावधानीपूर्वक फिर से बनाएं, फिर पूरे परिणाम की समीक्षा करने के बाद ही स्टेज और कमिट करें।