जीआईटी स्टैश पॉप क्यों कहता है कि यह स्टाॅक एंट्री से अनटैक्ड फाइल्स को रिस्टोर नहीं कर सकता है?


103

मेरे पास मंचन और अस्थिर परिवर्तनों का एक गुच्छा था और मैं जल्दी से दूसरी शाखा में जाना चाहता था और फिर वापस स्विच करना चाहता था।

इसलिए मैंने अपने बदलावों का उपयोग किया:

$ git stash push -a

(मेरे विचार से शायद मैं इसके --include-untrackedबजाय इसका इस्तेमाल कर सकता था --all)

तब जब मैं स्टश को पॉप करने के लिए गया, मुझे इसकी तर्ज पर बहुत सारी त्रुटियां मिलीं:

$ git stash pop
foo.txt already exists, no checkout
bar.txt already exists, no checkout
...
Could not restore untracked files from stash entry

ऐसा लगता नहीं है कि किसी भी परिवर्तन को स्टेश से बहाल किया गया है।

मैंने भी कोशिश की $ git stash branch tempलेकिन वही गलतियाँ दिखाता है।

मैंने इसके चारों ओर एक तरीका निकाला जिसका उपयोग करना था:

$ git stash show -p | git apply

अभी के लिए आपदा टल गई लेकिन इससे कुछ सवाल उठ रहे हैं।

पहली बार में यह त्रुटि क्यों हुई और मैं अगली बार इससे कैसे बचूं?


31
मुझे उपयोग करना था:git stash show -p | git apply --3
xmedeko

2
मेरे लिए एक ही चीज़ काम है ABOVE COMMENT !!
मेहराज मलिक

4
धन्यवाद @xmedeko, क्या कोई git stash show -p के बीच अंतर बता सकता है git apply और git stash show -p | git लागू - ३?
दीपक मोहनदास

5
यदि आप घबराते हैं, तो बस git stash showएक के बाद एक बचाव फाइलों के साथ और साथ में अपनी अटकी हुई फाइलों को सूचीबद्ध करें $ git show stash@{0}:your/stashed/file.txt > your_rescued_file.txt:। यह स्टैश से फाइल प्राप्त करेगा और इसे एक अलग नाम के तहत बचाएगा। अब आप उचित बचाव विधियों के साथ प्रयोग करने के लिए सुरक्षित हैं (नीचे उत्तर देखें)। यदि चीजें भटक जाती हैं, तो आपके पास हमेशा एक अंतिम संसाधन के रूप में आपकी सहेजी गई फाइलें होती हैं।
डेनियल

वाह, धन्यवाद @xmedeko! एक बार फिर आपकी टिप्पणी ही एकमात्र ऐसी चीज थी जो काम करती थी, और यह इतनी सरल थी। +1!
पीसीदेव

जवाबों:


104

अतिरिक्त विवरण के एक बिट के रूप में, ध्यान दें कि git stashया तो दो कमिट करता है, या तीन कमिट करता है। डिफ़ॉल्ट दो है; आप तीन मिलता है अगर आप --allया --include-untrackedविकल्पों में से किसी भी वर्तनी का उपयोग करते हैं।

ये दो या तीन, कमिट एक महत्वपूर्ण तरीके से विशेष हैं: वे बिना किसी शाखा पर हैं। Git उन्हें विशेष नाम से रेखांकित करता है stash1 , सबसे महत्वपूर्ण बात, हालांकि, यही वह चीज है जो आपको देती है- और आपको बनाती है - इन दो या तीन कमिट के साथ। इसे समझने के लिए हमें उन कमिट्स में क्या देखना है।

अंदर क्या है

हर कमिट एक या एक से अधिक अभिभावकों को सूचीबद्ध कर सकता है। ये एक ग्राफ बनाते हैं, जो बाद में पहले वाले बिंदुओं पर वापस जाता है। स्टैश आम तौर पर दो कमिट रखता है, जिसे मैं iइंडेक्स / स्टेजिंग-एरिया कंटेंट और wवर्क-ट्री कंटेंट के लिए कॉल करना पसंद करता हूं । यह भी याद रखें कि प्रत्येक प्रतिबद्ध एक स्नैपशॉट रखता है। एक सामान्य प्रतिबद्धता में, यह स्नैपशॉट इंडेक्स / स्टेजिंग-एरिया कंटेंट से बनाया गया है। तो iकमिट वास्तव में एक पूरी तरह से सामान्य प्रतिबद्धता है! यह किसी भी शाखा में नहीं है:

...--o--o--o   <-- branch (HEAD)
           |
           i

यदि आप एक सामान्य स्लैश बना रहे हैं, तो git stashकोड wअब आपके सभी ट्रैक किए गए कार्य-ट्री फ़ाइलों (एक अस्थायी सहायक सूचकांक में) की नकल करके बनाता है । Git wप्रतिबद्ध करने के लिए इंगित करने के HEADलिए इस प्रतिबद्ध के पहले माता-पिता को सेट करता है , और दूसरा माता-पिता को इंगित करने के लिए i। अंतिम, यह stashइस बात की ओर इशारा wकरता है:

...--o--o--o   <-- branch (HEAD)
           |\
           i-w   <-- stash

यदि आप जोड़ते हैं --include-untrackedया --all, Git एक अतिरिक्त प्रतिबद्ध बनाता है, uबनाने iऔर के बीच में w। स्नैपशॉट सामग्री uउन फ़ाइलों के लिए होती है जो अनट्रैक की जाती हैं, लेकिन उन्हें अनदेखा नहीं किया जाता है ( --include-untracked), या उन फ़ाइलों को भी जिन्हें अनसुना किया जाता है, भले ही उन्हें अनदेखा कर दिया जाए ( --all)। इस अतिरिक्त uप्रतिबद्ध है कोई माता पिता, और फिर जब git stashबनाता है w, यह सेट wके तीसरे माता-पिता इस के लिए uप्रतिबद्ध है, ताकि आप मिल:

...--o--o--o   <-- branch (HEAD)
           |\
           i-w   <-- stash
            /
           u

Git भी, इस बिंदु पर, किसी भी कार्य-ट्री फ़ाइलों को निकालता है जो uकमिट में घाव करते हैं ( git cleanऐसा करने के लिए)।

एक स्टाॅस्ट का जीर्णोद्धार

जब आप स्टैश को पुनर्स्थापित करने के लिए जाते हैं , तो आपके पास इसका उपयोग करने --index, या न करने का विकल्प होता है। यह बताता है git stash apply(या आदेश होते हैं जो आंतरिक रूप से उपयोग किए जाने वाले किसी भी applyतरह के रूप में, pop) है कि यह करना चाहिए का उपयोगi अपने वर्तमान सूचकांक को संशोधित करने के प्रयास करने के लिए प्रतिबद्ध हैं। इस संशोधन के साथ किया जाता है:

git diff <hash-of-i> <hash-of-i's-parent> | git apply --index

(कम या ज्यादा; इसमें मूल विवरण के रूप में प्राप्त होने वाली बारीकियों का विवरण है)।

यदि आप चूक करते हैं --index, तो git stash applyपूरी तरह से iप्रतिबद्ध की उपेक्षा करें ।

यदि स्‍टैश में केवल दो कमिट हैं, तो git stash applyअब wकमिट लगा सकते हैं । यह फोन करके ऐसा करता है git merge2 (यह प्रतिबद्ध या एक सामान्य मर्ज के रूप में परिणाम के इलाज के लिए अनुमति के बिना), मूल प्रतिबद्ध है जिस पर गुप्त कोष बनाया गया था का उपयोग कर ( iके माता पिता, और wके पहले माता-पिता) मर्ज आधार के रूप में, wके रूप में --theirsप्रतिबद्ध, और आपका वर्तमान (HEAD) मर्ज के लक्ष्य के रूप में प्रतिबद्ध है। यदि मर्ज सफल हो जाता है, तो सब अच्छा है - अच्छा, कम से कम गिट ऐसा सोचता है - और git stash applyस्वयं सफल होता है। आप का उपयोग किया है git stash popगुप्त कोष में लागू करने के लिए, कोड अब चला जाता है गुप्त कोष। 3 यदि मर्ज विफल हो जाता है, तो गिट लागू होने की घोषणा करता है। अगर आपने इस्तेमाल कियाgit stash popकोड स्टैश को बनाए रखता है और उसी विफलता को स्थिति के रूप में वितरित करता है git stash apply

लेकिन अगर आपके पास वह तीसरा कमिटमेंट है - यदि uआप जो आवेदन कर रहे हैं, उसमें एक कमिट है - तो चीजें बदल जाती हैं! यह ढोंग करने का कोई विकल्प नहीं है कि uप्रतिबद्धता मौजूद नहीं है। 4 Git उस प्रतिबद्ध से सभी फाइलों uको वर्तमान कार्य-वृक्ष में निकालने पर जोर देता है । इसका मतलब यह है कि फ़ाइलों को या तो मौजूद नहीं होना चाहिए, या uकमिट में जैसी सामग्री होनी चाहिए ।

ऐसा करने के लिए, आप git cleanस्वयं का उपयोग कर सकते हैं - लेकिन याद रखें कि अनटाइटेड फ़ाइलों (अनदेखा या नहीं) का एक Git रिपॉजिटरी के अंदर कोई अन्य अस्तित्व नहीं है, इसलिए सुनिश्चित करें कि ये फ़ाइलें सभी नष्ट हो सकती हैं! या, आप एक अस्थायी निर्देशिका बना सकते हैं, और फ़ाइलों को सुरक्षित रखने के लिए वहां ले जा सकते हैं - या यहां तक ​​कि एक और git stash save -uकर सकते हैं git stash save -a, क्योंकि वे git cleanआपके लिए चलेंगे । लेकिन uबाद में इससे निपटने के लिए आप सिर्फ एक और स्टाइल के साथ छोड़ देते हैं ।


1 यह वास्तव में है refs/stash। यह तब मायने रखता है जब आप एक शाखा बनाते हैं जिसका नाम है stash: शाखा का पूरा नाम है refs/heads/stash, इसलिए ये संघर्ष में नहीं हैं। : लेकिन ऐसा नहीं है Git मन नहीं होगा, लेकिन आप अपने आप को भ्रमित करेंगे। :-)

2git stash कोड वास्तव में उपयोग करता git merge-recursiveसीधे यहाँ। यह कई कारणों से आवश्यक है, और यह सुनिश्चित करने का साइड इफेक्ट भी है कि जब आप संघर्षों को हल करते हैं तो Git इसे मर्ज नहीं मानता है।

3 यही कारण है कि मैं इसके git stash popपक्ष में, परहेज करने की सलाह देता हूं git stash apply। आपको जो मिला है उसकी समीक्षा करने का मौका मिलता है, और यह तय करें कि क्या यह वास्तव में सही तरीके से लागू किया गया था । यदि नहीं, तो आपके पास अभी भी अपना स्टैश है, जिसका अर्थ है कि आप git stash branchपूरी तरह से सब कुछ ठीक करने के लिए उपयोग कर सकते हैं । ठीक है, कि pesky uप्रतिबद्ध की कमी को मानते हुए ।

4 वास्तव में होना चाहिए: git stash apply --skip-untrackedया कुछ और। एक ऐसा संस्करण भी होना चाहिए, जिसका अर्थ है कि उन सभी uफाइलों को एक नई निर्देशिका में छोड़ दें , जैसे git stash apply --untracked-into <dir>, शायद।


वाह! आप एक पदक के लायक हैं! क्या ऐसी कोई पुस्तक है जिसे आप इस तरह के विस्तृत विवरण के लिए सुझाएंगे? बहुत बढ़िया! 9🙇 at
seelts

1
@ दुर्भाग्य से, Git लगातार विकसित हो रहा है, इसलिए किताबें जल्दी से निकल जाती हैं। लेकिन Git उपकरण-आदेशों को एक में हेरफेर के लिए प्रतिबद्ध-ful फ़ाइलों का, या हेरफेर ग्राफ प्रतिबद्ध, या का एक सेट के रूप में समझा जाना चाहिए जो कुछ भी है कि आप जो कुछ भी करने के लिए उपयोगी है में इकट्ठा तुम , और नहीं भी कई किताबें यह दृष्टिकोण है कि लगता है या तो रास्ता।
torek

3
मैं समस्या के समाधान को समझने में विफल हूं। यह सिर्फ जोड़ रहा है --index: git stash apply --index?
डेनिजेल

1
साभार @torek मैंने पहले किया git stash save --all, फिर मैंने तुरंत किया git stash apply, लेकिन कुछ फाइलें गायब थीं क्योंकि मैंने उनका नाम बदल दिया और फिर से (स्टैशिंग से पहले) बनाया। क्या मदद की थी: git checkout stash@{0} -- .मैं भी परेशान नहीं करेगा git checkout stash^3 -- .क्योंकि अब सब ठीक लगता है। यह वास्तव में क्या चल रहा था यह समझने के लिए मेरे पास समय नहीं है। धन्यवाद।
डेनिजेल

1
@ user1169587: इसका मतलब है कि यह क्या कहता है। शायद एक उदाहरण से मदद मिलेगी। मान लीजिए कि तीसरी uकमिट में एक फ़ाइल है, जिसका नाम path/to/file(कुछ सामग्री के साथ) है। आगे मान लीजिए कि आपके कार्य-वृक्ष में पहले से ही एक फ़ाइल है, जिसका नामpath/to/file है। की सामग्री को निकाला जा रहा है uहोगा प्रतिबद्ध की जगह जो भी काम आप नाम की फ़ाइल में था नई सामग्री के साथ अपने मौजूदा फ़ाइल की सामग्री को नष्ट करने path/to/file। तो Git ऐसा नहीं करेगा। आपको पहले इन सामग्रियों को स्वयं नष्ट करना होगा (पूरी तरह से फ़ाइल को हटाकर), या उन्हें नुकसान के रास्ते से हटाकर (फ़ाइल को स्थानांतरित करके)।
torek

110

मैं आपके मुद्दे को फिर से बनाने में कामयाब रहा। ऐसा लगता है कि यदि आप अनट्रैक की गई फ़ाइलों को स्टैश करते हैं और फिर आप उन फ़ाइलों (अपने उदाहरण में, foo.txtऔर bar.txt) को बनाते हैं , तो आपके पास अनट्रैक की गई फ़ाइलों में स्थानीय परिवर्तन होते हैं जो आपके लागू होने पर अधिलेखित हो जाएंगे git stash pop

इस समस्या को हल करने के लिए, आप निम्न कमांड का उपयोग कर सकते हैं। यह किसी भी सहेजे गए स्थानीय परिवर्तन को ओवरराइड करेगा ताकि सावधान रहें।

git checkout stash -- .

पिछली कमांड पर मुझे कुछ और जानकारी मिली


मेरा काम करने का पेड़ निश्चित रूप से साफ था, हालांकि अनदेखी की गई फ़ाइलों में परिवर्तन हो सकते थे।
स्टीवनबोट

1
उपयोग करने --all/ देखने -a में अनदेखा फ़ाइलें शामिल होंगी , ताकि यह प्रासंगिक हो सके।
डैनियल स्मिथ

1
मैं यह मानने जा रहा हूं कि एक ही तर्क अनदेखी फाइलों पर लागू होता है और इसे उत्तर के रूप में चिह्नित करता है (हालांकि मुझे लगता है कि git merge --squash --strategy-option=theirs stashइस मामले में दृष्टिकोण बेहतर है)।
स्टीवनबोट

सहमत, मुझे वह दूसरा तरीका पसंद है! अपने काम के साथ शुभकामनाएँ!
डैनियल स्मिथ

यह मददगार था लेकिन यह अनटैक की गई फ़ाइलों को पुनर्स्थापित नहीं करता था - अगर आपको भी यही समस्या है ( already exists, no checkout), तो नीचे दिए गए मेरे उत्तर को देखें।
एरिक कोपामन्स

26

डैनियल स्मिथ के जवाब पर विस्तार करने के लिए : यह कोड केवल ट्रैक की गई फ़ाइलों को पुनर्स्थापित करता है , भले ही आपने स्टैश बनाते समय --include-untracked(या -u) का उपयोग किया हो । आवश्यक पूर्ण कोड है:

git checkout stash -- .
git checkout stash^3 -- .
git stash drop

# Optional to unstage the changes (auto-staged by default).
git reset

यह पूरी तरह से ट्रैक की गई सामग्री (इन stash) और अनट्रैक कंटेंट (इन stash^3) को पुनर्स्थापित करता है , फिर स्टैश को हटा देता है। कुछ नोट:

  • सावधान रहें - यह आपकी स्टैश सामग्री के साथ सब कुछ अधिलेखित कर देगा!
  • फ़ाइलों को पुनर्स्थापित करने के git checkoutकारण उन सभी का स्वचालित रूप से मंचन हो जाता है, इसलिए मैंने git resetसब कुछ अस्थिर कर दिया है।
  • कुछ संसाधन उपयोग करते हैं stash@{0}और stash@{0}^3, मेरे परीक्षण में यह उसी के साथ या बिना काम करता है@{0}

सूत्रों का कहना है:


1
आप सुरक्षा कारणों से थोड़ी देर के लिए इसे क्यों छोड़ देंगे?
डेनियल

@Danijel यकीन है कि आप रोक सकता है - मुझे लगता है कि आपके उपयोग के मामले पर निर्भर करता है। अपने उद्देश्यों के लिए मैं एक बार इसे बहाल करने के बाद स्टैश के साथ किया गया था।
एरिक कोपामंस

5

अन्य उत्तरों के अलावा, मैंने थोड़ी चाल चली

  • सभी नई फ़ाइलें हटा दी गईं (पहले से मौजूद फ़ाइलें, उदाहरण के लिए foo.txt और bar.txt प्रश्न में)
  • git stash apply (किसी भी कमांड का उपयोग कर सकते हैं जैसे आवेदन, पॉप आदि)

काम नहीं कर रहा है .. हटाए गए फ़ाइलें बस फिर से छिपाने की जगह पर दिखाई देते हैं .. और इसी तरह त्रुटि होती है!
आदित्य रेवाड़ी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.