git चयनात्मक एक फ़ाइल से स्थानीय परिवर्तनों को वापस लाएं


149

मेरे git रेपो में जो svn repo पर नज़र रख रहा है, मैंने एक फ़ाइल में कई संपादन किए हैं।

अब मैं उन परिवर्तनों (जैसे svn revert) को वापस करना चाहता हूं, लेकिन केवल फ़ाइल के कुछ हिस्से।

मैं फ़ाइल में मौजूद अंतरों को देखने में सक्षम होना चाहता हूं, उन परिवर्तनों को त्याग (रिवर्ट) करूं जो मैं नहीं चाहता और जो बदलाव चाहते हैं, उन्हें बरकरार रख सकता हूं।

git add -i 

कमांड के पास ऐसा करने का विकल्प प्रतीत होता है, लेकिन मैं अभी तक इसे चरणबद्ध नहीं करना चाहता।

जवाबों:


91

आप के साथ सीधे कर सकते हैं git checkout -p। देखें डैनियल Stutzbach का जवाब नीचे।


पुराना उत्तर (पहले checkout -pपेश किया गया था):

आप इसे इस तरह से कर सकते हैं:

git add -i

(आप जो हिक्स रखना चाहते हैं उसे चुनें)

git commit -m "tmp"

अब आपके पास केवल उन परिवर्तनों के साथ एक प्रतिबद्धता है जिन्हें आप रखना चाहते हैं, और बाकी सभी अस्थिर हैं।

git reset --hard HEAD

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

git reset --mixed HEAD^

यह अंतिम कमिट ('tmp') को हटा देता है, लेकिन आपके वर्किंग डायरेक्टरी में संशोधनों को अनस्टैजड रखता है।

EDIT: मचान क्षेत्र को साफ करने के --softसाथ प्रतिस्थापित किया --mixedगया।


यह उन परिवर्तनों को करेगा जो मैं रखना चाहता हूं, क्या यह नहीं है? मैं उन परिवर्तनों को अभी तक नहीं करना चाहता। मिमी शायद मैं बहुत गंभीरता से कमिट ले रहा हूं। शायद मुझे अब आराम करना चाहिए क्योंकि यह सभी स्थानीय रेपो में है। btw क्या git रिसेट --soft HEAD ^ करता है?
प्रदीप

"git रीसेट --soft HEAD ^" इस अर्थ में एक कमिट को अनडू करता है कि यह वर्क डायरेक्टरी और इंडेक्स को रखता है जैसे यह था, और करंट ब्रांच को एक कमिट में वापस ला देता है।
याकूब नारबस्की

धन्यवाद जैकब। पाओलो सिर के लिए एक नरम रीसेट क्यों होगा - 1 यहां आवश्यक होगा? आंशिक प्रतिबद्धता और हार्ड रीसेट पर्याप्त होना चाहिए कि यह कुछ बदलाव न रखे और दूसरों को न छोड़े?
प्रदीप

1
नीचे डैनियल का जवाब बहुत सरल है और ऐसा करने का सही तरीका दिखता है।
उमंग

309

मेरा मानना ​​है कि आप इसे सबसे सरल तरीके से कर सकते हैं:

git checkout -p <optional filename(s)>

मैनपेज से:

   −p, −−patch
       Interactively select hunks in the difference between the <tree−ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree−ish> was specified, the index).
       This means that you can use git checkout −p to selectively discard
       edits from your current working tree.

1
इसके अलावा, यदि आप यह चयन करने की इच्छा नहीं रखते हैं, तो आप परिवर्तनों को छोड़ने के लिए "गिट चेकआउट - <फ़ाइल> ..." का उपयोग कर सकते हैं।
db42

क्या यह निर्देशिकाओं से निपटता है?
bbum

1
परिवर्तनों को त्यागते समय यह मेरे लिए बहुत विफल प्रतीत होता है ("त्रुटि: पैच विफल <फ़ाइल>", "त्रुटि: <फ़ाइल> पैच लागू नहीं होता है")। पूरी तरह से पर्याप्त रूप से मैं उन त्रुटियों को प्राप्त करूंगा जब aएक संपूर्ण फ़ाइल को छोड़ने के लिए पैच मोड में विकल्प का उपयोग किया जाता है, फिर भी git checkout -- <file>अपेक्षा के अनुरूप काम करता है। किसी को पता है क्यों?
चर्नोला

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

3

आप चला सकते हैं git diffफ़ाइल पर, बचाने जिसके परिणामस्वरूप diff, संपादित यह परिवर्तन आप निकालना है , सहेजना चाहते तो इसे चलाने के माध्यम से patch -Rशेष डिफ पूर्ववत करने के लिए।

git diff file.txt> patch.tmp
# जिस पैच को आप रखना चाहते हैं, उसे निकालने के लिए patch.tmp को एडिट करें
पैच -R <Patch.tmp

मैं अपने पैच फ़ाइल में 2 हंक था और एक को हटा दिया। निश्चित नहीं है कि क्या कारण है, लेकिन पैच -R इसके साथ अस्वीकृत होता रहता है।
प्रदीप

2
आप एक अन्य टिप्पणी में उल्लेख git diffकरते हैं जो पूरी फाइल को बदल के दिखाती है। यह आमतौर पर तब होता है जब आपने फ़ाइल को अलग पंक्ति के अंत का उपयोग करके बचाया है जो पहले था। यह patchपैच फ़ाइल को अस्वीकार करने का कारण भी होगा । क्या उस तरह की आवाज़ आती है जो हो सकता है?
ग्रेग हेवगिल

तुम सही हो। जब भी मैं पैच कमांड का उपयोग करता हूं तो लाइन एंडिंग को टॉगल किया जाता है। मैं खिड़कियों पर हूं और क्रीम / विम का उपयोग कर रहा हूं। मुझे लगता है कि पहले इसे सुलझाने की जरूरत है।
प्रदीप

मैं विंडोज़ पर पैच के साथ समस्या को हल करने में असमर्थ था। हालांकि मुझे यकीन है कि यह काम मैं पाओलो के नुस्खा का उपयोग करना पसंद करता हूं। Git ऐड -i का उपयोग करके डिफरेंशियल के साथ काम करने के लिए उन इंटरैक्टिव कमांड्स के प्यार के लिए।
प्रदीप

3

जैसा चाहो वैसा दिखता है

 git revert --no-commit $REVSISON 

तब आप उपयोग कर सकते हैं

 git diff --cached

यह देखने के लिए कि आने से पहले क्या परिवर्तन किया जाएगा (जैसा कि पलटाव सिर्फ एक पूर्व दिशा में प्रतिबद्ध है जो अतीत में बदलाव का उलटा संकेत करता है)

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


जैसा कि आपने पिछले संशोधन (क्या यह सही है?) का उल्लेख किया था और अब git diff ने पूरी फ़ाइल को बदले हुए रूप में दिखाया। यह मेरे द्वारा किए गए संपादन दिखाने के लिए है?
प्रदीप

1

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

यदि परिवर्तन केवल आपकी कार्य प्रतिलिपि में हैं, तो ऐसा करने का सबसे आसान तरीका उन परिवर्तनों को चरणबद्ध करना है जिन्हें आप रखना चाहते हैं:

git add -i <file>

फिर उन परिवर्तनों को फेंक दें जिन्हें आप अनुक्रमणिका संस्करण की जाँच करके नहीं रखना चाहते हैं:

git checkout -- <file>

यदि आप उन्हें अभी तक मंचित नहीं करना चाहते हैं, तो तब परिवर्तन को रोकें:

git reset -- <file>

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

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

git reset <commit_before_first_unwanted_change> -- <file>

फिर आप git add -i <file>उन बदलावों को मंचित करने के लिए, जिन्हें आप रखना चाहते हैं, git checkout -- <file>अवांछित परिवर्तनों को दूर करने और परिवर्तनों git reset -- <file>को 'अस्थिर' करने के लिए पिछले नुस्खा का पालन कर सकते हैं।


0

यहां दिए गए उत्तरों में वर्णित कमांड लाइन विकल्प तब काम में आते हैं जब फ़ाइल एक सर्वर पर होती है जिसे मैं ssh टर्मिनल के माध्यम से एक्सेस कर रहा हूं। हालाँकि, जब फ़ाइल मेरे स्थानीय मशीन पर होती है तो मैं निम्नलिखित तरीके से पसंद करता हूँ:

फ़ाइल को नेटबीन्स एडिटर में खोलें (जो गिट सपोर्ट के साथ आता है)। नेटबिन यह दर्शाने के लिए लाइन नंबरों पर लाल / हरे / नीले निशान लगाता है कि जहाँ सामान नष्ट / जोड़ा / संशोधित (क्रमशः) किया गया था।

इनमें से किसी भी निशान पर राइट क्लिक करने से आपको उस परिवर्तन को पूर्ववत करने का विकल्प मिलता है। इसके अलावा, आप पॉपअप में पुराने संस्करण को देखने के लिए लाल और नीले निशान पर राइट क्लिक कर सकते हैं।

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