गिट में एक स्टाॅप पॉप को नष्ट करना


257

मैंने एक स्टैश पॉप किया और एक मर्ज संघर्ष था। उस प्रश्न के विपरीत जो एक डुप्लिकेट के रूप में सूचीबद्ध है, मेरे पास पहले से ही निर्देशिका में कुछ अनपेक्षित परिवर्तन थे जो मैं रखना चाहता था। मैं न केवल मर्ज संघर्ष को गायब करना चाहता हूं, बल्कि मेरी निर्देशिका को उस स्थिति में वापस लाने के लिए भी है जो यह पॉप से ​​पहले था।

मैंने कोशिश की git merge --abort, लेकिन git ने दावा किया कि कोई मर्ज नहीं था। क्या निर्देशिका में मूल रूप से मेरे द्वारा किए गए परिवर्तनों को नष्ट किए बिना एक पॉप को निरस्त करने का एक आसान तरीका है?


आपके अन-कम किए गए परिवर्तनों के लिए: क्या ये परिवर्तन पहले ही सूचकांक में थे?
जॉर्गेंसन

क्या आप जिस git का उपयोग कर रहे हैं उसका संस्करण पोस्ट कर सकते हैं।
टीनमैन


2
स्वीकृत उत्तर जटिल लगता है। मुझे लगता है कि git stash popअशुद्ध काम करने वाले डायर पर प्रयास की तरह यह कभी भी अच्छा सामान्य अभ्यास नहीं है । जिस स्थिति में आप बस git reset --hardऔर आपकी स्थिति अभी भी बरकरार है। (यह बात कमोबेश @ ब्रैडकॉच के जुड़े विषय से पता चलता है)
स्टीवन लू

1
@StevenLu, मैं सहमत हूं, लेकिन यदि आप किसी भिन्न शाखा में जाने के लिए परिवर्तनों को रोक रहे हैं, तो यह समस्या एक साफ-सुथरी कार्यप्रणाली में हो सकती है। इस टकराव के साथ टकराव होता है जो नई शाखा पर मौजूद होता है जो पुराने पर मौजूद नहीं था।
जेक स्टीवंस-हास

जवाबों:


55

ठीक है, मुझे लगता है कि मैंने "गिट स्टैप अनपेली" काम किया है। यह इससे अधिक जटिल है git apply --reverseक्योंकि यदि आपके द्वारा किए गए किसी भी विलय के मामले में आपको रिवर्स मर्जिंग कार्रवाई की आवश्यकता है git stash apply

रिवर्स मर्ज की आवश्यकता है कि सभी वर्तमान परिवर्तनों को सूचकांक में धकेला जाए:

  • git add -u

उसके बाद merge-recursiveइसके द्वारा किया गया था git stash apply:

  • git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1

अब आप केवल गैर-स्टेश परिवर्तनों के साथ बचे रहेंगे। वे सूचकांक में होंगे। git resetयदि आप चाहें तो अपने परिवर्तनों को अस्थिर करने के लिए उपयोग कर सकते हैं ।

यह देखते हुए कि आपका मूल git stash applyविफल हुआ, मुझे लगता है कि रिवर्स भी विफल हो सकता है क्योंकि इसमें से कुछ को पूर्ववत् करना चाहता है।

यहां एक उदाहरण दिखाया गया है कि कैसे काम की प्रतिलिपि (के माध्यम से git status) फिर से साफ हो जाती है:

 $ git status
# On branch trunk
nothing to commit (working directory clean)
 $ git stash apply
Auto-merging foo.c
# On branch trunk
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.c
#
no changes added to commit (use "git add" and/or "git commit -a")
 $ git add -u
 $ git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1
Auto-merging foo.c
 $ git status
# On branch trunk
nothing to commit (working directory clean)

2
ऐसा करने के बाद, पहले से ही संपादित किए गए संपादन हमेशा के लिए खो जाएंगे, या क्या वे वापस स्टैश में हैं?
ब्रायन एच।

7
git stash applyकभी git stash popभी एक
स्लैश नहीं गिराता है

खराब चीजें तब होंगी जब मूल
स्लैश

286

मेरा उपयोग मामला: बस गलत शाखा पर पॉपिंग की कोशिश की और संघर्ष हुआ। मुझे बस पॉप को पूर्ववत करना है लेकिन इसे स्टैश सूची में रखना है ताकि मैं इसे सही शाखा पर पॉप आउट कर सकूं। इसे मैने किया है:

git reset HEAD --hard
git checkout my_correct_branch
git stash pop

आसान।


22
तो जब तक आप एक सफल पॉप नहीं चाहते हैं, तब तक जो स्टैश सूची में रहता है, वह स्टैश?
रयान क्लार्क

52
यह मूल प्रश्न का उत्तर नहीं है क्योंकि यह उन स्थानीय परिवर्तनों को मिटा देगा जो प्रतिबद्ध नहीं थे।
दिमित्री

13
@RyanClark डेविडजी का जवाब नीचे देखें। मूल रूप से, हाँ, यह स्टैश सूची में रहता है।
fkorsa

1
मुझे लगता है कि अधिकांश उपयोगकर्ता जो इस स्थिति में खुद को पाते हैं, वे इस समाधान को आदर्श पाएंगे। मैं ऐसी स्थिति की कल्पना नहीं कर सकता, जहाँ मैंने इसमें काम करने का प्रयास करने से पहले अपनी कार्यशील निर्देशिका में परिवर्तन न किए हों stash pop। जो कि आपदा का नुस्खा लगता है।
Shadoninja

2
अच्छा लगा। इसे पढ़ने के बाद मैंने git stash पॉप डॉक्स को देखा और यह कहता है कि "राज्य को लागू करना संघर्षों के साथ विफल हो सकता है, इस मामले में, इसे स्टैश सूची से हटाया नहीं जाता है।" तो, यही कारण है कि एक रीसेट / चेकआउट के बाद स्टैश फिर से पॉप-अप होने में सक्षम है।
ब्रैडी होल्ट

48

संपादित करें: git help stashपॉप अनुभाग में प्रलेखन से :

राज्य को लागू करना संघर्षों के साथ विफल हो सकता है; इस स्थिति में, इसे स्‍टैश सूची से हटाया नहीं जाता है। आपको हाथ से संघर्ष को हल करने और बाद में मैन्युअल रूप से गिट स्टैश ड्रॉप को कॉल करने की आवश्यकता है।

यदि --इंडेक्स विकल्प का उपयोग किया जाता है, तो न केवल कार्यशील पेड़ के परिवर्तन को बहाल करने की कोशिश करता है, बल्कि सूचकांक के भी। हालांकि, यह विफल हो सकता है, जब आपके पास संघर्ष होता है (जो सूचकांक में संग्रहीत होता है, जहां आप इसलिए अब परिवर्तनों को लागू नहीं कर सकते हैं क्योंकि वे मूल रूप से थे)।

अपने सभी रेपो को नए डायर में बदलने की कोशिश करें (ताकि आपके पास इसकी एक प्रति हो) और चलाएं:

git stash show और अगर आप इसके बारे में परवाह करते हैं तो उस आउटपुट को कहीं और सेव करें।

तब: git stash dropपरस्पर विरोधी संघर्ष को रोकने के लिए:git reset HEAD

उस अवस्था में अपना रेपो छोड़ देना चाहिए जो पहले था (उम्मीद है, मैं अभी भी आपकी समस्या को दूर करने में सक्षम नहीं हूं)

===

मैं आपकी समस्या को दूर करने की कोशिश कर रहा हूं, लेकिन जब मुझे कुछ होता git stash popहै:

error: Your local changes to the following files would be overwritten by merge:
...
Please, commit your changes or stash them before you can merge.
Aborting

एक साफ डायर में:

git init
echo hello world > a
git add a & git commit -m "a"
echo hallo welt >> a
echo hello world > b
git add b & git commit -m "b"
echo hallo welt >> b
git stash
echo hola mundo >> a
git stash pop

मैं अपने परिवर्तनों को मर्ज करने की कोशिश नहीं कर रहा हूँ, यह बस विफल हो जाता है। क्या आपके पास कोई रेप्रो चरण है जिसे हम आपकी सहायता करने के लिए अनुसरण कर सकते हैं?


किसी भिन्न फ़ाइल में परिवर्तन को रोकने का प्रयास करें।
asmeurer

एक अलग फ़ाइल में जाने की कोशिश करने से काम नहीं चला (नए रेप्रो चरण देखें)। मैं सिर्फ इस मुद्दे को
खारिज

1
यह समाधान काम नहीं करता है अगर वर्किंग डायरेक्टरी में अनक्मिटेड बदलाव होते हैं।
यहाँ

@ यहां यह एक वास्तविक समाधान नहीं है, यह केवल यह दिखाने के लिए है कि ओपी के पास जो समस्या है, मैं उसे पुन: पेश नहीं कर सकता हूं और उसने जहां वह है वहां पहुंचने के लिए कोई कदम नहीं दिया है।
डेविड जूल

1
वास्तविक परिदृश्य यह है: 1) फ़ाइल ए 2 बदलें) स्लैश परिवर्तन 3) फ़ाइल ए और कमिट (जैसे उसी लाइन को बदलें) 4 में परिवर्तन करें। फ़ाइल 5 बी बदलें) 'स्टैट पॉप पॉप' करें। अब आपके पास संघर्ष और स्थानीय परिवर्तन हैं। आम तौर पर वे अलग-अलग फ़ाइलों में होंगे, लेकिन आपको कभी भी पता नहीं चलेगा कि कौन सी गैर-परस्पर विरोधी फाइलें स्टैश से संशोधित हैं और जो स्थानीय अस्थिर परिवर्तन हैं।
दिमित्री

16

मैंने हमेशा इस्तेमाल किया है

git reset --merge

मुझे याद है कि यह कभी असफल नहीं हो सकता।


@ गौरवपालीवाल, मैं अगली बार एक नज़र डालूँगा git reset। क्या आप जानते हैं कि यह कार्यात्मक रूप से समान है git reset --merge?
केएन सेबेस्टा

5

यदि आपको अपने द्वारा किए गए किसी भी अन्य बदलाव के बारे में चिंता करने की ज़रूरत नहीं है और आप बस अंतिम प्रतिबद्ध पर वापस जाना चाहते हैं, तो आप ऐसा कर सकते हैं:

git reset .
git checkout .
git clean -f

4

ठीक है, मुझे लगता है कि मैं एक काम-प्रवाह खोजने में कामयाब रहा हूं जो आपको वापस उसी स्थान पर ले जाएगा जहां आपको होना चाहिए (जैसे कि आपने पॉप नहीं किया था)।

एक बेकअप से पहले ले लो !! मुझे नहीं पता कि यह आपके लिए काम करेगा या नहीं, इसलिए अपने पूरे रेपो को कॉपी करें जब यह काम नहीं करता है।

1) मर्ज की समस्याओं को ठीक करें और पैच से आने वाले सभी परिवर्तनों का चयन करके सभी संघर्ष को ठीक करें (टॉर्टोसेमर्गेस में, यह एक दिखावा है। REMOETE (उनका))।

git mergetool

2) इन परिवर्तनों को प्रतिबद्ध करें (वे पहले से ही मर्जटूल कमांड के माध्यम से जोड़ दिए जाएंगे)। इसे "मर्ज" या ऐसा कुछ संदेश दें जो आपको याद हो।

git commit -m "merge"

3) अब आपके पास अपने स्थानीय अस्थिर परिवर्तन होंगे जो आपने मूल रूप से शुरू किए थे, पैच से एक नई प्रतिबद्धता के साथ (हम बाद में इससे छुटकारा पा सकते हैं)। अब अपने अस्थिर परिवर्तन करें

git add .
git add -u .
git commit -m "local changes"

4) पैच उल्टा करें। यह निम्नलिखित कमांड के साथ किया जा सकता है:

git stash show -p | git apply -R

5) ये बदलाव करें:

git commit -a -m "reversed patch"

6) पैच / अनपेच कमिट्स से छुटकारा पाएं

git rebase -i HEAD^^^

इसमें से 'मर्ज' और 'उलट पैच' वाली दो लाइनें हटा दें।

7) अपने अनस्टैंग्ड परिवर्तन वापस लाएं और 'स्थानीय परिवर्तन' को पूर्ववत करें

git reset HEAD^

मैंने इसे एक साधारण उदाहरण के साथ चलाया है और यह आपको वापस वहीं पहुंचा देता है, जहाँ आप होना चाहते हैं - सीधे सीधे स्टैश पॉप होने से पहले, आपके स्थानीय बदलावों के साथ और स्टैश अभी भी पॉप में उपलब्ध है।


अगर वह काफी काम नहीं करता है, तो उम्मीद है कि यह आपको वहां सबसे ज्यादा मिलेगा! :-)
एजेंटगंजो

git stash show -p | git apply -Rअगर git stash applyकोई वास्तविक विलय नहीं हुआ तो वह काम नहीं करता है । मेरा जवाब देखें ...
बेन जैक्सन

3

मैंने इसे कुछ अलग तरीके से हल किया। यहाँ क्या हुआ है।

सबसे पहले, मैं गलत शाखा पर पॉप गया और संघर्ष हुआ। यह टकराव बरकरार रहा लेकिन सूचकांक कई आदेशों को अवरुद्ध करते हुए, विवाद समाधान में था।

एक साधारण git reset HEADने संघर्ष के प्रस्ताव को निरस्त कर दिया और अधूरा छोड़ दिया (और UNWANTED) ) परिवर्तनों को ।

कई git co <filename>ने सूचकांक को प्रारंभिक स्थिति में वापस ला दिया। अंत में, मैंने git co <branch-name>एक नई शाखा के साथ स्विच किया और चलाया git stash pop, जो संघर्षों के बिना हल हुई।


2

कुछ विचार:

  • git mergetoolमर्ज फ़ाइलों को मूल और नए भागों में विभाजित करने के लिए उपयोग करें । उम्मीद है कि उनमें से एक फाइल है जिसमें आपके नॉन-स्टैश बदलाव हैं।

  • केवल उन परिवर्तनों को पूर्ववत करने के लिए, स्टैश के भिन्न को रिवर्स में लागू करें। आपको शायद फ़ाइलों को मर्ज संघर्षों के साथ मैन्युअल रूप से विभाजित करना होगा (जो उम्मीद है कि उपरोक्त चाल के लिए काम करेगा)।

मैंने इनमें से किसी का भी परीक्षण नहीं किया, इसलिए मुझे नहीं पता कि वे काम करेंगे।


1

मैं git stash pop"गंदे" निर्देशिका पर साफ कर सकता हूं , बिना किसी परिवर्तन के, लेकिन अभी तक पॉप नहीं जो एक मर्ज संघर्ष उत्पन्न करता है।

यदि मर्ज संघर्ष पर गुप्त कोष में आप लागू करने के लिए गायब हो जाते हैं न पहुंच पाए, तो आप जांच करने के लिए कोशिश कर सकते हैं git show stash@{0}(वैकल्पिक साथ --oursया --theirs) और इससे तुलना git statisऔर git diff HEAD। आपको यह देखने में सक्षम होना चाहिए कि स्टेश लगाने से कौन से बदलाव आए।


1

यदि डेविड जी सही हैं कि यह मर्ज संघर्ष के कारण स्टैश पॉप नहीं करता है, तो आपको केवल अपने कामकाजी निर्देशिका को साफ करने की आवश्यकता है। जल्दी git commitसब कुछ आप के बारे में परवाह है। (आप बाद में कर सकते हैं resetया कर सकते हैं squashयदि आप नहीं कर रहे हैं।) फिर सब कुछ आप सुरक्षित, git resetसब कुछ है कि git stash popअपने काम निर्देशिका में फेंक दिया के बारे में परवाह है ।


1

यदि git stash popइस प्रश्न के अनुसार , पहले कोई परिवर्तन नहीं हुए थे , तो निम्नलिखित दो कमांड काम करने चाहिए।

git diff --name-only --cached | xargs git checkout --ours HEAD
git ls-tree stash@{0}^3 --name-only | xargs rm

पहला, किसी भी मर्ज को स्टैश से उलट देता है, सफल या नहीं। दूसरा स्टैश द्वारा शुरू की गई किसी भी अनट्रैक की गई फ़ाइल को हटा देता है।

प्रेषक man git stash: The working directory must match the index. जो @DavidG बताता है, वह stash popविफल हो जाएगा यदि कोई भी वर्तमान में बिना किसी संशोधित फ़ाइल संघर्ष के। इस तरह, हमें वापस जाने से पहले मर्जिंग कॉनफ़्लिक्ट्स के बारे में चिंता करने की आवश्यकता नहीं होनी चाहिए HEAD। किसी भी बची हुई संशोधित फ़ाइलों को तब स्टैस से असंबंधित किया जाता है, और इससे पहले संशोधित किया गया थाstash pop

यदि वहाँ परिवर्तन किए गए थे, तो मैं स्पष्ट नहीं हूँ कि क्या हम उसी आदेशों पर भरोसा कर सकते हैं और आप @Ben जैक्सन की तकनीक को आजमाना चाहते हैं। सुझावों की सराहना की ..

यहाँ विभिन्न मामलों के सभी के लिए एक परीक्षण सेटअप है https://gist.github.com/here/4f3af6dafdb4ca15e804

# Result:
# Merge succeeded in m (theirs)
# Conflict in b
# Unstaged in a
# Untracked in c and d

# Goal:
# Reverse changes to successful merge m
# Keep our version in merge conflict b
# Keep our unstaged a
# Keep our untracked d
# Delete stashed untracked c

मुझे लगता है कि यह अब तक का सबसे सही जवाब है। बहुत अच्छी तरह से सोचा।
एजेंट शुक्रवार

0

git reflogअपने गिट इतिहास में किए गए सभी परिवर्तनों को सूचीबद्ध करने के लिए उपयोग करें । एक कार्रवाई आईडी और प्रकार की प्रतिलिपि बनाएँgit reset ACTION_ID


2
इससे पहले कि आप पॉप करें (आपको कमिट करने की आवश्यकता है)
रीफ्लिट

-1

मैं यहाँ पोस्ट कर रहा हूँ उम्मीद है कि दूसरों को मेरा जवाब मददगार लगता है। जब मैं इससे अलग था, तो मुझे एक अलग समस्या थी जब मैंने एक अलग शाखा पर एक स्टैश पॉप करने की कोशिश की थी। मेरे मामले में मेरे पास ऐसी कोई फाइल नहीं थी जो अनकम्युनिटेड थी या इंडेक्स में थी, लेकिन फिर भी मर्ज संघर्ष मामले (@pid के रूप में एक ही मामला) में मिला। जैसा कि अन्य लोगों ने पहले बताया था, असफल git stash pop ने वास्तव में मेरे stash को बनाए रखा है, फिर एक त्वरित git रीसेट HEAD प्लस मेरी मूल शाखा में वापस जा रहा है और वहाँ से stash कर मेरी समस्या का समाधान किया है।

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