क्या मैं जीआईटी में आंशिक सुधार कर सकता हूं


156

क्या बहु फ़ाइल कमिट में केवल एक फ़ाइल या किसी फ़ाइल में कुछ बदलावों को वापस करना संभव है?

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


ब्रायन मुझे सही रास्ते पर मिला। मैंने git add --patch का उपयोग करके समाप्त किया, फिर पैच के भीतर एडिट फ़ंक्शन का उपयोग करके जो मुझे चाहिए था।
क्लच

2
मुझे खेल में काफी देर हो गई है, लेकिन मुझे लगता है कि मुझे "सही" जवाब मिला
ntc2

@ ntc2 विचित्र रूप से, स्वीकृत उत्तर मेरे लिए आपके द्वारा लिंक किए गए से बेहतर काम करता है - इसने मेरे लिए मर्ज संघर्षों को हल करने के लिए बनाया, बजाय पैच लागू करने में विफल।
इरिडन

@liridayn क्या आपने मेरा पूरा जवाब पढ़ा? "विविधताओं" खंड में मेरा दावा है कि --3wayपैच लगाने में विफलता के बजाय मर्ज संघर्ष में परिणाम जोड़ते हैं।
ntc2

जवाबों:


204

आप '--no-प्रतिबद्ध' विकल्प को जोड़कर एक नया बनाने के बिना प्रतिबद्ध वापस कर सकते हैं। यह स्टेजिंग क्षेत्र में सभी रिवर्ट की गई फाइलों को छोड़ देता है। वहां से, मैं एक नरम रीसेट करता हूं और उन परिवर्तनों में जोड़ता हूं जो मैं वास्तव में चाहता था। एक उदाहरण वर्कफ़्लो के लिए:

git revert <sha-of-bad-commit> --no-commit
git reset   // This gets them out of the staging area
<edit bad file to look like it should, if necessary>
git add <bad-file>
git checkout . // This wipes all the undesired reverts still hanging around in the working copy
git commit

42
नरम रीसेट के बाद, आप git add -pएक इंटरैक्टिव सत्र शुरू करने के लिए भी कर सकते हैं जो आपको संपूर्ण फ़ाइलों के बजाय चुनिंदा फ़ाइलों को जोड़ने की अनुमति देता है। ( git reset -pचुनिंदा अस्थिर परिवर्तनों के लिए भी है। यह जानने के लिए अच्छा है, लेकिन शायद आप इस परिदृश्य में क्या नहीं चाहते हैं।)
स्टीफन कोचन

1
यह वही था जो मैं देख रहा था: काम की प्रतिलिपि में वापस लौटें, अंतःक्रियात्मक रूप से लोभी चुनें, कमिट करें। आप इसके लिए एक बड़े, नमकीन मानव-
स्मूदी के पात्र हैं

एक अन्य समाधान इस एक से प्रेरित किया जाएगा करने के लिए revert, reset, stash -p, (गुप्त कोष "रद्द है कि मैं वास्तव में बनाने के लिए नहीं करना चाहते हैं") addबाकी है,commit
सिरिल CHAPON

82

आप checkoutकमांड का उपयोग करके किसी फ़ाइल के पुराने संस्करण को अंतःक्रियात्मक रूप से लागू कर सकते हैं ।

उदाहरण के लिए, यदि आप जानते हैं कि COMMITवापस जोड़ने का कोड कहाँ हटा दिया गया था, तो आप निम्नलिखित कमांड चला सकते हैं:

git checkout -p COMMIT^ -- FILE_TO_REVERT

Git आपको फ़ाइल के वर्तमान संस्करण से अनुपलब्ध हक्स को वापस जोड़ने के लिए संकेत देगा। आप eइसे वापस लागू करने से पहले परिवर्तन का एक पैच बनाने के लिए उपयोग कर सकते हैं ।


बहुत उपयोगी है अगर आप केवल फ़ाइल का हिस्सा वापस करना चाहते हैं! मूल रूप से, सिर से git checkout -p path/to/file
चूजे

40

आप केवल उन फ़ाइलों की पुरानी, ​​अच्छी सामग्री को मैन्युअल रूप से देख सकते हैं जिनका आप उपयोग करना चाहते हैं git checkout। उदाहरण के लिए, यदि आप my-important-fileउस संस्करण में वापस लौटना चाहते हैं जो संस्करण में था abc123, तो आप कर सकते हैं

git checkout abc123 -- my-important-file

अब आपके पास पुरानी सामग्री my-important-fileवापस आ गई है, और यदि आप चाहें तो उन्हें संपादित भी कर सकते हैं, और हमेशा की तरह एक प्रतिबद्ध बनाने के लिए प्रतिबद्ध हैं जो उन्होंने किए गए परिवर्तनों को वापस कर देगा। यदि उसकी प्रतिबद्धता के कुछ हिस्से हैं जो आप वापस करना चाहते हैं, तो git add -pउस पैच से केवल कुछ हंक का चयन करने के लिए उपयोग करें जो आप कर रहे हैं।


19
यह एक नहीं है revert, आप फ़ाइल का पुराना संस्करण वापस ले रहे हैं। एक उचित revertबुरा निकाल देंगे फ़ाइल के भीतर संशोधनों के लिए प्रतिबद्ध है, भले ही यह कई बार संशोधित किया गया है के बाद से है कि बुरा प्रतिबद्ध है, और आप ढीला नहीं करना चाहती उन संशोधनों।
टोटर

2
टोटर, मेरा जवाब देखिए। आप संशोधनों को सहेजने के लिए '-p' का उपयोग कर सकते हैं। जवाब वास्तव में इस एक के बहुत करीब है।
सेमीकिन्टी

1
या आप इसमें संयोजन कर सकते हैं git checkout -p
लीओ लैम

31

मुझे Git मेलिंग सूची में ऐसा करने का एक तरीका मिला:

git show <commit> -- <path> | git apply --reverse

स्रोत: http://git.661346.n2.nabble.com/Revert-a-single-commit-in-a-single-file-td6064050.html#a6064406

बदलाव

यदि पैच साफ़ तरीके से लागू नहीं होता है, तो यह कमांड विफल रहता है (कोई परिवर्तन नहीं होता है), लेकिन --3wayइसके साथ ही आपको संघर्ष का सामना करना पड़ता है जिसे आप तब स्वयं हल कर सकते हैं (इस मामले में केसी का जवाब अधिक व्यावहारिक हो सकता है):

git show <commit> -- <path> | git apply --reverse --3way

आप इसका उपयोग कई कमिट्स को आंशिक रूप से वापस करने के लिए भी कर सकते हैं, जैसे:

git log -S<string> --patch | git apply --reverse

<string>किसी भी कमिट में मेल खाने वाले बदलाव के साथ फाइल को वापस करना । यह वही है जो मुझे अपने उपयोग के मामले में चाहिए था (कुछ अलग-अलग कमिट्स ने अलग-अलग फ़ाइलों में समान बदलाव पेश किए, साथ ही असंबंधित तरीके से अन्य फ़ाइलों में परिवर्तन किए गए जो मैं वापस नहीं करना चाहता था)।

आप है diff.noprefix=trueअपने में सेट ~/.gitconfigतो आप जोड़ने की जरूरत -p0करने के लिए git applyआदेश, जैसे

git show <commit> -- <path> | git apply -p0 --reverse

यह उत्तर स्वीकृत एक की तुलना में बहुत बेहतर है: "बेहतर अभी तक, उस फ़ाइल में दो परिवर्तनों को वापस जाएं और वापस जाएं"।
फिर से लिखा

मैं कमिट के केवल एक भाग को वापस करना चाहता था, इसलिए मैंने जो (1) git show ... > foo.txt (2) संपादित foo.txtकरने के लिए अलग-अलग तरीकों को हटाने के लिए संपादित किया, जो मैं नहीं चाहता था (3) फिर git apply --reverse foo.txt से सूचीबद्ध किए गए डिफॉर्म्स को वापस करने के लिए foo.txt
cxw

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