2009-05-30 7 views
20

मेरे पास 33 एमबी बड़ी फ़ाइल है जहां मैं उस फ़ाइल के सबसे पुराने संशोधन को स्थायी रूप से हटाना चाहता हूं, इसलिए मैं केवल नवीनतम एक्स संशोधन को रखता हूं। यह कैसे करना है?गिट फ़ाइल के सबसे पुराने संशोधन को हटाएं

मेरी नंगे भंडार इसके कारण बड़ी हो गई है।

मैं निम्नलिखित की कोशिश की है .. लेकिन यह फ़ाइल को हटा पूरी तरह

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_manual.txt' HEAD 

मेरी भंडार में बड़ी फ़ाइलों को मैं git-large-blob by Aristotle Pagaltzis का उपयोग पहचान करने के लिए।

+0

मुझे लगता है कि यदि आप इस फाइल को और तुम क्या करने की कोशिश कर रहे हैं के बारे में कुछ और जानकारी दे दी है यह मदद मिलेगी। यह एक एक बंद घटना होने जा रहा है या आप फ़ाइल को शुद्ध और भंडार इतिहास नियमित रूप से पुनर्लेखन के लिए योजना बनाई है? यदि आपको अपना इतिहास रखने की आवश्यकता नहीं है तो आप फ़ाइल को गिट में क्यों ट्रैक कर रहे हैं? आपका नंगे भंडार कितना बड़ा है और क्या यह वास्तव में एक समस्या है यदि यह बड़ा है? –

+0

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

+0

हां, मुझे आशा है कि समय-समय पर ऐसा करना संभव है। – neoneye

उत्तर

16

मुझे लगता है कि आप git filter-branch कमांड के साथ सही रास्ते पर हैं। समस्या यह है कि आपने फ़ाइल को किसी भी काम में रखने के लिए नहीं बताया है, इसलिए इसे उन सभी से हटा दिया गया है। अब, मुझे नहीं लगता कि सीधे किसी भी काम को छोड़ने के लिए git-filter-branch बताएं। हालांकि, चूंकि कमांड शेल संदर्भ में चलाए जाते हैं, इसलिए संशोधनों की अंतिम एक्स संख्या के अलावा सभी को हटाने के लिए खोल का उपयोग करना बहुत कठिन नहीं होना चाहिए। कुछ इस तरह:

KEEP=10 I=0 NUM_COMMITS=$(git rev-list master | wc -l) \ 
git filter-branch --index-filter \ 
'if [[ ${I} -lt $((NUM_COMMITS - KEEP)) ]]; then 
    git rm --cached --ignore-unmatch big_manual.txt; 
fi; 
I=$((I + 1))' 

कि पिछले 10 प्रतिबद्ध में big_manual.txt बनाए रखेगा।

कहा जा रहा है कि चार्ल्स ने उल्लेख किया है, मुझे यकीन नहीं है कि यह सबसे अच्छा तरीका है, क्योंकि आप पुराने संस्करणों को हटाकर वीसीएस के पूरे बिंदु को पूर्ववत कर रहे हैं।

क्या आपने पहले से ही git-gc और/या git-repack के साथ गिट रेपॉजिटरी को अनुकूलित करने का प्रयास किया है? यदि नहीं, तो वे कोशिश करने लायक हो सकते हैं।

+1

यह समाधान है! यह सभी 312 संशोधनों के माध्यम से चला गया और सबसे पुराना संशोधन, सही छोड़ दिया। यह बहुत शैक्षिक था। लूप के लिए, पुन: सूची .. और किसी भी प्रतिबद्ध आईडी के बिना फिल्टर-शाखा को कॉल करना जो अनजान लगता है (यह जांचना होगा कि जादू कैसे काम करता है), लेकिन यह काम करता था। उसके लिये आपका धन्यवाद। कभी-कभी मैं गिट-जीसी और एफएसके का उपयोग करता हूं, लेकिन यह अभी तक कुछ नहीं है जिसे मैंने स्वचालित किया है। चलो वीसीएस के बारे में मेरी राय के बारे में बात न करें :-) – neoneye

+1

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

+0

लिपि के लिए धन्यवाद। मैंने इसे एक बैश स्क्रिप्ट फ़ाइल में बनाया और पाया कि मुझे इसे थोड़ा समायोजित करने की आवश्यकता है ' #!/bin/bash KEEP = 10 I = 0 NUM_COMMITS = $ (गिट रेव-लिस्ट मास्टर | wc -l) \ गिट फ़िल्टर-शाखा - इंडेक्स-फ़िल्टर \ 'अगर [$ {I} -lt $ ((NUM_COMMITS - KEEP))]; फिर git rm --cached --ignore-unmatch फ़ाइल-to-delete.tar; फाई; I = $ ((I + 1)) ' ' –

15

नोट: इस जवाब एक पूरी परियोजना के इतिहास को छोटा करने के बजाय पुराने इतिहास क्या सवाल के बारे में था से एकल फाइल हटाने के बारे में है!

$ echo "$commit_id" >> .git/info/grafts 

जहां $commit_id है:


एक पूरी परियोजना के इतिहास git filter-branch का उपयोग कर उपयोग करने के लिए किया जाएगा द्वारा कम करने के लिए सबसे आसान तरीका तंत्र (repository layout दस्तावेज़ देखें) छोटा करने के लिए इतिहास grafts एक प्रतिबद्धता है कि आप एक नई भंडार की जड़ (पहली प्रतिबद्धता) बनना चाहते हैं। "गिट लॉग" या ग्राफ़िकल इतिहास व्यूअर का उपयोग करके देखें, जैसे कि इतिहास जैसा दिखता है, और "गिट फ़िल्टर-शाखा - सभी" चलाएं; ग्रिट-फ़िल्टर-शाखा दस्तावेज में ग्राफ्ट्स का उपयोग वर्णित किया गया है।

या आप git clone की --depth <depth> विकल्प का उपयोग करके उथले क्लोन उपयोग कर सकते हैं।



आप एकल फ़ाइल (क्या मूल रूप से अनुरोध किया गया था) के हिस्से के इतिहास निकालने के लिए ग्राफ्ट का उपयोग कर सकते चरणों का उपयोग कर नीचे का वर्णन। इस समाधान में solution proposed by Dan Moulding से अधिक चरण शामिल हैं, लेकिन प्रत्येक चरण सरल है, और आप "गिट लॉग" या आलेखीय इतिहास दर्शक का उपयोग करके मध्यवर्ती चरणों की जांच कर सकते हैं।

  1. सबसे पहले, उस बिंदु का चयन करें जहां आप फ़ाइल को हटाना चाहते हैं, और उन बिंदुओं पर शाखाएं बनाकर उनको चिह्नित करें। उदाहरण के लिए आप फ़ाइल के लिए पहली बार दिखाई में f020285b प्रतिबद्ध करना चाहते हैं और यह सब यह पूर्वजों में हटा दिया है, तो वह पूर्वज निशान (यह मानते हुए साधारण है, गैर मर्ज करने) का उपयोग कर

    $ git branch cleanup f020285b^ 
    
  2. दूसरा, को दूर इतिहास cleanup (यानी f020285b^) के साथ शुरुआत Git फिल्टर शाखा का उपयोग करने से फ़ाइल, के रूप में git-filter-branch मैनपेज का "उदाहरण" अनुभाग में दिखाया गया:

    $ git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_manual.txt' cleanup 
    

    आप भी सब करता है जो केवल करने के लिए बदल गया था निकालना चाहते हैं हटाई गई फ़ाइल आप अतिरिक्त रूप सेका उपयोग कर सकते हैं गिट-फ़िल्टर-शाखा के लिएविकल्प।

  3. इसके बाद, इतिहास का उपयोग ग्राफ्ट तंत्र के बाकी के साथ इतिहास का पुनः हिस्सा शामिल हो:

    $ echo $(git-rev-parse f020285b) $(git rev-parse cleanup) >> .git/info/grafts 
    

    तो फिर तुम अगर इसे सही ढंग से जुड़ा हुआ है की जाँच करने के इतने Histry जांच कर सकते हैं।

  4. अंतिम, ग्राफ्ट स्थायी (यह सब ग्राफ्ट स्थायी बनाना होगा, लेकिन यहाँ मान लें कि आप ग्राफ्ट अन्यथा का उपयोग नहीं करते की सुविधा देता है) Git फिल्टर शाखा का उपयोग कर,

    $ git filter-branch cleanup..HEAD 
    

    बनाने के लिए और ग्राफ्ट (हटाने के रूप में वे किसी भी अधिक की जरूरत नहीं कर रहे हैं), और cleanup शाखा

    $ rm .git/info/grafts 
    $ git branch -d cleanup 
    

अंतिम नोट: यदि आप कुछ फ़ाइल के इतिहास के हिस्से को हटाने, तो आप बेहतर सुनिश्चित करें कि यह बिना परियोजना फ़ाइल समझ में आता है (और उदाहरण के लिए सही ढंग से संकलित करता है)।

+0

दिलचस्प। कोशिश करेंगे। – neoneye

+0

हाँ, ग्राफ्ट तंत्र वास्तव में ऐसा करने का इरादा तरीका प्रतीत होता है। मुझे इसके बारे में जागरूक करने के लिए धन्यवाद। दुर्भाग्यवश मेरे पास आज प्रयोग करने का समय नहीं है। – neoneye

+0

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

3

आप git submodules उपयोग करने पर विचार कर सकते हैं। इस तरह आप एक और Git भंडार में चित्र और अन्य बड़ी फ़ाइलों रख सकते हैं, और भंडार स्रोत कोड है कि अन्य भंडार की एक विशेष संशोधन का उल्लेख कर सकते है।

आप सिंक में भंडार संस्करणों को रखने का है, क्योंकि माता-पिता भंडार एक विशेष उप भंडार संशोधन करने के लिए एक लिंक होता है में मदद मिलेगी कि। यह आपको उप-भंडार में पुराने संशोधन को हटाने/पुनर्स्थापित करने की अनुमति देगा, बिना माता-पिता भंडार को प्रभावित किए, जहां आपका स्रोत कोड है - उप-भंडार में पुराने संशोधन के निष्कासन माता-पिता भंडार के इतिहास को गड़बड़ नहीं करेंगे, क्योंकि आप बस अद्यतन कि जो भंडार अंक के संशोधन माता-पिता में उप भंडार लिंक करने के लिए।

+0

अच्छा बिंदु। मैं गिट submodules के बारे में नहीं पता था। – neoneye

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