Git में पुरानी (अंतिम नहीं) प्रतिबद्ध में बदली हुई फ़ाइल को कैसे जोड़ा जाए


461

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

लॉग इस तरह दिखता है:

    GIT TidyUpRequests u:1 d:0> git log 
    commit fc6734b6351f6c36a587dba6dbd9d5efa30c09ce 
    Author: David Klein <> 
    Date:   Tue Apr 27 09:43:55 2010 +0200

        The Main program now tests both Webservices at once

    commit 8a2c6014c2b035e37aebd310a6393a1ecb39f463 
    Author: David Klein <>
    Date:   Tue Apr 27 09:43:27 2010 +0200

        ISBNDBQueryHandler now uses the XPath functions from XPath.fs too

    commit 06a504e277fd98d97eed4dad22dfa5933d81451f 
    Author: David Klein <> 
    Date:   Tue Apr 27 09:30:34 2010 +0200

        AmazonQueryHandler now uses the XPath Helper functions defined in XPath.fs

    commit a0865e28be35a3011d0b6091819ec32922dd2dd8 <--- changed file should go here
    Author: David Klein <> 
    Date:   Tue Apr 27 09:29:53 2010 +0200

        Factored out some common XPath Operations

कोई विचार?


जवाबों:


693

का उपयोग करें git rebase। विशेष रूप से:

  1. git stashउन परिवर्तनों को संग्रहीत करने के लिए उपयोग करें जिन्हें आप जोड़ना चाहते हैं।
  2. उपयोग करें git rebase -i HEAD~10(या फिर बहुत से कमिट्स जो आप देखना चाहते हैं)।
  3. लाइन में शुरू में a0865...शब्द pickको बदलकर संपादित करने के लिए प्रश्न ( ) को प्रतिबद्ध करें edit। अन्य पंक्तियों को न हटाएं क्योंकि इससे आवागमन नष्ट हो जाएगा। [^ vimnote]
  4. रिबास फ़ाइल को सहेजें, और गिट शेल पर वापस आ जाएगा और उस कमिट को ठीक करने के लिए आपका इंतजार करेगा।
  5. उपयोग करके स्टैश पॉप करें git stash pop
  6. के साथ अपनी फ़ाइल जोड़ें git add <file>
  7. के साथ कमिट करें git commit --amend --no-edit
  8. ऐसा करो git rebase --continueजो नए के खिलाफ आपके बाकी के कमिट्स को फिर से लिखेगा।
  9. यदि आपने संपादन के लिए एक से अधिक प्रतिबद्ध चिह्नित किए हैं, तो चरण 2 से आगे दोहराएं।

[^ vimnote]: यदि आप उपयोग कर रहे हैं, vimतो आपको Insertसंपादित करने के लिए कुंजी को हिट करना होगा , फिर फ़ाइल को बचाने, संपादक को छोड़ने और परिवर्तनों को लागू करने के लिए Escटाइप :wqकरना होगा। वैकल्पिक रूप से, आप कर सकते हैं कॉन्फ़िगर एक उपयोगकर्ता के अनुकूल Git संपादक प्रतिबद्ध के साथ git config --global core.editor "nano"


23
क्या होगा यदि आपके पास अस्थिर परिवर्तन हैं जो आप संपादन में जोड़ना चाहते हैं? अगर मैं उन्हें रोक देता हूं, तो मैं नहीं कर सकता git add
सैम

15
सैम आप केवल बदलावों पर अमल कर सकते हैं जबकि सवाल में यह ठीक है।
ओमनिकॉन सेप

17
नोट: जब आप कमिट को मार्क करते हैं edit, तो फाइल में सूचीबद्ध अन्य कमेंट्स को डिलीट न करें। यदि आप करते हैं, तो आवागमन हटा दिए जाएंगे और आपको उन्हें वापस लाने के लिए इन चरणों का पालन करना होगा।
डेविड टयूइट

2
@DavidTuite ने क्या कहा, इस बारे में कि मेरी एक आदत है कि जब मैं यह नहीं कर पाऊंगा कि मैं टाइमलाइन की वर्तमान स्थिति को बचाने के लिए "ब्रांचेनाम-रेफ" शाखा कैसे बना रहा हूं, तो मुझे यकीन नहीं है कि git पर सामान करते समय मेरी एक आदत है। जब मैं पूरा हो जाता हूं, मैं इसे हटा देता हूं।
राफेल

1
चरण 6 में, शामिल करें। (डॉट) कमांड में। सही कमांड:git add .
टॉम

323

एक छोटे से बदलाव के साथ एक पुरानी प्रतिबद्ध को "ठीक" करने के लिए, पुरानी प्रतिबद्ध के प्रतिबद्ध संदेश को बदलने के बिना, जहां OLDCOMMITकुछ ऐसा है 091b73a:

git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

आप git commit --squash=OLDCOMMITरिबास के दौरान पुराने प्रतिबद्ध संदेश को संपादित करने के लिए भी उपयोग कर सकते हैं ।


  • git rebase --interactiveएक पाठ संपादक (जो कॉन्फ़िगर किया जा सकता है ) को रिबेस निर्देश अनुक्रम की पुष्टि करने (या संपादित करने) के लिए लाएगा । फ़ाइल में पुन: निर्देश अनुदेश परिवर्तन के लिए जानकारी है ; बस बचाने के लिए और बाहर निकलने के संपादक ( :wqमेंvim ) रिबेस के साथ जारी रखने के लिए।
  • --autosquash--fixup=OLDCOMMITवांछित क्रम में स्वचालित रूप से कोई भी कमिट लगाएगा । ध्यान दें कि --autosquashजब --interactiveविकल्प का उपयोग किया जाता है तो केवल मान्य होता है।
  • ^में OLDCOMMIT^साधन यह एक संदर्भ है बस से पहले प्रतिबद्ध करने के लिए OLDCOMMIT

उपरोक्त चरण रिबेज़ निर्देश अनुक्रम के सत्यापन और / या संशोधन के लिए अच्छे हैं , लेकिन इसके द्वारा इंटरएक्टिव रिबेस टेक्स्ट एडिटर को छोड़ना / स्वचालित करना भी संभव है:

Git कमिट और git रिबास देखें । हमेशा की तरह, जब इतिहास को फिर से लिखना है , तो आपको केवल फ़िक्सअप या स्क्वैश करना चाहिए जो आपने अभी तक किसी और को प्रकाशित नहीं किया है (यादृच्छिक इंटरनेट उपयोगकर्ताओं और बिल्ड सर्वर सहित)।


18
अन्य विकल्पों की तुलना में बहुत स्पष्ट है, और यह एक आकर्षण की तरह काम करता है
क्रिस मिचेलमोर

5
@ जोनाह: संपादक को प्रतिबद्ध संदेश को संपादित करने के लिए नहीं खोला गया है , लेकिन रिबेस चरणों की पुष्टि करने (या संपादित करने) के लिए । इसे टाला नहीं जा सकता; --autosquashकेवल तभी मान्य होता है जब --interactiveविकल्प का उपयोग किया जाता है
जोएल पुर्रा

5
इस समाधान का उपयोग कर मैं VIM दिखा रहा हूँ। मेरी समस्या यह है, मुझे नहीं पता कि वीआईएम का उपयोग कैसे करें। मैं इससे कैसे बाहर निकलता हूं, मैं इस बात को कैसे नियंत्रित कर सकता हूं, यह इतना भ्रामक है।
नियॉन वारगे

2
@NeonWarge: पसंद का संपादक उदाहरण के लिए उपयोग करने योग्य है git config --global core.editor "pico"। कर रहे हैं कॉन्फ़िगर Git और / या करने के लिए कई अन्य तरीकों से अपने सिस्टम डिफ़ॉल्ट संपादक बदलने आदि।
जोएल पुर्रा

2
एक पंक्ति अच्छा उर्फ यहाँ
idanp

61

जीआईटी 1.7 के साथ, उपयोग करने का एक बहुत आसान तरीका है git rebase:

अपनी फ़ाइलों को चरणबद्ध करें:

git add $files

अपनी "टूटी हुई" प्रतिबद्धता का एक नया प्रतिबद्ध और फिर से उपयोग संदेश बनाएँ

git commit -c master~4

आगे जोड़ते fixup!विषय पंक्ति में (या squash!अगर आप संपादित करना चाहते हैं संदेश प्रतिबद्ध ()):

fixup! Factored out some common XPath Operations

git rebase -i --autosquashअपनी प्रतिबद्धता को ठीक करने के लिए उपयोग करें


2
+1। नए फ़ेकअप निर्देश (1.7+) का अच्छा उपयोग: stackoverflow.com/questions/2302736/trimming-git-checkins/…
VONC

@knittl मैं अपनी एक पुरानी कमेटी (धक्का नहीं दिया) के लिए एक और फाइल जोड़ने के लिए आपके तरीके की कोशिश कर रहा था, लेकिन जब मुझे रिबासिंग मिलती है You asked me to rebase without telling me which branch you want to rebase against, and 'branch.master.merge'और अगर मैं तब उपयोग करता git rebase -i --autosquashहूं तो मुझे एक noopसब्जेक्ट लाइन मिलती है , खुद पर कमिटिंग करते हुए। किसी भी विचार मैं गलत क्या करते हैं?
ऑस्क्रेन्क

7
@oschrenk: आपको एक प्रतिबद्ध प्रदान करने की आवश्यकता है, जिसके लिए आप git rebase -i --autosquash HEAD~10
रिबास

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

@PaOOdeon: मैं आपके प्रश्न को नहीं समझता। आप क्या करने की कोशिश कर रहे हैं, और आपको कहाँ समस्या हो रही है?
knittl

8

आप rebase --interactiveअपनी पुरानी प्रतिबद्धताओं को संशोधित करने के लिए एक सत्र की कोशिश कर सकते हैं (बशर्ते आप पहले से ही उन अन्य रिटो को आगे नहीं बढ़ाते)।

कभी-कभी b.2 में तय की गई चीज। यह काफी हद तक सही नहीं है, क्योंकि यह प्रतिबद्ध है एक पैच श्रृंखला में गहराई से दफन है संशोधन नहीं किया जा सकता है ।
यही कारण है कि इंटरएक्टिव रिबास के लिए है: "ए" और "बी" के बहुत सारे के बाद इसका उपयोग करें, कमानों को पुन: व्यवस्थित और संपादित करके, और एक में कई कमेंट्स स्क्वैशिंग करें।

इसे अंतिम प्रतिबद्धता के साथ शुरू करें जिसे आप बनाए रखना चाहते हैं:

git rebase -i <after-this-commit>

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

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

ऑनेलाइन विवरण शुद्ध रूप से आपकी खुशी के लिए हैं; git rebase उन्हें नहीं बल्कि कमिटेड नामों ("डेडबी" और "fa1afe1" इस उदाहरण में) पर दिखेगा, इसलिए नामों को हटाएं या संपादित न करें।

कमांड "पिक" को कमांड "एडिट" के साथ बदलकर, आप उस रीति को लागू करने के बाद रोकने के लिए गिट रिबेस को बता सकते हैं, ताकि आप फाइलों को संपादित कर सकें और / या कमिट मैसेज को एडिट कर सकें, कमिट कर सकें और रिबासिंग जारी रख सकें

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