2012-01-11 15 views
113

मैंने 3 गिट काम किया है, लेकिन धक्का नहीं दिया गया है। मैं पुराने (डीडीसी 685 9एफ 44) और (47175e84c) में कैसे संशोधन कर सकता हूं जो सबसे हालिया नहीं है?पुरानी गिट प्रतिबद्धता में संशोधन कैसे करें?

$git log 
commit f4074f289b8a49250b15a4f25ca4b46017454781 
Date: Tue Jan 10 10:57:27 2012 -0800 

commit ddc6859af448b8fd2e86dd0437c47b6014380a7f 
Date: Mon Jan 9 16:29:30 2012 -0800 

commit 47175e84c2cb7e47520f7dde824718eae3624550 
Date: Mon Jan 9 13:13:22 2012 -0800 
+3

कृपया स्पष्ट करें कि क्या आप उन 2 प्रतिबद्धताओं को 1 प्रतिबद्धता में जोड़ना चाहते हैं या यदि आप प्रत्येक को और परिवर्तनों में संशोधन करना चाहते हैं। –

+2

मैंने इस सटीक उद्देश्य के लिए एक बैश स्क्रिप्ट बनाई है: github.com/colinodell/git-amend-old एक बार इंस्टॉल हो जाने पर, आप इसका उपयोग इस तरह करेंगे: 'git amend-old abcd123', जहां 'abcd123' पुराना है प्रतिबद्ध है कि आप अपने चरणबद्ध परिवर्तनों में संशोधन करना चाहते हैं। उम्मीद है कि किसी को यह उपयोगी लगेगा! –

+0

@ कॉलिनो 'अपनी स्क्रिप्ट चट्टानों को डेल करें! धन्यवाद। – MikeSchinkel

उत्तर

9

आप प्रतिबद्ध इतिहास को फिर से लिखने के लिए git rebase का उपयोग कर सकते हैं। यह आपके परिवर्तनों के लिए संभावित रूप से विनाशकारी हो सकता है, इसलिए देखभाल के साथ उपयोग करें।

पहले सामान्य प्रतिबद्धता के रूप में अपना "संशोधन" परिवर्तन करें। फिर अपने सबसे पुराने प्रतिबद्धता

git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^ 

यह आपके संपादक को सभी कामों के साथ आग लग जाएगा। उन्हें पुन: व्यवस्थित करें ताकि आपकी "संशोधन" प्रतिबद्धता उस व्यक्ति के नीचे आती है जिसे आप संशोधित करना चाहते हैं। फिर s के साथ "संशोधन" प्रतिबद्धता के साथ लाइन पर पहले शब्द को प्रतिस्थापित करें जो पहले (s क्वाश) को जोड़ देगा। सहेजें और अपने संपादक से बाहर निकलें और निर्देशों का पालन करें।

+3

वह स्क्वैश या फिर से काम नहीं करना चाहता है। –

+3

@AdamDymitruk: वह कहां कहता है? बीटीडब्ल्यू, आपका उत्तर इतिहास को फिर से लिखने का भी सुझाव देता है। –

+0

वह सिर्फ संशोधन करना चाहता है। स्क्वैशिंग का कोई उल्लेख एक साथ काम करता है या उन्हें फिर से व्यवस्थित करता है। –

9

आप का उपयोग कर उस प्रतिबद्धता पर edit कमांड का उपयोग कर सकते हैं, जिसे आप संशोधित करना चाहते हैं।

146
git rebase -i HEAD^^^ 

अब जिन्हें आप edit या e (pick की जगह) के साथ संशोधन करने के लिए चाहते हैं निशान। अब बचाओ और बाहर निकलें। आप एक अतिरिक्त जोड़ने के लिए हटा प्रतिबद्ध आदेश से विकल्प निकाल दें

अब अपने परिवर्तन, तो

git add -A 
git commit --amend --no-edit 
git rebase --continue 

बनाते हैं। अगर आप संदेश को समायोजित करना चाहते हैं, तो बस --no-edit विकल्प छोड़ दें।

+2

रीबेज के दौरान पुराने प्रतिबद्धता में परिवर्तनों को आसानी से लागू करने के लिए 'गिट स्टेश' या 'गिट स्टैश [-पी | --पैच] '(इंटरैक्टिव) का उपयोग करना सुविधाजनक हो सकता है। – here

+4

नोट - आपको गिट एड-ए के बाद प्रतिबद्धता को गठबंधन करने की आवश्यकता नहीं है, बस गिट रीबेस --continue आपके परिवर्तनों को बनाए रखेगा। – manyways

+0

'कोई मिलान नहीं मिला: HEAD ^^^ ' – kleinfreund

2

मामले में ओपी छुटकारा पाने के लिए 2 1 में निर्दिष्ट करता है चाहता है, यहाँ रिबेसिंग

git checkout HEAD^    # go to the first commit you want squashed 
git reset --soft HEAD^   # go to the second one but keep the tree and index the same 
git commit --amend -C [email protected]{1} # use the message from first commit (omit this to change) 
git checkout [email protected]{3} -- .  # get the tree from the commit you did not want to touch 
git add -A      # add everything 
git commit -C [email protected]{3}   # commit again using the message from that commit 

@{N) वाक्य रचना के बिना यह करने के लिए एक वैकल्पिक तरीका है पता करने के लिए आसान है, क्योंकि यह आप संदर्भ के लिए अनुमति देगा आपका संदर्भ कहां से इतिहास था। इस मामले में यह हेड है जो आपके वर्तमान प्रतिबद्धता का प्रतिनिधित्व करता है।

78

मैंने अपनी प्रतिबद्धता तैयार की कि मैं एक पुराने व्यक्ति के साथ संशोधन करना चाहता हूं और यह देखकर आश्चर्यचकित हुआ कि रिबेस-मैंने शिकायत की है कि मेरे पास असामान्य परिवर्तन हैं। लेकिन मैं अपने बदलावों को फिर से पुराने प्रतिबद्धता के संपादन विकल्प को निर्दिष्ट नहीं करना चाहता था। तो समाधान बहुत आसान और सरल था:

  1. अपने अद्यतन तैयार करने के लिए पुराने प्रतिबद्ध है, यह जोड़ सकते हैं और प्रतिबद्ध
  2. git rebase -i <commit you want to amend>^ - नोटिस ^ तो आप ने कहा कि देखते हैं पाठ संपादक में प्रतिबद्ध
  3. आप करेंगे इस तरह sometihng मिलती है:

    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync 
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies 
    pick e23d23a fix indentation of jgroups.xml 
    
  4. अब

    8c83e24 आप लाइन क्रम बदल सकते हैं और इस तरह स्क्वैश उपयोग कर सकते हैं के साथ गठबंधन करने के लिए e23d23a:

    +०१२३५१६४१०
    pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync  
    squash e23d23a fix indentation of jgroups.xml 
    pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies 
    
  5. फ़ाइल लिखें और बाहर निकलें, आप प्रतिबद्ध संदेशों को मर्ज करने के लिए एक संपादक के साथ उपस्थित होंगे।ऐसा करने के लिए और बचाने के लिए/पाठ दस्तावेज़

  6. आप से किया जाता है बाहर निकलते हैं, अपने प्रतिबद्ध
  7. में संशोधन कर रहे हैं

क्रेडिट जाता है: http://git-scm.com/book/en/Git-Tools-Rewriting-History वहाँ भी अन्य उपयोगी प्रदर्शन किया Git जादू है।

+6

मुझे एहसास नहीं हुआ कि मैं रीबेस फ़ाइल में लाइनों को पुन: व्यवस्थित कर सकता हूं। महान टिप! मेरे लिए – Dan

+1

यह समझना आसान है। और बस महान काम करता है – BritishDeveloper

8

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

मैं निम्नलिखित तरीके से करता पर गौर करेंगे, तो यह आसानी से पढ़ने योग्य है:

C# good commit after a bad one 
B # bad commit 
A # good commit before a bad one 

शुरुआत में आपका इतिहास इस तरह दिखता है:

x - A - B - C 
|   | 
|   master 
| 
origin/master 

हम करने के लिए इसे पुन: करेंगे इस तरह से:

x - A - B*- C' 
|   | 
|   master 
| 
origin/master 

यह प्रक्रिया है:

git checkout B  # get working-tree to the state of commit B 
git reset --soft A # tell git that we are working before commit B 
git checkout -b rewrite-history # switch to a new branch for our alternative history 

git add (git add -i, git stash इत्यादि) का उपयोग करके अपनी पुरानी प्रतिबद्धता में सुधार करें। आप अपनी पुरानी प्रतिबद्धता को दो या दो से भी विभाजित कर सकते हैं।

git commit   # recreate commit B (result = B*) 
git cherry-pick C # copy C to our new branch (result = C') 

मध्यवर्ती परिणाम:

x - A - B - C 
| \  | 
|  \  master 
|  \ 
|  B*- C' 
|   | 
|   rewrite-history 
| 
origin/master 

आइए खत्म:

git checkout master 
git reset --hard rewrite-history # make this branch master 

यह है कि, अब आप अपनी प्रगति push कर सकते हैं।

संबंधित मुद्दे