2014-06-12 8 views
7

में शून्य sha1 के साथ एक प्रविष्टि को कैसे निकालें I पेड़ में एक प्रतिबद्ध प्रविष्टि के लिए एक शून्य शॉ 1 के साथ एक गिट भंडार विरासत में मिला है, जिससे फिशई को भंडार सूचकांक को रोक दिया गया है।गिट पेड़

$ git fsck 
Checking object directoriies: 100%(256/256), done. 
warning in tree db22a67df70dc4ff90ec4cd666da91e9c2cb0d9: 
    contains entries pointing to null sha1 
Checking objects: 100% (416532/416532), done. 
Checking connectivity: 416532, done. 

दिया पेड़ के लिए खोज रहे मेरा पीछा परिणाम दे:

$ git ls-tree db22a6 
100644 blob e615f18b55a39f2719112ce209c2505dd92d8e75 .gitignore 
100644 blob ac852f06c5a04420356c1d5efca44d9a864e78b0 .project 
160000 commit 0000000000000000000000000000000000000000 SomeDirectory 
100644 blob 631c17e28026261a2ccf6bc570842cf4af9f181c GoDeploy.bat 
100644 blob 40e992ab5c3868af2910135c3ac4610c3646e7f8 pom.xml 

इतिहास में देखते हुए, मैंने पाया है कि SomeDirectory शुरू में एक Git submodule था और प्रतिबद्ध है कि उस का कारण बन रहा है मुद्दा वह है जिसने .gitmodules और SomeDirectory दोनों को हटा दिया है। अब, एक वास्तविक निर्देशिका है जिसे SomeDirectory कहा जाता है जहां अपराधी था।
मैं हालांकि मैं अभी भी एक git filter-branch चलाने को देखने के लिए मैं क्या हो जाएंगे ठीक करने की कोशिश कर सकता है, लेकिन यह काम नहीं करता है: क्या मैं अगले कोशिश करना चाहिए, यह जानकर कोई बैकअप है कि वहाँ

$ git filter-branch --force --index-filter \ 
$ 'git rm --cached --ignore-unmatch SomeDirectory' \ 
$ --prune-empty --tag-name-filter cat -- --all 
[... striped out for clarity] 
Rewrite c571a3ec94e9f84471577bac41ac7375c729ef08 (76/18522)error: 
    cache enttry has null sha1: SomeDirectory 
fatal: unable to write new index file 
Could not initialize the index 
[... striped out for clarity] 

कि मैं इस मुद्दे के कारण प्रतिबद्धता से पहले मुझे पता है।

उत्तर

13

संदेश आपको मिल पता चलता है केवल एक बुरा submodule के साथ एक एकल पेड़ नहीं है। उस स्थिति में, आपको साफ करना बहुत कम है। आप एक नया तय पेड़ है कि इस समस्या नहीं है बना सकते हैं:

 
$ git ls-tree db22a67df70dc4ff90ec4cd666da91e9c2cb0d9 | 
> sed -e '/0\{40\}/d' | 
> git mktree 
(new tree SHA1 here) 

आपका प्रश्न पहले से ही git ls-tree उत्पादन को दर्शाता है। sed खराब सबमिशन के साथ लाइन को हटा देता है, और git mktree परिणाम से एक नया पेड़ ऑब्जेक्ट बनाता है। समस्याग्रस्त एक शाब्दिक रूप में वस्तु के लिए प्रतिबद्ध

 
$ git cat-file commit c571a3ec94e9f84471577bac41ac7375c729ef08 | 
> sed 's/db22a67df70dc4ff90ec4cd666da91e9c2cb0d9/(new tree SHA1 here)/' | 
> git hash-object -t commit -w --stdin 
(new commit SHA1 here) 

git cat-file commit c571a3ec94e9f84471577bac41ac7375c729ef08 प्रिंट:

एक बार जब आप निश्चित पेड़ है, तो आप एक निश्चित इस पेड़ का उपयोग कर के लिए प्रतिबद्ध बना सकते हैं। यह tree db22a67df70dc4ff90ec4cd666da91e9c2cb0d9 के साथ शुरू होगा, और बाकी की प्रतिबद्ध जानकारी (माता-पिता, लेखक, कमिटर, प्रतिबद्ध संदेश) के साथ जारी रहेगा। sed नए पेड़ के पुराने पेड़ के tree लाइन के संदर्भ को प्रतिस्थापित करता है। git hash-object -t commit -w --stdin परिणाम से एक नई प्रतिबद्ध वस्तु बनाता है, इसे भंडार में लिखता है, और इसकी आईडी प्रिंट करता है।

एक बार जब आप तय कर दी है प्रतिबद्ध है, तो आप git replace उपयोग कर सकते हैं:

 
$ git replace c571a3ec94e9f84471577bac41ac7375c729ef08 (new commit SHA1 here) 

यह वास्तव में अभी तक कुछ भी नहीं बदलता है, लेकिन बताता Git कि यह प्रतिबद्ध c571a3ec94e9f84471577bac41ac7375c729ef08 पढ़ता था जब भी, यह पढ़ना चाहिए नई वस्तु के लिए प्रतिबद्ध बजाय।

और अंत में, इसे स्थायी बनाने के लिए git filter-branch का उपयोग करें। यह सभी काम करता है, उन्हें पढ़ता है, और उन्हें वापस लिखता है। आमतौर पर, कमेटी को संशोधित करने के किसी भी विकल्प के बिना, इसका अधिक प्रभाव नहीं पड़ेगा, लेकिन पहले git replace की वजह से, यह सभी c571a3ec94e9f84471577bac41ac7375c729ef08 के साथ काम करता है क्योंकि माता-पिता को इसके बजाय नई प्रतिबद्धता के संदर्भ में फिर से लिखा जाना चाहिए, जो सभी करता है उनको फिर से लिखे गए, आदि का संदर्भ लें।

+0

मैंने इसे एक समान भंडार पर करने की कोशिश की, लेकिन यह काम नहीं किया। 'गिट फ़िल्टर-शाखा' चलाते समय, यह मुझे बताता है कि टूटी हुई कैश प्रविष्टि के कारण इसे निष्पादित नहीं किया जा सकता है। 'गिट रेव-पार्स हेड' से पता चलता है कि जीआईटी ने प्रतिस्थापन ऑपरेशन पर ध्यान नहीं दिया है और अभी भी हेड को अपरिवर्तित टूटी प्रतिबद्धता पर सेट किया गया है। और मैं कामकाजी निर्देशिका में बदलाव खोए बिना एक और शाखा की जांच नहीं कर सकता। –

+0

@ मार्कग्रीन मुझे संदेह है कि वहां कुछ विवरण है जो इस प्रश्न से काफी अलग है कि इसे एक संशोधित या यहां तक ​​कि एक अलग दृष्टिकोण की आवश्यकता है, और यदि ऐसा है, तो यह एक अच्छा नया प्रश्न बना सकता है। यदि आप इसे इस तरह पोस्ट कर सकते हैं (स्वाभाविक रूप से पर्याप्त विवरण के साथ अपने आप उत्तरदायी होने के लिए), तो मुझे एक नज़र डालने में खुशी होगी। – hvd

+0

यह शानदार होगा अगर आदेशों के कुछ स्पष्टीकरण भी होंगे। मैं [इस तरह महसूस करता हूं] (https://xkcd.com/1597/) हर बार जब मुझे गिट समस्या होती है और SO –

0

शायद यह उस समस्या को संशोधित करने के लिए एक इंटरैक्टिव रीबेस के साथ काम करेगा जिसमें परेशानी कुछ डायरेक्ट्री प्रतिबद्ध संदर्भ शामिल है, उदा।

$ git branch backup_branch  # To be able to revert if not satisfied 
$ git rebase -i db22a6^   # From parent to db22a6 
... 
# You then select Edit for commit db22a6 in the editor 
... 
$ git reset HEAD^    # Reset the commit db22a6 but not its changes 
$ git status 
... 
# should list as modified: .gitignore .project SomeDirectory GoDeploy.bat pom.xml 
... 
$ git checkout SomeDirectory  # Cancel the troublesome change 
$ git add .gitignore .project GoDeploy.bat pom.xml 
$ git commit -m "your commit message" 
$ git rebase --continue 
+0

db22a6 पेड़ वस्तु का SHA1 है, दोषपूर्ण प्रतिबद्धता नहीं। वैसे भी, मैंने इसे c571a3 के साथ करने की कोशिश की लेकिन सफलता के बिना। यह परिवर्तन करने में विफल रहता है और इसे अगले प्रतिबद्धता के साथ एक संघर्ष के रूप में चिह्नित करता है। – gizmo

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