क्या मैं एक जीआईटी कमिट को हटा सकता हूं लेकिन बदलाव को रख सकता हूं


1055

मेरी एक विकास शाखा में, मैंने अपने कोडबेस में कुछ बदलाव किए। इससे पहले कि मैं जिन विशेषताओं पर काम कर रहा था, उन्हें पूरा करने में सक्षम होने से पहले, मुझे कुछ विशेषताओं को प्रदर्शित करने के लिए अपनी वर्तमान शाखा को मास्टर में बदलना पड़ा। लेकिन सिर्फ एक "गिट चेकआउट मास्टर" का उपयोग करके मैंने अपने विकास शाखा में किए गए परिवर्तनों को संरक्षित किया, इस प्रकार मास्टर में कुछ कार्यक्षमता को तोड़ दिया। इसलिए मैंने जो किया वह एक प्रतिबद्ध संदेश "अस्थायी प्रतिबद्ध" और फिर डेमो के लिए चेकआउट मास्टर के साथ मेरी विकास शाखा में बदलाव के लिए प्रतिबद्ध था।

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


65
अगली बार:git stash
मैट बॉल

51
@MattBall, जरूरी नहीं। जबकि git stashएक अच्छा उपकरण है, "प्रगति में काम" फेंक-दूर हिट काफी वैध उपकरण हैं, भी।
कोस्टिक्स

3
यह Github से स्ट्रेट एक महान संसाधन है: पूर्ववत कैसे Git के साथ (लगभग) कुछ भी
jasonleonhard

9
@MattBall @kostix हाँ, स्टैश विशेष रूप से "लॉन्ग-टर्म" स्टैशिंग के लिए अनुकूल है, यह देखते हुए कि यह पूरे रेपो के लिए एक वैश्विक स्टैक है। मैं चाहता हूं कि मैं एक शाखा में बदलाव ला सकूं और फिर दूसरी शाखाओं में जाऊं, जो भी करूं, कुछ दिन बाद वापस आऊं, बिना इस चिंता के कि मैं git stashअंतरिम में किसी और शाखा में इस्तेमाल कर सकता हूं ।
एलेक

4
एक बात ध्यान देने योग्य stashहै कि यह पूरी तरह से स्थानीय है और रेपो-विलोपन या मनोरंजन या हार्डवेयर विफलता या हानि से कोड हानि का खतरा होगा। IMO, यह वास्तव में केवल बहुत छोटी अवधि के लिए इस्तेमाल किया जाना चाहिए WIP। छुट्टी पर जाने से पहले एक डब्ल्यूआईपी कमिटमेंट से प्यार करें: पी .. इसे ब्रेन डंप कमिट कहें!
18ο atMεδιϲ

जवाबों:


1617

यह इस तरह सरल है:

git reset HEAD^

नोट: कुछ गोले ^एक विशेष चरित्र के रूप में व्यवहार करते हैं (उदाहरण के लिए कुछ विंडोज गोले या ग्लोबिंग सक्षम के साथ ZSH ), इसलिए आपको "HEAD^"उन मामलों में उद्धृत करना पड़ सकता है ।

git resetबिना किसी फ़ाइल को बदले, बिना निर्दिष्ट किए हुए बिंदु पर जाने के लिए --hardया --softआपकी ओर बढ़ता है HEADHEAD^आपके वर्तमान कमेटी के (पहले) मूल माता-पिता को संदर्भित करता है, जो आपके मामले में अस्थायी से पहले की प्रतिबद्धता है।

ध्यान दें कि एक अन्य विकल्प सामान्य के रूप में ले जाने के लिए है, और फिर चलाने के बजाय अगले प्रतिबद्ध बिंदु पर:

git commit --amend [-m … etc]

इसके बजाय ऊपर के रूप में एक ही प्रभाव होने पर, सबसे हालिया प्रतिबद्ध को संपादित करेगा ।

ध्यान दें कि यह (लगभग हर गिट जवाब के साथ) समस्या पैदा कर सकता है यदि आपने पहले से ही खराब प्रतिबद्ध को उस स्थान पर धकेल दिया है, जहां से किसी और व्यक्ति ने इसे खींच लिया है। उससे बचने की कोशिश करें


47
यह अब तक का सबसे सरल है, लेकिन अगर आपने पहले ही अपनी प्रतिबद्धता को रिमोट से धकेल दिया है और किसी और ने इसे खींच लिया है, तो मुझे माफी माँगने के अलावा कुछ भी करने में बहुत संकोच होगा।
atw13

11
@ सिस्कोफ्रेनिक, इस अवसर पर "रीसेट डेमिस्टिफ़ाइड " पढ़ने के लिए अपारदर्शिता को याद न करें
कोस्टिक्स

33
मुझे More?ऐसा करने के बाद मिलता है । जो कुछ भी मैं उस संकेत पर fatal: ambiguous argument 'HEADwhateverItypedIn': unknown revision or path not in the working tree.
लिखता

50
@DaAwesomeP लगता है कि आप एक शेल का उपयोग कर रहे हैं जो ^एक विशेष चरित्र के रूप में व्यवहार करता है । आप या तो संदर्भ उद्धृत कर सकता है "HEAD^", या का उपयोग वैकल्पिक वाक्य रचना HEAD~1गैर उद्धृत
गैरेथ

8
मेरे लिए काम किया, हालांकि चरित्र से बचना थाgit reset HEAD\^
cevaris

188

इससे निपटने के दो तरीके हैं। जो आसान है वह आपकी स्थिति पर निर्भर करता है

रीसेट

यदि आप जिस कमिटमेंट से छुटकारा पाना चाहते हैं, वह आखिरी कमिटमेंट था, और आपने कोई अतिरिक्त काम नहीं किया है, जिसका आप आसानी से उपयोग कर सकते हैं git-reset

git reset HEAD^

अपनी वर्तमान HEAD से ठीक पहले अपनी शाखा को वापस प्रतिबद्ध कर लेता है। हालाँकि, यह वास्तव में आपके काम के पेड़ में फ़ाइलों को नहीं बदलता है। नतीजतन, उस बदलाव में जो बदलाव हुए, वह संशोधित हुए - एक 'अनलमिटी' कमांड की तरह। वास्तव में, मेरे पास ऐसा करने के लिए एक उपनाम है।

git config --global alias.uncommit 'reset HEAD^'

तब आप git uncommitभविष्य में सिर्फ एक कमिट का सहारा ले सकते हैं।

कुचलने

कमिट करने का मतलब है दो या दो से अधिक का संयोजन। मैं अक्सर ऐसा करता हूं। आपके मामले में आपके पास एक आधा किया हुआ फीचर शुरू हो गया है, और फिर आप इसे समाप्त कर देंगे और फिर से उचित, स्थायी संदेश के साथ प्रतिबद्ध होंगे।

git rebase -i <ref>

मैं ऊपर कहता हूं क्योंकि मैं यह स्पष्ट करना चाहता हूं कि यह किसी भी संख्या में वापस हो सकता है। दौड़ें git logऔर उस कमिटमेंट को खोजें जिससे आप छुटकारा पाना चाहते हैं, इसके SHA1 को कॉपी करें और इसके स्थान पर इसका उपयोग करें <ref>। Git आपको इंटरएक्टिव रिबेस मोड में ले जाएगा। यह आपकी वर्तमान स्थिति और आपके स्थान पर जो कुछ भी डालता है, उसके बीच सभी कमिट्स दिखाएगा <ref>। तो अगर <ref>पहले 10 कमिट्स हैं, तो यह आपको सभी 10 कमिट्स दिखाएगा।

प्रत्येक प्रतिबद्ध के सामने, यह शब्द होगा pick। प्रतिबद्ध आप से छुटकारा पाने और से इसे बदलना चाहते का पता लगाएं pickकरने के लिए fixupया squashfixupसंदेश भेजने और संदेश में अपने तत्काल पूर्ववर्ती में परिवर्तन को मर्ज करने वाले केवल सादर का उपयोग करना । squashकीवर्ड एक ही बात करता है, लेकिन आप नव संयुक्त प्रतिबद्ध के संदेश के लिए प्रतिबद्ध संपादित करने के लिए अनुमति देता है।

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

चेतावनी:

रिबासिंग इतिहास को संशोधित करता है - ऐसा न करें कि आप पहले से ही अन्य डेवलपर्स के साथ साझा कर चुके हैं।

stashing

भविष्य में, इस समस्या से बचने के git stashलिए अस्थायी रूप से बिना काम के स्टोर का उपयोग करने पर विचार करें ।

git stash save 'some message'

यह आपके वर्तमान परिवर्तनों को आपकी स्‍टैश सूची में किनारे पर संग्रहीत कर देगा। ऊपर स्टैश कमांड का सबसे स्पष्ट संस्करण है, जो टिप्पणी करने की अनुमति देता है कि आप क्या चोरी कर रहे हैं। आप बस चला भी सकते हैं git stashऔर कुछ नहीं, लेकिन कोई संदेश संग्रहीत नहीं किया जाएगा।

आप अपनी स्‍टैश सूची ब्राउज़ कर सकते हैं ...

git stash list

यह आपको आपके सभी स्टैड्स दिखाएगा कि वे किस ब्रांच पर किए गए थे, और मैसेज और प्रत्येक लाइन की शुरुआत में, और उस स्टैश के लिए आइडेंटिफ़ायर जो इस तरह दिखता है stash@{#}जहाँ # स्टैस की सरणी में उसकी पोजीशन है।

एक स्‍टैश को पुनर्स्थापित करने के लिए (जो किसी भी शाखा पर किया जा सकता है, चाहे स्‍टैश मूल रूप से बनाया गया हो) आप बस चलाते हैं ...

git stash apply stash@{#}

फिर, वहाँ # स्टैम्स की सरणी में स्थिति है। यदि आप जिस स्‍टेश को बहाल करना चाहते हैं, वह 0स्थिति में है - अर्थात, यदि यह सबसे हालिया स्‍टेश था। फिर आप बस स्टैश स्थिति को निर्दिष्ट किए बिना कमांड चला सकते हैं, गिट आपको मान लेंगे कि अंतिम एक का मतलब है git stash apply:।

इसलिए, उदाहरण के लिए, यदि मैं खुद को गलत शाखा पर काम करता हुआ पाता हूं - तो मैं निम्नलिखित अनुक्रम चला सकता हूं।

git stash
git checkout <correct_branch>
git stash apply

आपके मामले में आप शाखाओं के चारों ओर थोड़ा अधिक चले गए, लेकिन एक ही विचार अभी भी लागू होता है।

उम्मीद है की यह मदद करेगा।


6
git config --global alias.uncommit reset HEAD^बस उपनाम रीसेट करने के लिए अयोग्य। इसके बजाय, क्या करते हैंgit config --global alias.uncommit 'reset HEAD^'
mernst

3
ध्यान दें कि अगर आपको विंडोज़ कमांड प्रॉम्प्ट में उपयोग करना है तो ^ के बजाय ^ ^ का उपयोग करना होगा।
प्रमोद BR

106

मुझे लगता है कि आप इसके लिए देख रहे हैं

git reset --soft HEAD~1

यह मंचन में किए गए परिवर्तनों को ध्यान में रखते हुए सबसे हालिया प्रतिबद्ध को पूर्ववत् करता है।


7
धन्यवाद। इसने मेरे लिए काम किया। git reset HEAD^विंडोज पर कॉल करना केवल "अधिक?" - जो भी इसका मतलब है
टायरन

12
@Tyron ^DOS में एक एस्केप कैरेक्टर है। जब एक नई लाइन के साथ जोड़ा जाता है, तो यह पूर्ववर्ती कमांड के लिए निरंतरता प्रांप्ट के रूप में कार्य करता है। टाइपिंग git reset HEAD^^विंडोज पर काम करना चाहिए।
trk

40

हां, आप परिवर्तनों को हटाए बिना अपनी प्रतिबद्धता को हटा सकते हैं: git रीसेट @ ~


7
यह वास्तव में मैं क्या चाहता हूं, और यह मेरी राय में स्वीकृत उत्तर होगा, बहुत धन्यवाद!
कार्लोस लियू

2
दिलचस्प, कॉम्पैक्ट वाक्यविन्यास, मैंने पहले कभी इसका इस्तेमाल नहीं किया था। यह कैसे git reset --softया से अलग है git reset --keep?
user776686

18

आप के लिए या तो देख रहे हैं git reset HEAD^ --softया git reset HEAD^ --mixed

डॉक्स में बताए अनुसार रीसेट कमांड के 3 तरीके हैं :

git reset HEAD^ --soft

पूर्ववत करें git commit। वर्किंग ट्री (प्रोजेक्ट फ़ोल्डर) + इंडेक्स (- कैश) में अभी भी परिवर्तन मौजूद हैं

git reset HEAD^ --mixed

पूर्ववत करें git commit+ git add। काम करने वाले पेड़ में अभी भी परिवर्तन मौजूद हैं

git reset HEAD^ --hard

जैसे आपने कभी इन परिवर्तनों को कोडबेस में नहीं किया। काम के पेड़ से परिवर्तन चला गया है।


9

Zsh का उपयोग करने वालों के लिए, आपको निम्नलिखित का उपयोग करना होगा:

git reset --soft HEAD\^

यहाँ समझाया गया: https://github.com/robbyrussell/oh-my-zsh/issues/449

यदि URL मृत हो जाता है, तो यह महत्वपूर्ण हिस्सा है:

अपने आदेश में ^ बच

आप वैकल्पिक रूप से HEAD ~ का उपयोग कर सकते हैं ताकि आपको हर बार इसे बचाना न पड़े।


15
मैं इस कमांड को कभी याद नहीं रख सकता और इसे गूगल करना होगा और अपना जवाब
हाहाहा ढूंढना होगा

2
git reset HEAD^मेरे लिए zsh में काम कर रहा है, निश्चित किया गया है।
बेन कोला मैन्सले

@BenKolyaMansley आप कौन सा संस्करण चला रहे हैं?
ग्रेग हिल्स्टन

मैं उपयोग कर रहा हूंzsh 5.3 (x86_64-apple-darwin18.0)
बेन कोला मैन्सले

7

मेरे मामले में, मैंने पहले ही रेपो को धक्का दे दिया। आउच!

आप अपनी स्थानीय फ़ाइलों में परिवर्तन करते हुए एक विशिष्ट वचनबद्धता को वापस कर सकते हैं:

git revert -n <sha>

इस तरह मैं उन बदलावों को रखने में सक्षम था, जिनकी मुझे ज़रूरत थी और एक ऐसे वचन को रद्द कर दिया, जिसे पहले ही धकेल दिया गया था।


मेरे मामले में, मुझे कुछ वापस करने की आवश्यकता थी जिसे मैंने पहले से ही दूरस्थ भंडार में धकेल दिया था। और भी ज्यादा! सबसे अच्छा तरीका था git revert bad-commit-sha, तब git revert -n revert-commit-just-created-shaऔर फिर वहाँ से मरम्मत करना। आपने मुझे आधा कर दिया। धन्यवाद!
TinkerTenorSoftwareGuy

यह विपरीत करने के लिए लगता है, नहीं? यह नए परिवर्तन बनाता है जो चयनित कमिट में किए गए परिवर्तनों के प्रतिफल के अनुरूप होता है। यदि आप इन नए परिवर्तनों को करने के लिए थे, तो आपको वह काम पूर्ववत करना होगा जो आप वास्तव में रखना चाहते थे।
सावंस

3

Git 2.9 का उपयोग करना (अधिक सटीक रूप से 2.9.2.windows.1) git reset HEAD^अधिक के लिए संकेत देता है; यह निश्चित नहीं है कि यहाँ अपेक्षित इनपुट क्या है। कृपया नीचे स्क्रीनशॉट देखें

यहां छवि विवरण दर्ज करें

अन्य समाधान मिले git reset HEAD~#numberOfCommitsजिनका उपयोग करके हम आपके परिवर्तनों को अक्षुण्ण रखते हुए उन स्थानीय कमिटों की संख्या चुन सकते हैं जिन्हें आप रीसेट करना चाहते हैं। इसलिए, हमें सभी स्थानीय कमिटों के साथ-साथ सीमित संख्या में स्थानीय कमैंट्स को भी फेंकने का अवसर मिलता है।

git reset HEAD~1कार्रवाई में प्रदर्शित स्क्रीनशॉट के नीचे देखें : यहां छवि विवरण दर्ज करें

यहां छवि विवरण दर्ज करें


आपको संभवतः ^ वर्ण से बचने की आवश्यकता है - "रीसेट ^" की कोशिश करें या जीआईएटी रीसेट रीसेट करें ^ ^
मार्क फिशर

इसे जोड़ने पर, एक जीआईएटी रीसेट HEAD ^ ^ एकल के रूप में काम करता है ^ को एक नई लाइन के रूप में माना जाता है।
जॉन ऑस

2

इसे करने का एक और तरीका।

अस्थायी प्रतिबद्ध के शीर्ष पर कमिट जोड़ें और फिर करें:

git rebase -i

दो कमिट्स को एक में मर्ज करने के लिए (कमांड स्पष्ट निर्देशों के साथ टेक्स्ट फ़ाइल खोलेगी, इसे संपादित करें)।


2
तकनीकी रूप से सही लेकिन कहीं नहीं के रूप में बस के रूप में सुरुचिपूर्ण पास git reset HEAD^। Git rebase में त्रुटि के लिए बहुत जगह है।
बजज़सॉ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.