गिट के साथ एक कमिट का हिस्सा बदलना


144

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

क्या इसके समान कोई दृष्टिकोण है git add --patchजो मुझे यह तय करने के लिए चुनिंदा रूप से संपादित करने की अनुमति देगा कि किसी पुर्ज़े के किन हिस्सों को वापस करना है?


यहां अधिक समाधान , लेकिन आंशिक फ़ाइलों को विशिष्ट फ़ाइलों तक सीमित करने पर ध्यान केंद्रित करना।
ntc2

जवाबों:


226

का प्रयोग करें --no-commit( -n) करने का विकल्प git revertहै, तो परिवर्तन unstage, तो का उपयोग git add --patch:

$ git revert -n $bad_commit    # Revert the commit, but don't commit the changes
$ git reset HEAD .             # Unstage the changes
$ git add --patch .            # Add whatever changes you want
$ git commit                   # Commit those changes

नोट: जिन फ़ाइलों को आप git add --patch का उपयोग करके जोड़ते हैं, वे फाइलें हैं जिन्हें आप वापस करना चाहते हैं, न कि उन फ़ाइलों को जिन्हें आप रखना चाहते हैं।


13
अंतिम आवश्यक आदेश को जोड़ने के लायक हो सकता है, उन लोगों के लिए जो गिट से परिचित नहीं हैं: करने के बाद, git reset --hardउन अन्य परिवर्तनों को त्यागने के लिए जिन्हें आप वापस नहीं करना चाहते थे।
कंपकंपी

15
git reset --hardnewbies के लिए खतरनाक है, क्योंकि यह एडिटिंग को ढीला कर सकता है। इसके बजाय आदत हो git status, यह git checkout -- FILE..चीजों को और अधिक सुरक्षित रूप से वापस लाने के लिए संकेत देता है।
टीनो

क्या एक अंतराल चूक git; git revertबस एक --patchतर्क लेना चाहिए ।
काज

@ काज़: git revertका उपयोग संपूर्ण कमियों को पुनः प्राप्त करने के लिए किया जाता है। आप का उपयोग कर सकते हैं git checkout -pइंटरैक्टिव का चयन करने के लिए बिट्स वापस करने के लिए।
मपदी

1
मैं यह भी (शायद) स्पष्ट जोड़ना चाहूंगा, जो पहले आपके काम को बचाए । या तो commitपहले, या stashफिर प्रयास करें revert
फेलिप अल्वारेज़

39

मैंने निम्नलिखित का सफलतापूर्वक उपयोग किया है।

पहले फुल कमिट वापस करें (इसे इंडेक्स में डालें) लेकिन कमिट न करें।

git revert -n <sha1>  # -n is short for --no-commit

फिर अंतःक्रियात्मक रूप से सूचकांक से उलटे GOOD परिवर्तन को हटा दें

git reset -p          # -p is short for --patch  

फिर बुरे बदलावों का उलटा असर करें

git commit -m "Partially revert <sha1>..."

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

git reset --hard

5
क्या यह स्वीकृत उत्तर (जो उपयोग करता है reset HEAD .) का एक बेहतर विकल्प नहीं है , क्योंकि इसके लिए काम करने वाले डायर के अंतिम सफाई की आवश्यकता नहीं है?
स्टीवन लू

2
यह उत्तर बेहतर है, क्योंकि इसके बाद की reset -pतुलना में कम reset HEADहै add -p। लेकिन इसे अभी भी साफ करने की आवश्यकता है, क्योंकि "अच्छे" हूक जो रीसेट किए गए हैं वे अभी भी कमिटमेंट के बाद वर्किंग डायरेक्टरी में हैं।
चिले दस ब्रिंक

यह उत्तर बेहतर नहीं है क्योंकि आप जो परिवर्तन चाहते हैं , उसे अंतःक्रियात्मक रूप से हटाना अक्सर भ्रमित और त्रुटि-प्रवण होता है --- विशेषकर यदि उनमें से किसी को संपादन की आवश्यकता होती है।
काज

5

व्यक्तिगत रूप से, मैं इस संस्करण को पसंद करता हूं, जो ऑटो-जनरेट किए गए प्रतिबद्ध संदेश का पुन: उपयोग करता है और उपयोगकर्ता को अंतिम रूप देने से पहले "आंशिक रूप से" शब्द को संपादित करने और चिपकाने का अवसर देता है।

# generate a revert commit
# note the hash printed to console on success
git revert --no-edit <hash to revert>

# undo that commit, but not its changes to the working tree
# (reset index to commit-before-last; that is, one graph entry up from HEAD)
git reset HEAD~1

# interactively add reversions
git add -p

# commit with pre-filled message
git commit -c <hash from revert commit, printed to console after first command>

# reset the rest of the current directory's working tree to match git
# this will reapply the excluded parts of the reversion to the working tree
# you may need to change the paths to be checked out
# be careful not to accidentally overwrite unsaved work
git checkout -- .

4

उपाय:

git revert --no-commit <commit hash>
git reset -p        # every time choose 'y' if you want keep the change, otherwise choose 'n'
git commit -m "Revert ..."
git checkout -- .   # Don't forget to use it.

यह लोगों की मदद करेगा यदि आपने कहा कि यह स्वीकृत समाधान से अलग कैसे है
चार्ल्स बीयू

1
@Krzysztof अंत में चेकआउट क्यों महत्वपूर्ण है और यह समाधान user1338062 से अलग क्यों है?
मार्टिन

3

एक अन्य विकल्प (यदि आपकी फ़ाइल का वर्तमान संस्करण उस संस्करण से बहुत दूर नहीं है जिसे आप वापस करने की कोशिश कर रहे हैं) तो आप जिसको आंशिक रूप से वापस करना चाहते हैं ( उससे पहले) कमिट का हैश प्राप्त करना है git log। तब आपकी आज्ञा बन जाती है:

$ git checkout -p <hash_preceding_commit_to_revert> -- file/you/want/to/fix.ext

यह आपके काम करने वाले पेड़ की फाइलों को बदल देता है, लेकिन कोई कमिट नहीं बनाता है, इसलिए यदि आप वास्तव में सामान बनाते हैं तो आप बस फिर से शुरू कर सकते हैं git reset --hard -- file/you/want/to/fix.ext


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