Git में परिवर्तन और commits को वापस लाना


कुछ न कुछ हमेशा वापस लाने की जरूरत होती है। आपने एक संपादन किया जो आपको नहीं चाहिए था, एक फिक्स की कोशिश की जिससे चीजें और खराब हुईं, या ऐसा कुछ commit किया जो कोई नहीं देखना चाहेगा। Git आपके प्रोजेक्ट के लगभग हर संस्करण का रिकॉर्ड रखता है जो इसने कभी देखा है, इसलिए अधिकांश गलतियां उस समय की तुलना में अधिक सुधार योग्य होती हैं जब वे लगती हैं। कौन सा उपकरण आपको वापस लाता है यह इस बात पर निर्भर करता है कि गलती कितनी दूर गई है: अभी भी आपके संपादक में बैठी हुई है, पहले से ही staged है, पहले से ही commit है, या पहले से ही कहीं push है जहां एक टीम सदस्य इसे देख सकता है। यह अध्याय उस क्रम में प्रत्येक चरण के माध्यम से चलता है।
push और pull क्या हैं?
Push आपके commits को repository की एक साझा प्रति में भेजता है जहां से टीम के सदस्य भी काम करते हैं, और pull उनके commits को आपके पास नीचे लाता है। Remotes और GitHub दोनों को पूरी तरह से कवर करता है; इस अध्याय के लिए, "pushed" का अर्थ है commit आपकी मशीन छोड़ चुका है।
इसे commit करने से पहले एक परिवर्तन को त्यागना
मान लीजिए कि आप commit loop से weather-app में styles.css को restyling कर रहे हैं, और नया layout एक बुरा विचार साबित होता है। आपने इसे staged नहीं किया है, आपने इसे commit नहीं किया है। आप फाइल को वापस उसी तरह चाहते हैं जैसे यह आखिरी बार लगती थी, कुछ नहीं और। ठीक इसी काम के लिए कमांड git restore है:
$ git status
On branch main
Changes not staged for commit:
modified: styles.css
$ git restore styles.css
$ git status
On branch main
nothing to commit, working tree cleangit restore <file> एक uncommitted संपादन को फेंक देता है और फाइल को इसकी अंतिम सहेजी गई स्थिति में डाल देता है। यदि आपने अपना विचार बदलने से पहले पहले से ही git add के साथ परिवर्तन को staged कर दिया है, तो सादा git restore इसे छूएगा नहीं, क्योंकि फाइल अब staging area में बैठी है केवल आपकी working directory में नहीं। पहले इसे unstage करें, फिर इसे restore करें:
$ git add styles.css
$ git restore --staged styles.css
$ git restore styles.cssदो अलग-अलग क्षेत्रों के लिए दो अलग-अलग कदम: git restore --staged एक फाइल को staging area से वापस बाहर ले जाता है, और अपने आप git restore आपकी working directory में संपादन को त्याग देता है। git restore केवल uncommitted काम तक पहुंचता है, एक बार commit होने के बाद, एक अलग कमांड ले लेता है।
git restore <file> एक edit को फेंक देता है जो आपने commit नहीं किया है और फाइल को वापस उसी तरह डाल देता है जैसे वह आखिरी बार थी। यदि आपने पहले से ही git add के साथ परिवर्तन को staged कर दिया है, तो पहले git restore --staged <file> के साथ इसे unstage करें, फिर फाइल को restore करें यदि आप संपादन को गायब करना चाहते हैं। यह केवल ऐसे परिवर्तनों पर काम करता है जिन्हें आपने अभी तक commit नहीं किया है, इसलिए यह एक गलती को बचा नहीं सकता जो आपने पहले से ही सहेजी है। git stash के साथ काम को एक तरफ रखना
कभी-कभी कोई गलती नहीं होती है fix करने के लिए, केवल बुरा timing होता है। आप styles.css पर mid-edit हैं और एक टीम सदस्य आपको अभी दूसरी branch पर चाहिए, लेकिन आप half-finished styling को commit करने के लिए तैयार नहीं हैं। git stash आपके परिवर्तनों को shelf करता है और आपको एक clean working directory देता है ताकि आप दूर हो सकें और बाद में वापस आ सकें।
$ git status
On branch main
Changes not staged for commit:
modified: styles.css
$ git stash
Saved working directory and index state WIP on main: 8f3c7d1 Cache forecast responses in localStorage
$ git status
On branch main
nothing to commit, working tree cleanstyles.css में संपादन गायब नहीं है, यह parked है। एक बार तैयार होने पर git stash pop के साथ इसे वापस लाएं:
$ git stash pop
On branch main
Changes not staged for commit:
modified: styles.cssgit stash उन परिवर्तनों के लिए है जिन्हें आप अभी तक commit करने के लिए तैयार नहीं हैं, यह कभी भी आपकी branch पर एक commit नहीं बनाता है।
git stash ऐसे परिवर्तनों को shelf करता है जिन्हें आप commit करने के लिए तैयार नहीं हैं, इसलिए आपकी working directory clean हो जाती है, और git stash pop उन्हें बाद में वापस लाता है। कुछ भी commit नहीं होता है और कुछ भी खोता नहीं है, संपादन एक बिट के लिए parked रहता है। मैं लगातार इसे पहुंचता हूं जब भी एक टीम सदस्य मुझे अभी दूसरी branch पर चाहता है। git revert के साथ एक commit को undo करना
मान लीजिए commit 8f3c7d1, "Cache forecast responses in localStorage", गलत साबित होता है, और यह पहले से ही pushed है, इसलिए एक टीम सदस्य ने इसे भी pull किया है। इस commit को अब rewrite करना ऐसा कुछ बदलना है जो किसी और के पास पहले से ही है, और उनकी प्रति और आपकी अगली बार pull करने पर disagree करेगी। git revert यह हल करता है बिना कुछ बदले जो पहले से ही exist करता है: यह एक बिल्कुल नई commit बनाता है जो परिवर्तन के opposite को apply करता है।
$ git revert 8f3c7d1
[main 2b6f0d1] Revert "Cache forecast responses in localStorage"History अभी भी दोनों commits को दिखाता है, original और जो इसे undo करता है, क्रम में। किसी की प्रति को reshape करने की जरूरत नहीं है, एक टीम सदस्य किसी अन्य की तरह new revert commit को pull करता है।
git revert हमेशा एक commit पर safe है जो दूसरों के पास पहले से ही है, क्योंकि यह एक पुरानी को change करने की बजाय एक नई commit जोड़ता है।
git revert <commit> एक commit को undo करता है एक बिल्कुल नई commit जोड़कर जो इसे reverse करती है, original को erase करने की बजाय। यह safe pick है एक बार एक commit पहले से ही किसी और के साथ shared है, क्योंकि कुछ भी पहले से ही saved नहीं change होता है। History mistake और fix दोनों का एक record रखता है, जो मैं Git को जितना अधिक use करता हूं उतना अधिक like करता हूं। git reset के साथ rewind करना: soft, mixed, और hard
एक commit को undo करने का एक तीसरा तरीका है, git reset, और यह revert से अलग काम करता है: एक नई commit जोड़ने की बजाय जो पुरानी को undo करती है, reset आपकी current branch को एक अलग commit की ओर point करने के लिए move करती है। यह uncommitted commits के लिए fast और clean बनाता है जो किसी और ने नहीं देखा है, और commits के लिए risky है जो उन्होंने देखा है।
Reset restore और revert का wider, easier to misuse cousin है। आप इसे अधिकांश day-to-day fixes के लिए reach नहीं करेंगे, restore, revert, और stash "help, undo this" moments का vast majority cover करते हैं। आप इसे दूसरे लोगों के instructions में अभी भी देखेंगे, तो यहाँ headline है: reset आपकी branch को history में backward move करता है, और इसके एक mode, --hard, uncommitted काम को बिना confirmation के throw away करता है। यदि कोई command जो आप कहीं से copy कर रहे हैं में git reset --hard शामिल है, तो इसे run करने से पहले read करें कि यह क्या करता है।
git reset reach नहीं करेंगे, restore, revert, और stash पहले से ही लगभग सब कुछ cover करते हैं। फिर भी, इसकी shape जानें: reset आपकी branch को एक पहले की commit में वापस move करता है, और इसका --hard mode आपकी working directory को match करने के लिए confirmation के बिना wipe करता है। किसी भी command को treat करें जो आप copy करते हैं जिसमें reset --hard शामिल है real caution के साथ। revert या reset को चुनना
rule जो decide करती है कि कौन सा tool reach करना है: क्या किसी और ने पहले से ही यह commit pull किया है? यदि हाँ, तो revert। यदि commit केवल आपकी machine पर exist करता है, एक branch पर जो आपने push नहीं किया, तो reset ठीक है और अक्सर tidier fix होता है। जब आप निश्चित नहीं हैं, revert हमेशा safe choice है, क्योंकि यह दोनों cases में काम करता है।
git reflog के साथ एक commit को recover करना
एक reset --hard, एक messy rebase, या branch को accidentally delete करना एक commit को completely vanished जैसा लग सकता है। यह usually नहीं हुआ है। Git एक local log रखता है कि आपके HEAD और branches कहाँ point किए हैं, जिसे reflog कहा जाता है, और यह log लगभग हमेशा आपका तरीका है एक commit को वापस लाने का जो lost दिखता है।
आप इसकी आमतौर पर जरूरत नहीं करेंगे, लेकिन यहाँ headline है: Git शायद ही कभी कुछ को throw away करता है जैसे ही यह लगता है। यदि आप कभी reset --hard चलाते हैं और बाद में realize करते हैं कि आपको उस commit की जरूरत थी, तो बहुत संभावना है कि इसे वापस पाने का एक तरीका है, जो यहाँ cover किया गया है जब भी आप गहराई में जाने के लिए तैयार हों।
reset --hard चलाते हैं और बाद में realize करते हैं कि आपको वह commit की जरूरत थी, तो यह संभवतः अभी भी recoverable है। Git एक local record रखता है जिसे reflog कहा जाता है जहाँ आपका काम point किया गया है, और यह usually एक commit को वापस लाने के लिए काफी है जो gone दिखता है। यह deep-dive territory है, लेकिन यह reassuring है जानना कि यह there है। 
