2013-07-26 8 views
7

परिदृश्य निम्न है:गिट फ़िल्टर-शाखा ने एक डिस्कनेक्ट इतिहास का नेतृत्व किया: पुराने कामों से कैसे छुटकारा पाएं?

मेरे पास एक बड़ा सीवीएस भंडार है जिसे मैं 14 विशिष्ट गिट भंडारों में परिवर्तित करना चाहता हूं। cvs2git प्रक्रिया का हिस्सा ठीक है और एक बड़ी भंडार repo.git की ओर जाता है।

14 Git रेपो में से प्रत्येक के लिए, मैं मुख्य रेपो क्लोन और मैं निम्नलिखित कमांड चलाएँ:

git filter-branch -d /tmp/rep --tag-name-filter cat --prune-empty --subdirectory-filter "sub/directory" -- --all 

हालांकि, इस आदेश से पहले, मैं कुछ Git संग्रह क्योंकि के लिए एक और git filter-branch आदेश प्रदर्शन करने के लिए है मुझे एक निर्देशिका से दूसरी निर्देशिका में फ़ाइल को स्थानांतरित करने के लिए प्रतिबद्धताओं को फिर से लिखना होगा। --tree-filter वह विकल्प है जिसका मैं उपयोग करता हूं।

script_tree_filter="if test -f rep/to/my/file && test -d another/rep ; then echo Moving my file ; mv rep/to/my/file another/rep; fi" 
git filter-branch -d /tmp/rep --tag-name-filter cat --prune-empty --tree-filter '$script_tree_filter' -- --all 

प्रक्रिया के अंत में: यहाँ कमांड लाइन का एक उदाहरण मार डाला है (14500 प्रतिबद्ध: इसके बारे में 1 घंटा लगता है!) मैं refs साफ और प्रयोग git gc:

git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d 
git reflog expire --expire=now --all 
git gc --prune=now 

पर अंत में मैं 1.2 जीओ के आकार के साथ एक भंडार प्राप्त करता हूं (जो अभी भी बहुत बड़ा है), और कामों को देखकर, मैं देख सकता हूं कि बहुत से पुराने लोग अभी भी मौजूद हैं। वे फ़ाइल और निर्देशिकाओं से संबंधित हैं जो --subdirectory-filter कमांड के बाद और यहां नहीं रहना चाहिए।

discontinuity seen in gitk

मैं बहुत कुछ है कि उन प्रतिबद्ध अभी भी वजह से मौजूद हैं हूँ:

प्रतिबद्ध के इतिहास में, वहाँ gitk --all के रूप में देखा अवांछित करता और अच्छे के बीच एक अलगाव है उन पर कुछ पर टैग। यदि ऐसा है, तो क्या अच्छे टैग पर किसी को हटाए बिना उन टैग को हटाना संभव है?

यदि टैग कारण नहीं हैं, तो कोई विचार?

अधिक जानकारी के लिए refs निर्देशिका की सामग्री (Git भंडार उपनिर्देशिका फिल्टर द्वारा प्राप्त में) खाली है:

$ ls -R refs/ 
refs/: 
heads original tags 

refs/heads: 

refs/original: 
refs 

refs/original/refs: 
heads tags 

refs/original/refs/heads: 

refs/original/refs/tags: 

refs/tags: 

मैं पाया है कि शाखाओं और टैग फ़ाइल packed-refs में सूचीबद्ध हैं गिट भंडार में:

d0c675d8f198ce08bb68f368b6ca83b5fea70a2b refs/tags/v03-rev-04 
95c3f91a4e92e9bd11573ff4bb8ed4b61448d8f7 refs/tags/v03-rev-05 

फ़ाइल में सूचीबद्ध 817 टैग और 21 9 शाखाएं हैं।

+1

'git gc' टैग रीफ को पैक किया जाएगा .git/packed-refs, इसलिए खाली निर्देशिकाएं। मुझे यकीन नहीं है कि टैग पुराने कामों को क्यों इंगित करेंगे, हालांकि प्रत्येक फिल्टर-शाखा सेशन ने '--tag-name-filter' का उपयोग किया था .... – torek

+1

क्या आपने इस पोस्ट के 4 आदेशों के अनुसार साफ किया था ?http://stackoverflow.com/a/7966852/11343 – CharlesB

+0

'रीसेट हार्ड' को छोड़कर, मैंने अपने प्रश्न में उल्लिखित 3 अन्य कमांड किए हैं ('rm -rf .git/refs/original /' लिखा नहीं गया है वैसे ही जब मेरे पास एक नंगे भंडार है)। मैंने जीसी के '--ग्रेशिव' विकल्प का उपयोग नहीं किया, लेकिन मैं कोशिश नहीं कर सकता (मुझे नहीं लगता कि यह कुछ भी बदलेगा)। – Frodon

उत्तर

5

मैंने cvs2git का उपयोग करने के तरीके को बदलकर अपनी समस्या को हल करने में कामयाब रहा: पूरे सीवीएस बेस को परिवर्तित करने के बजाय और subdirectory-filter कमांड का उपयोग करने के बजाय, मैंने प्रत्येक पनडुब्बियों को परिवर्तित किया।

# Module 1 
cvs2git --blobfile=blob_module1 --dump=dump_module1 /path/to/cvs/base/path/to/module1 
# Module 2 
cvs2git --blobfile=blob_module2 --dump=dump_module2 /path/to/cvs/base/path/to/module2 

पहले

cvs2git --blobfile=blob --dump=dump /path/to/cvs/base 
# Module 1 
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter "path/to/module1" -- --all 
# Module 2 
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter "path/to/module2" -- --all 

अब प्रत्येक भंडार अब एक आदर्श इतिहास रहा है: मेरे मामले में, यह 18 विभिन्न cvs2git आदेशों लांच करने के लिए नेतृत्व किया।

पिछली विधि क्यों काम नहीं करती थी? मेरा अनुमान है कि cvs2git सभी सबडोड्यूल के साथ उलझन में था (उनमें से कुछ ने उनके इतिहास के नाम को उनके इतिहास के दौरान बदल दिया था)।

@ माइकल @ चार्ल्स बी जवाब देने और मेरी सहायता करने के लिए अपना समय लेने के लिए धन्यवाद।

+1

+1 आपके समाधान को साझा करने के लिए, आपको यह जानकर खुशी हुई कि आपने इसे हल किया है – CharlesB

+1

@ चार्ल्सबी: आपके समर्थन के लिए धन्यवाद – Frodon

+2

खुशी है कि आपको यह हल हो गया है, मैं उत्सुक था कि आप सीवी से खुद को एक बड़ा रेपो क्यों बना रहे थे - भयानक है कि आपने साझा किया समाधान - चीयर्स। +1 भी – Michael

2

मुझे यकीन है कि आप इस के साथ मारा जा रहा है: सीवीएस और Git शाखा/टैग मॉडलों के बीच

  • अंतर: सीवीएस एक शाखा या टैग की अनुमति देता है कई स्रोत से स्रोत पुनरीक्षण के मनमाने ढंग से संयोजन से बनाया जा करने के लिए शाखाओं। यह फ़ाइल संशोधनों को भी अनुमति देता है जो कभी भी एक शाखा/टैग में जोड़े जाने के लिए समकालीन नहीं थे। दूसरी तरफ, गिट पूरे स्रोत पेड़ की अनुमति देता है, क्योंकि यह इतिहास में कुछ पल में अस्तित्व में था, एक इकाई के रूप में ब्रांच या टैग किया गया था। इसके अलावा, एक गिट संशोधन के वंश ने उस संशोधन की सामग्री के बारे में प्रभाव डाला है। इस अंतर का मतलब है कि एक गिट भंडार में 100% ईमानदारी से एक मनमानी सीवीएस इतिहास का प्रतिनिधित्व करना मूल रूप से असंभव है।cvs2git निम्न उपायों की उपयोग करता है:

    • cvs2git एक ही स्रोत से एक शाखा बनाने की कोशिश करता है, लेकिन अगर यह समझ नहीं कैसे करने के लिए, यह शाखा एकाधिक स्रोत शाखाओं से एक "मर्ज" का उपयोग कर बनाता है। रोगजनक परिस्थितियों में, शाखा के लिए विलय स्रोतों की संख्या मनमाने ढंग से बड़ी हो सकती है। परिणामी इतिहास का तात्पर्य है कि जब भी किसी भी फाइल को शाखा में जोड़ा गया था, तो संपूर्ण स्रोत शाखा गंतव्य शाखा में विलय कर दी गई थी, जो स्पष्ट रूप से गलत है। (वैकल्पिक, विलय को छोड़ने के लिए, जानकारी को त्याग दिया जाएगा कि कुछ सामग्री एक शाखा से दूसरी शाखा में ले जाया गया था।)

    • यदि cvs2git यह निर्धारित नहीं कर सकता कि एक सीवीएस टैग एक संशोधन से बनाया जा सकता है, तो यह बनाता है TAG.FIXUP नाम की एक टैग फ़िक्सअप शाखा, फिर इस शाखा को टैग करें। (यह इस तथ्य के लिए एक आवश्यक कामकाज है कि गिट केवल मौजूदा संशोधन को टैग करने की अनुमति देता है।) TAG.FIXUP शाखा को उन सभी शाखाओं के बीच विलय के रूप में बनाया गया है जिनमें टैग में शामिल फ़ाइल संशोधन शामिल हैं, जिसमें वर्णित वही व्यापार शामिल है शाखाओं के लिए ऊपर। रूपांतरण के अंत में TAG.FIXUP शाखा साफ़ कर दी गई है, लेकिन (गिट फास्ट-आयात फ़ाइल प्रारूप की तकनीकी सीमा के कारण) हटाई नहीं गई है। कुछ स्थितियां हैं जब एक एकल संशोधन से एक टैग बनाया जा सकता है, लेकिन cvs2git इसे महसूस नहीं करता है और एक अनिवार्य टैग फ़िक्सअप शाखा बनाता है। परिणामी गिट भंडार के भीतर contrib/git-move-refs.py स्क्रिप्ट चलाकर रूपांतरण के बाद अनावश्यक टैग फ़िक्सअप शाखाओं को हटाना संभव है।

  • कोई जांच नहीं है कि सीवीएस शाखा और टैग नाम कानूनी गिट नाम हैं। शायद अन्य गिट बाधाएं हैं जिन्हें भी जांचना चाहिए। see cvs2git

आप नए dirs की या रूपांतरण के बाद बड़े रेपो की refs निर्देशिका दिखा रहे हैं? बड़े रिपो को फ़िल्टर और विभाजित करने से पहले आप अपने एकल बड़े निर्यात रेपो में टैग हटा सकते हैं।

आप निर्देशिका में फ़ाइल को हटाकर बड़े रिपो में टैग हटा सकते हैं - यह केवल SHA का संदर्भ है।

+0

रेफरी निर्देशिका एक नई डीआईआर में से एक है (उपनिर्देशिका फ़िल्टर के बाद)। सभी टैग हटाना एक विकल्प नहीं है: मैं उन लोगों को रखना चाहता हूं जो मेरे द्वारा रखी गई निर्देशिकाओं से संबंधित हैं। – Frodon

+0

मैंने नहीं कहा कि सभी टैग हटाएं, केवल अनावश्यक लोगों को हटाएं = आप कह रहे थे कि कुछ अनावश्यक टैग समस्याएं पैदा कर रहे थे। – Michael

+0

चाल यह है कि मुझे नहीं पता कि "अच्छे" टैग और "खराब" को कैसे अंतर किया जाए। मैं वर्तमान में उन पर टैग के साथ खाली प्रतिबद्धताओं को हटाने की जांच कर रहा हूं। – Frodon

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