एक सफल "git चेरी-पिक" को पूर्ववत कैसे करें?


97

एक स्थानीय रेपो पर, मैंने अभी-अभी अमल किया है git cherry-pick SHA बिना किसी संघर्ष या समस्याओं के है। मुझे तब एहसास हुआ कि मैं वही नहीं करना चाहता जो मैंने किया है। मैंने इसे कहीं नहीं धकेला है।

मैं इस चेरी पिक को कैसे हटा सकता हूं?

मैं यह जानना चाहूंगा कि क्या ऐसा करने का कोई तरीका है:

  • जब मेरे पास अन्य स्थानीय परिवर्तन होंगे
  • जब मेरे पास कोई अन्य स्थानीय परिवर्तन नहीं है

यदि संभव हो तो दोनों मामलों के लिए एक कमांड के साथ अधिमानतः।

जवाबों:


133

एक चेरी-पिक मूल रूप से एक प्रतिबद्ध है, इसलिए यदि आप इसे पूर्ववत करना चाहते हैं, तो आप बस इसे पूर्ववत करें।

जब मेरे पास अन्य स्थानीय परिवर्तन होंगे

अपने वर्तमान परिवर्तनों को रोकें ताकि आप उन्हें कमिट करने के बाद पुन: लागू कर सकें।

$ git stash
$ git reset --hard HEAD^
$ git stash pop  # or `git stash apply`, if you want to keep the changeset in the stash

जब मेरे पास कोई अन्य स्थानीय परिवर्तन नहीं है

$ git reset --hard HEAD^

6
बस सवाल और जवाब के अलावा अगर आपको यकीन नहीं है कि आप चेरी-पिक-आईएनजी हैं तो आप हमेशा 'चेरी-एसएचए -नो-कमिट' कर सकते हैं और कोई भी ऐसा बदलाव नहीं होगा, जिसे आसानी से जांचा जा सके , यह आंशिक रूप से चेरी-पिकिंग के लिए उपयोगी है
kuskmen

1
विंडोज़: git रीसेट
स्लिम

21

अपनी अंतिम प्रतिबद्धता को पूर्ववत करने के लिए, बस करें git reset --hard HEAD~

संपादित करें : यह उत्तर उस प्रश्न के पुराने संस्करण पर लागू होता है जिसमें स्थानीय परिवर्तनों के संरक्षण का उल्लेख नहीं था; टिम से स्वीकृत उत्तर वास्तव में सही है। सिर के लिए qwertzguy के लिए धन्यवाद।



वे दोनों HEAD के बराबर हैं (और HEAD ^ 1, उस मामले के लिए)
डेविड Deutsch

1
@DavidDeutsch यह सच है (हालांकि केवल Git के अधिक हाल के संस्करणों में), लेकिन अपरकेस ( HEAD) अधिक मजबूत है: दुर्भाग्यपूर्ण मामले पर विचार करें जहां headमौजूदा संदर्भ का नाम है।
जुब्स

1
@ जुब्स - अच्छी बात; मैंने अपने उत्तर में आवरण बदल दिया है।
डेविड

1
@qwertzguy, अच्छी पकड़; टाइमस्टैम्प को देखते हुए, स्थानीय परिवर्तन के बारे में थोड़ा सा प्रश्न एक मिनट के बाद जोड़ा गया जब मैंने यह उत्तर पोस्ट किया :)
डेविड

8

यदि संभव हो, तो हार्ड रीसेट से बचें। हार्ड रीसेट git में बहुत कम विनाशकारी कार्यों में से एक है। सौभाग्य से, आप बिना चेरी के चेरी-पिक को पूर्ववत कर सकते हैं और विनाशकारी कुछ भी नहीं कर सकते।

उस चेरी-पिक के हैश पर ध्यान दें जिसे आप पूर्ववत करना चाहते हैं, यह कहें ${bad_cherrypick}। ए करें git revert ${bad_cherrypick}। अब आपके काम करने वाले पेड़ की सामग्री वैसी ही है जैसी वे आपकी खराब चेरी-पिक से पहले थीं।

अपना दोहराएं git cherry-pick ${wanted_commit}, और जब आप नए चेरी-पिक से खुश हों, तो एक करें git rebase -i ${bad_cherrypick}~1। रिबास के दौरान, दोनों ${bad_cherrypick}और इसके संबंधित रिवर्ट को हटा दें ।

जिस शाखा पर आप काम कर रहे हैं, उसमें केवल चेरी-पिक होगी। कोई रीसेट की आवश्यकता है!


6

git reflog आपके बचाव में आ सकता है।

इसे अपने कंसोल में टाइप करें और आपको SHA-1 का प्रतिनिधित्व करने के साथ-साथ आपके गिट इतिहास की एक सूची मिलेगी।

बस किसी भी SHA-1 को चेकआउट करें जिसे आप वापस करना चाहते हैं


उत्तर देने से पहले आइए कुछ पृष्ठभूमि जोड़ते हैं, यह बताते हुए कि यह क्या है HEAD

First of all what is HEAD?

HEADवर्तमान शाखा पर वर्तमान प्रतिबद्ध (नवीनतम) का संदर्भ है। किसी भी समय
केवल एक ही हो सकता है HEAD। (छोड़कर git worktree)

की सामग्री HEADअंदर संग्रहित है .git/HEADऔर इसमें वर्तमान बाइट के 40 बाइट्स SHA-1 हैं।


detached HEAD

यदि आप नवीनतम कमिट पर नहीं हैं - इसका अर्थ है कि HEADइतिहास में एक पूर्व कमिट की ओर इशारा किया जाता है detached HEAD

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

कमांड लाइन पर, यह शाखा के नाम के बजाय SHA-1 की तरह दिखाई देगा क्योंकि HEADवर्तमान शाखा के सिरे की ओर इशारा नहीं करता है

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

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

एक अलग सिर से उबरने के बारे में कुछ विकल्प:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

यह वांछित प्रतिबद्धता की ओर इशारा करते हुए नई शाखा की जाँच करेगा।
यह कमांड किसी दिए गए कमिट को चेकआउट करेगा।
इस बिंदु पर, आप एक शाखा बना सकते हैं और इस बिंदु से काम करना शुरू कर सकते हैं।

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

आप हमेशा के reflogरूप में अच्छी तरह से उपयोग कर सकते हैं ।
git reflogकिसी भी परिवर्तन को प्रदर्शित करेगा जिसने अपडेट किया HEADऔर वांछित रिफ्लग प्रविष्टि की जाँच करके इस कमेटी को HEADवापस सेट कर दिया जाएगा ।

हर बार जब संशोधित किया जाता है तो नई प्रविष्टि होगी reflog

git reflog
git checkout HEAD@{...}

यह आपको आपकी इच्छित कमिट पर वापस मिल जाएगा

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


git reset --hard <commit_id>

"HEAD" को अपने एचआईएडी को मनचाहे कमेट पर वापस ले जाएं।

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.

git revert <sha-1>

दी गई प्रतिबद्ध या प्रतिबद्ध सीमा को "पूर्ववत करें"।
रीसेट कमांड दिए गए कमिट में किए गए किसी भी बदलाव को "पूर्ववत" करेगा।
पूर्ववत पैच के साथ एक नई प्रतिबद्धता होगी, जबकि मूल प्रतिबद्धता इतिहास में भी रहेगी।

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

यह स्कीमा दिखाता है कि कौन सी कमांड क्या करती है।
जैसा कि आप देख सकते हैं वहाँ reset && checkoutसंशोधित करें HEAD

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


शायद जोड़git reset --hard
wyx

3

इसी समस्या का सामना करते हुए, मुझे पता चला कि क्या आपने अपने सफल चेरी-पिक के बाद से प्रतिबद्ध और / या रिमोट से धकेल दिया है, और आप इसे हटाना चाहते हैं, तो आप चेरी-पिक का SHA चलाकर पा सकते हैं:

git log --graph --decorate --oneline

फिर, ( :wqलॉग से बाहर निकलने का उपयोग करने के बाद ) आप चेरी-पिक का उपयोग करके निकाल सकते हैं

git rebase -p --onto YOUR_SHA_HERE^ YOUR_SHA_HERE

जहां YOUR_SHA_HEREचेरी-उठाया कमिटमेंट 40- या संक्षिप्त 7-वर्ण SHA के बराबर है।

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

git push --force origin YOUR_REPO_NAME

(मैंने सेठ रॉबर्टसन से इस समाधान को अनुकूलित किया : देखें "एक पूरी प्रतिबद्धता को हटा दें।"


1

एक आदेश और विनाशकारी आदेश का उपयोग नहीं करता है git reset:

GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostash

यह केवल प्रतिबद्ध करता है, आपको चेरी-पिक से ठीक पहले राज्य में वापस डालता है, भले ही आपके पास स्थानीय परिवर्तन हों।


यह बस प्रतिबद्ध है। आपको क्या लगता git reset HEAD^है?
टिम

@TimCastelijns git resetकिसी भी बदलाव को छोड़ने के बिना प्रतिबद्ध कार्रवाई को रद्द करता है। मैं आपको git-scm.com/docs/git-reset पढ़ने की सलाह देता हूं । ओपी से सवाल चेरी-पिक को पूर्ववत करने का है। दोनों आदेशों का प्रयास करें, मेरा आपको चेरी-पिक से पहले सटीक स्थिति में वापस डाल देगा। git resetआपके काम करने के पेड़ को गड़बड़ कर देगा क्योंकि यह चेरी-पिक के परिवर्तनों को छोड़ देता है और वे आपके पहले से मौजूद स्थानीय परिवर्तनों से अप्रभेद्य बन जाते हैं।
क्वर्टीजगुई

हाँ, क्षमा करें, मेरा मतलब था reset --hard। यह कोई बदलाव नहीं छोड़ता है
टिम

1
@TimCastelijns git reset --hardएक विनाशकारी आदेश है जो असंबंधित स्थानीय परिवर्तनों को भी हटा देगा और ऐसा अपरिवर्तनीय तरीके से करेगा! इसलिए ओपी ने जो मांगा वह नहीं हुआ।
qwertzguy

2
यह उत्तर बहुत अधिक उपयोगी होगा यदि आपने बताया कि वह sedकमांड क्या कर रहा है, यह कैसे मैन्युअल रूप से करने से अलग है, और क्या --autostashकरता है।
क्रिस पेज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.