सामान्य तौर पर, git reset
फ़ंक्शन को वर्तमान शाखा को लेना है और इसे कहीं और इंगित करने के लिए रीसेट करना है, और संभवतः सूचकांक और काम के पेड़ को साथ लाना है। अधिक संक्षिप्त रूप से, यदि आपकी मास्टर शाखा (वर्तमान में जाँच की जा चुकी है) इस प्रकार है:
- A - B - C (HEAD, master)
और आपको पता चलता है कि आप मास्टर को B को इंगित करना चाहते हैं, C को नहीं, आप git reset B
इसे वहां स्थानांतरित करने के लिए उपयोग करेंगे :
- A - B (HEAD, master) # - C is still here, but there's no branch pointing to it anymore
पाचन: यह एक चेकआउट से अलग है। यदि आप दौड़ेंगे git checkout B
, तो आपको यह मिलेगा:
- A - B (HEAD) - C (master)
आप एक अलग राज्य में समाप्त हो गए हैं। HEAD
, काम के पेड़, सूचकांक सभी मैच B
, लेकिन मास्टर शाखा को पीछे छोड़ दिया गया था C
। यदि आप D
इस बिंदु पर एक नई प्रतिबद्धता बनाते हैं , तो आपको यह मिल जाएगा, जो कि शायद आप नहीं चाहते हैं:
- A - B - C (master)
\
D (HEAD)
याद रखें, रीसेट करना कमिट नहीं करता है, यह सिर्फ एक शाखा (जो एक कमिट के लिए एक पॉइंटर है) को एक अलग कमिट को इंगित करने के लिए अपडेट करता है। बाकी सिर्फ आपके सूचकांक और काम के पेड़ के साथ क्या होता है, इसका विवरण है।
बक्सों का इस्तेमाल करें
मैं git reset
अगले अनुभाग में विभिन्न विकल्पों के अपने विवरण के भीतर मुख्य उपयोग के कई मामलों को कवर करता हूं । यह वास्तव में चीजों की एक विस्तृत विविधता के लिए इस्तेमाल किया जा सकता है; सामान्य धागा यह है कि सभी में किसी दिए गए वचन को इंगित / मिलान करने के लिए शाखा, सूचकांक और / या कार्य ट्री को रीसेट करना शामिल है।
ध्यान रखने योग्य बातें
--hard
आप वास्तव में काम खो सकते हैं। यह आपके काम के पेड़ को संशोधित करता है।
git reset [options] commit
आप के कारण कर सकते हैं (की तरह) कमिट्स खो देते हैं। ऊपर के खिलौने के उदाहरण में, हमने कमिट किया C
। यह अभी भी रेपो में है, और आप इसे देख सकते हैं git reflog show HEAD
या इसे देख सकते हैं git reflog show master
, लेकिन यह वास्तव में किसी भी शाखा से सुलभ नहीं है।
Git 30 दिनों के बाद स्थायी रूप से ऐसे कमिट्स को हटा देता है, लेकिन तब तक आप C को फिर से ( git checkout C; git branch <new branch name>
) पर इंगित करके पुनर्प्राप्त कर सकते हैं ।
तर्क
मैन पेज को पैराफ्रेस करते हुए, सबसे आम उपयोग फॉर्म का है git reset [<commit>] [paths...]
, जो दिए गए कमिट से उनके राज्य के लिए दिए गए रास्तों को रीसेट करेगा। यदि पथ प्रदान नहीं किए गए हैं, तो संपूर्ण पेड़ रीसेट हो जाता है, और यदि वचनबद्धता प्रदान नहीं की जाती है, तो इसे HEAD (वर्तमान प्रतिबद्ध) किया जाता है। यह git कमांड्स में एक सामान्य पैटर्न है (उदाहरण के लिए चेकआउट, अंतर, लॉग, हालांकि सटीक शब्दार्थ भिन्न होता है), इसलिए यह बहुत आश्चर्यजनक नहीं होना चाहिए।
उदाहरण के लिए, git reset other-branch path/to/foo
अन्य राज्य-शाखा में पथ / / से अपने राज्य के लिए सब कुछ रीसेट करता है git reset -- .
, HEAD में अपने राज्य में वर्तमान निर्देशिका को रीसेट करता है, और HEAD में अपने राज्य को git reset
सब कुछ रीसेट करता है।
मुख्य कार्य पेड़ और सूचकांक विकल्प
रीसेट के दौरान आपके काम के पेड़ और सूचकांक के साथ क्या होता है, इसे नियंत्रित करने के लिए चार मुख्य विकल्प हैं।
याद रखें, सूचकांक git का "स्टेजिंग एरिया" है - यह वह जगह है जहां चीजें तब होती हैं जब आप git add
प्रतिबद्ध होने की तैयारी में कहते हैं।
--hard
आपके द्वारा रीसेट किए गए कमिट से सब कुछ मेल खाता है। यह समझना सबसे आसान है, शायद। आपके सभी स्थानीय परिवर्तन स्पष्ट हो जाते हैं। एक प्राथमिक उपयोग आपके काम को दूर कर रहा है, लेकिन स्विच नहीं कर रहा है: git reset --hard
इसका मतलब है git reset --hard HEAD
कि शाखा को न बदलें, लेकिन सभी स्थानीय परिवर्तनों से छुटकारा पाएं। दूसरा बस एक स्थान से दूसरे स्थान पर एक शाखा को स्थानांतरित कर रहा है, और अनुक्रमणिका / कार्य ट्री को सिंक में रख रहा है। यह वह है जो वास्तव में आपको काम खो सकता है, क्योंकि यह आपके काम के पेड़ को संशोधित करता है। बहुत सुनिश्चित करें कि आप किसी भी कार्य को चलाने से पहले स्थानीय काम को दूर फेंकना चाहते हैं reset --hard
।
--mixed
डिफ़ॉल्ट है, git reset
इसका मतलब है git reset --mixed
। यह इंडेक्स को रीसेट करता है, लेकिन काम के पेड़ को नहीं। इसका मतलब है कि आपकी सभी फाइलें बरकरार हैं, लेकिन मूल प्रतिबद्धता और आपके द्वारा रीसेट किए जाने वाले किसी भी अंतर को गिट स्थिति के साथ स्थानीय संशोधनों (या अनट्रैक की गई फ़ाइलों) के रूप में दिखाया जाएगा। इसका उपयोग तब करें जब आपको एहसास हो कि आपने कुछ बुरे काम किए हैं, लेकिन आप अपने द्वारा किए गए सभी कामों को बनाए रखना चाहते हैं ताकि आप इसे ठीक कर सकें और फिर से इकट्ठा कर सकें। प्रतिबद्ध करने के लिए, आपको फ़ाइलों को फिर से सूचकांक में जोड़ना होगा ( git add ...
)।
--soft
अनुक्रमणिका या कार्य ट्री को स्पर्श नहीं करता है । आपकी सभी फाइलें --mixed
उसी तरह बरकरार हैं , लेकिन सभी परिवर्तन changes to be committed
जीआईटी की स्थिति के साथ दिखाई देते हैं (यानी कमिट करने की तैयारी में जाँच की गई)। इसका उपयोग तब करें जब आपको एहसास हो कि आपने कुछ बुरे काम किए हैं, लेकिन काम के सभी अच्छे - आपको बस इतना करना है कि इसे अलग तरीके से फिर से समझें। सूचकांक अछूता है, इसलिए यदि आप चाहते हैं तो आप तुरंत प्रतिबद्ध कर सकते हैं - परिणामी प्रतिबद्ध में वही सब सामग्री होगी जहां आप रीसेट करने से पहले थे।
--merge
हाल ही में जोड़ा गया था, और आपको एक असफल मर्ज को खत्म करने में मदद करने का इरादा है। यह आवश्यक है क्योंकि git merge
वास्तव में आप एक गंदे काम के पेड़ (स्थानीय संशोधनों के साथ एक) के साथ मर्ज करने का प्रयास करेंगे जब तक कि उन मर्ज से अप्रभावित फ़ाइलों में हैं। git reset --merge
सूचकांक को रीसेट करता है (जैसे --mixed
- सभी परिवर्तन स्थानीय संशोधनों के रूप में दिखाई देते हैं), और मर्ज से प्रभावित फ़ाइलों को रीसेट करता है, लेकिन दूसरों को अकेला छोड़ देता है। यह खराब मर्ज से पहले सब कुछ बहाल करने की उम्मीद करेगा। आप इसे आमतौर पर git reset --merge
(अर्थ git reset --merge HEAD
) के रूप में उपयोग करेंगे क्योंकि आप केवल मर्ज को दूर करना चाहते हैं, वास्तव में शाखा को स्थानांतरित नहीं करते हैं। ( HEAD
अभी तक अद्यतन नहीं किया गया है, क्योंकि विलय विफल रहा है)
अधिक ठोस होने के लिए, मान लीजिए कि आपने ए और बी फ़ाइलों को संशोधित किया है, और आप एक शाखा में विलय करने का प्रयास करते हैं, जो सी और डी को संशोधित करती है। मर्ज किसी कारण से विफल हो जाता है, और आप इसे निरस्त करने का निर्णय लेते हैं। आप उपयोग करें git reset --merge
। यह सी और डी को वापस लाता है कि वे कैसे थे HEAD
, लेकिन अपने संशोधनों को ए और बी को अकेले छोड़ देते हैं, क्योंकि वे प्रयास के विलय का हिस्सा नहीं थे।
अधिक जानना चाहते हैं?
मुझे लगता man git reset
है कि यह वास्तव में इसके लिए काफी अच्छा है - शायद आपको उस तरीके की थोड़ी समझ की आवश्यकता है, क्योंकि उनके लिए वास्तव में सिंक करने के लिए गिट काम करता है। विशेष रूप से, यदि आप उन्हें ध्यान से पढ़ने के लिए समय लेते हैं, तो वे सारणियाँ सभी विभिन्न विकल्पों और मामलों के लिए अनुक्रमणिका और कार्य ट्री में फ़ाइलों की स्थिति का विवरण देती हैं। (लेकिन हाँ, वे बहुत घने हैं - वे बहुत ही संक्षिप्त रूप में उपरोक्त जानकारी का एक बहुत कुछ बता रहे हैं।)
अजीब संकेतन
"अजीब संकेतन" ( HEAD^
और HEAD~1
) जो आप उल्लेख करते हैं, वह कमिट निर्दिष्ट करने के लिए एक आशुलिपि है, जैसे हैश नाम का उपयोग किए बिना 3ebe3f6
। यह पूरी तरह से उदाहरण और संबंधित वाक्यविन्यास के साथ git-rev-parse के लिए आदमी पृष्ठ के "निर्दिष्ट संशोधनों" अनुभाग में प्रलेखित है । कैरेट और टिल्ड वास्तव में अलग-अलग चीजों का मतलब है :
HEAD~
के लिए छोटा है HEAD~1
और इसका मतलब है कि पहला माता-पिता। HEAD~2
का मतलब है कमिटमेंट का पहला पैरेंट का पहला पैरेंट। HEAD~n
"हेड से पहले एन कमिट्स" या "हेड की एनटी पीढ़ी पूर्वज" के रूप में सोचें ।
HEAD^
(या HEAD^1
) का अर्थ कमिट का पहला अभिभावक भी है। HEAD^2
का मतलब है कि कमिट का दूसरा माता-पिता। याद रखें, एक सामान्य मर्ज कमिट में दो माता-पिता होते हैं - पहला माता-पिता मर्ज-कमिट होता है, और दूसरा माता-पिता वह मर्ज होता है जो मर्ज किया गया था। सामान्य तौर पर, विलय में वास्तव में कई माता-पिता (ऑक्टोपस विलय) हो सकते हैं।
^
और ~
ऑपरेटरों एक साथ बांधा जा सकता है, के रूप में HEAD~3^2
, की तीसरी पीढ़ी के पूर्वज के दूसरे माता पिता HEAD
, HEAD^^2
के पहले माता-पिता की दूसरी माता पिता HEAD
, या यहाँ तक HEAD^^^
है, जो के बराबर है HEAD~3
।