2010-06-29 19 views
53

चलो कहते हैं कि मैं एक रेपो कि इस निर्देशिका संरचना शामिल करते हैं:सभी काम करने के लिए मैं एक गिट रेपो में निर्देशिका कैसे स्थानांतरित कर सकता हूं?

repo/ 
    blog/ 
    _posts/ 
     some-post.html 
    another-file.txt 

मैं रेपो के शीर्ष स्तर पर _posts ले जाना चाहते हैं, तो संरचना इस तरह दिखेगा:

repo/ 
    _posts/ 
    some-post.html 
    another-file.txt 

यह git mv के साथ काफी आसान है, लेकिन मैं इतिहास को देखना चाहता हूं जैसे कि _postsहमेशा रेपो की जड़ पर मौजूद था, और मैं के पूरे इतिहास को git log -- _posts/some-post.html के माध्यम से प्राप्त करने में सक्षम होना चाहता हूं। मुझे कल्पना है कि मैं इसे पूरा करने के लिए git filter-branch के साथ कुछ जादू का उपयोग कर सकता हूं, लेकिन मुझे यह नहीं पता कि यह कैसे करना है। कोई विचार?

उत्तर

68

आप प्राप्त करने के लिए उप-निर्देशिका फिल्टर का उपयोग कर सकते

$ git filter-branch --subdirectory-filter blog/ -- --all 

संपादित करें 1:

$ git filter-branch --tree-filter 'mv blog/_posts .' HEAD 
: यदि आप प्रभावी रूप से _posts जड़ बनाने के लिए नहीं करना चाहती
हैं, तो एक पेड़ फिल्टर का प्रयोग

संपादित करें 2: यदि blog/_posts कुछ कामों में मौजूद नहीं था, तो उपर्युक्त विफल हो जाएगा। बजाय इस का उपयोग करें:

$ git filter-branch --tree-filter 'test -d blog/_posts && mv blog/_posts . || echo "Nothing to do"' HEAD 
+3

यह भी है * बहुत * तेजी से' उपयोग करने के लिए --index-filter', क्योंकि यह पेड़ की जाँच की जरूरत नहीं है – Cascabel

+6

हाँ सूचकांक - तुम भी dir1/dir2/dir3/तरह नेस्टेड dirs उपयोग कर सकते हैं -फिल्टर तेज़ है, लेकिन यह काम नहीं करेगा क्योंकि दिखाए गए आदेश _not_ इंडेक्स को प्रभावित करते हैं। आपको इंडेक्स मैनिपुलेशन केवल तभी करना होगा जब आप इंडेक्स-फ़िल्टर का उपयोग करना चाहते हैं (उदाहरण के लिए 'rm' के बजाय 'git rm --cached') – sehe

+0

क्या मैं टैग भी रख सकता हूं? ऐसा लगता है कि वे मेरे मामले में चले गए हैं। – Michael

31

जबकि रामकुमार का जवाब बहुत ही उपयोगी और worthwile है, यह कई स्थितियों में काम नहीं करेगा। उदाहरण के लिए, जब आप किसी अन्य स्थान पर अन्य उपनिर्देशिकाओं के साथ निर्देशिका को स्थानांतरित करना चाहते हैं।

git filter-branch --index-filter \ 
    'git ls-files -s | sed "s-\t\"*-&NEWSUBDIR/-" | 
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ 
    git update-index --index-info && 
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD 

बस अपने वांछित नई निर्देशिका के साथ NEWSUBDIR बदल देते हैं:

इस के लिए, आदमी पेज सही आदेश में शामिल है। । "

+9

और चूंकि यह तुरंत देखने से स्पष्ट नहीं है वह आदेश या परिणामी त्रुटियां, \ t खराब नहीं है ओएस एक्स के संस्करण के के संस्करण पर के। इसके चारों ओर बहुत सारे तरीके हैं, लेकिन शायद सबसे तेज़ है \ t को हटाना और ctrl-v, टाइप करके इसे एक शाब्दिक टैब से प्रतिस्थापित करना। –

+2

आप मूल फ़ोल्डर को कैसे निर्दिष्ट करते हैं, या यह सिर्फ पूरी शाखा को स्थानांतरित करता है? जब मैं इसे किसी फ़ोल्डर से चलाने की कोशिश करता हूं जिसे मैं स्थानांतरित करना चाहता हूं, तो मुझे 'कमांड को काम करने वाले पेड़ के अपूर्ण से चलाने की आवश्यकता है' – joshcomley

+1

'sed' कमांड क्या करता है? मैं विंडोज़ पर यह कोशिश कर रहा हूं और एक विकल्प की जरूरत है। – Lucius

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

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