2012-04-09 7 views
168

मैं अपने गिटहब खाते पर एक संग्रह पर काम कर रहा था और यह एक समस्या है जिस पर मैंने ठोकर खाई। कुछ NPM संकुल स्थापित गिट/गिटहब के इतिहास से फ़ोल्डर और इसकी सामग्री को हटाएं

  • संकुल node_modules फ़ोल्डर
  • जोड़ा गया है कि भंडार git करने के लिए फ़ोल्डर और में थे के साथ एक फ़ोल्डर के साथ

    • Node.js परियोजना कोड GitHub के लिए (के बारे में सोच नहीं किया गया था धक्का दिया उस समय NPM हिस्सा)
    • एहसास है कि तुम सच नहीं है जरूरत है कि फ़ोल्डर कोड
    • का एक हिस्सा उस फ़ोल्डर नष्ट कर दिया गया हो सकता है, यह
    धक्का दिया

    उस उदाहरण पर, कुल गिट रेपो का आकार लगभग 6MB था जहां वास्तविक कोड (उस फ़ोल्डर को छोड़कर सभी) केवल 300 KB था।

    अब मैं अंत में क्या देख रहा हूं वह गिट के इतिहास से उस पैकेज फ़ोल्डर के विवरण से छुटकारा पाने का एक तरीका है, इसलिए यदि कोई इसे क्लोन करता है, तो उन्हें 6 एमबी के इतिहास को डाउनलोड करने की ज़रूरत नहीं है, जहां केवल वास्तविक फाइलें वे अंतिम प्रतिबद्धता के रूप में प्राप्त करेंगे 300KB होगा।

    मैं इस के लिए संभव समाधान ऊपर देखा और

    सार लग रहा था जैसे कि यह काम करने की कोशिश की इन 2 तरीकों जहां स्क्रिप्ट चलाने के बाद, यह दिखाया गया है कि यह उस फ़ोल्डर से छुटकारा पा लिया और उसके बाद यह दिखाया गया कि 50 अलग-अलग कामों को संशोधित किया गया था। लेकिन उसने मुझे उस कोड को धक्का नहीं दिया। जब मैंने इसे धक्का देने की कोशिश की, तो उसने Branch up to date कहा लेकिन दिखाया कि 50 कमिट्स git status पर संशोधित किए गए थे। अन्य 2 विधियों ने भी मदद नहीं की।

    अब यह दिखाया गया है कि यह उस फ़ोल्डर के इतिहास से छुटकारा पाता है, जब मैंने अपने लोकहोस्ट पर उस रेपो के आकार की जांच की, तो यह अभी भी लगभग 6 एमबी था। (मैंने refs/original फ़ोल्डर को भी हटा दिया लेकिन रेपो के आकार में परिवर्तन नहीं देखा)।

    जो मैं स्पष्ट करने के लिए देख रहा हूं, अगर न केवल प्रतिबद्ध इतिहास से छुटकारा पाने का कोई तरीका है (जो कि मुझे लगता है कि एकमात्र चीज है) लेकिन उन फाइलों की गिट यह भी मान रही है कि कोई रोलबैक करना चाहता है।

    आइए कहें कि इसके लिए एक समाधान प्रस्तुत किया गया है और इसे मेरे लोकहोस्ट पर लागू किया गया है लेकिन उस गिटहब रेपो को पुन: उत्पन्न नहीं किया जा सकता है, क्या यह रेपो क्लोन करना संभव है, पहली प्रतिबद्धता के लिए रोलबैक चाल को निष्पादित करता है और इसे दबाता है (या करता है इसका मतलब है कि गिट के पास अभी भी उन सभी का इतिहास होगा? - उर्फ ​​6 एमबी)।

    मेरा अंतिम लक्ष्य मूल रूप से गिट से फ़ोल्डर सामग्री से छुटकारा पाने का सबसे अच्छा तरीका है ताकि उपयोगकर्ता को 6 एमबी मूल्य की सामग्री डाउनलोड न हो और फिर भी संभवतः अन्य ऐसा काम करता है जो मॉड्यूल को कभी नहीं छुआ गिट के इतिहास में फ़ोल्डर (जो उनमें से बहुत अधिक है)।

    मैं यह कैसे कर सकता हूं?

  • +0

    यदि नीचे दिए गए किसी भी उत्तर में आपकी समस्या हल हो गई है, तो शायद आपको अपने प्रश्न का उत्तर स्वीकार करने पर विचार करना चाहिए। https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – starbeamrainbowlabs

    उत्तर

    320

    कॉपी-पेस्ट करने के लिए तुम यहाँ कर रहे हैं कोड:

    यह एक उदाहरण है जो इतिहास से node_modules को दूर करता है

    git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD 
    git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d 
    echo node_modules/ >> .gitignore 
    git add .gitignore 
    git commit -m 'Removing node_modules from git history' 
    git gc 
    git push origin master --force 
    
    +13

    हटाए गए संदर्भों द्वारा उपयोग की जाने वाली सभी जगहों को खाली करने के लिए आपके आदेश चलाने के बाद मुझे 'git gc' भी चलाया गया था । – pagliuca

    +12

    यह ध्यान देने योग्य है कि यदि आपको इस अपस्ट्रीम को धक्का देना है, तो आपको शायद 'गिट पुश मूल मास्टर --force' – DaveStephens

    +10

    का उपयोग करके एक गैर-फास्ट-फॉरवर्ड अपडेट को मजबूर करने की आवश्यकता होगी। यह स्वीकार्य उत्तर होना चाहिए! – prakharsingh95

    5

    पूरा प्रतिलिपि & पेस्ट नुस्खा, बस टिप्पणी में आदेश (के लिए जोड़ने कॉपी-पेस्ट समाधान), उन्हें परीक्षण के बाद:

    git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD 
    echo node_modules/ >> .gitignore 
    git add .gitignore 
    git commit -m 'Removing node_modules from git history' 
    git gc 
    git push origin master --force 
    

    इस के बाद, आप .gitignor से लाइन "node_modules /" निकाल सकते हैं ई

    106

    मुझे लगता है कि अन्य उत्तरों में उपयोग किए गए --tree-filter विकल्प बहुत धीमे हो सकते हैं, विशेष रूप से बहुत से कामों के साथ बड़े भंडारों पर।

    यहाँ विधि मैं पूरी तरह से --index-filter विकल्प है, जो बहुत जल्दी चलाता है का उपयोग कर Git इतिहास से एक निर्देशिका दूर करने के लिए उपयोग करते हैं:

    # Make a fresh clone of YOUR_REPO 
    git clone YOUR_REPO 
    cd YOUR_REPO 
    
    # Create tracking branches of all branches 
    for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done 
    
    # Remove DIRECTORY_NAME from all commits, then remove the refs to the old commits 
    # (repeat these two commands for as many directories that you want to remove) 
    git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch DIRECTORY_NAME/' --prune-empty --tag-name-filter cat -- --all 
    git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d 
    
    # Ensure all old refs are fully removed 
    rm -Rf .git/logs .git/refs/original 
    
    # Perform a garbage collection to remove commits with no refs 
    git gc --prune=all --aggressive 
    
    # Force push all branches to overwrite their history 
    # (use with caution!) 
    git push origin --all --force 
    git push origin --tags --force 
    

    आप से पहले भंडार के आकार की जाँच कर सकते और gc के बाद साथ :

    git count-objects -vH 
    
    +2

    क्या आप समझा सकते हैं कि यह बहुत तेज क्यों है? – knocte

    +6

    @knocte: दस्तावेज़ों से (https://git-scm.com/docs/git-filter-branch)। "- इंडेक्स-फ़िल्टर: ... पेड़ फ़िल्टर के समान है लेकिन पेड़ की जांच नहीं करता है, जो इसे बहुत तेज बनाता है" –

    +9

    यह स्वीकार्य उत्तर क्यों नहीं है? यह बहुत गहन है। –

    18

    लोकप्रिय जवाब above के अलावा मैं विंडोज -systems के लिए कुछ नोट जोड़ना चाहते हैं। आदेश

    git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD 
    
    • काम करता है पूरी तरह से किसी भी संशोधन के बिना! इसलिए, आपकोRemove-Item, del या rm -rf के बजाय कुछ और नहीं करना चाहिए।

    • आप किसी फ़ाइल या निर्देशिका उपयोग करने के लिए एक पथ निर्दिष्ट करने के लिए की जरूरत है स्लैश सबसे अच्छा और सबसे सटीक विधि मैंने पाया bfg.jar फ़ाइल डाउनलोड करने के लिए था./path/to/node_modules तरह

    +1

    यह लिनक्स पर भी सही और सरलतम आदेश है। – peterh

    +0

    यदि निर्देशिका में कोई है तो यह विंडोज पर काम नहीं करेगा। (डॉट) नाम में। –

    +2

    और मुझे समाधान मिला। आरएम कमांड के लिए डबल इनवर्टेड-कॉमा का उपयोग करें: "आरएम-आरएफ नोड.मोड्यूल"। –

    7

    : https://rtyley.github.io/bfg-repo-cleaner/

    git clone --bare https://project/repository project-repository 
    cd project-repository 
    java -jar bfg.jar --delete-folders node_modules 
    git reflog expire --expire=now --all && git gc --prune=now --aggressive 
    git push --mirror https://project/new-repository 
    

    :

    फिर कमांड चलाने आप फ़ाइल को हटाना चाहते हैं तो बजाय नष्ट-फ़ाइलें विकल्प का उपयोग:

    java -jar bfg.jar --delete-files *.pyc 
    
    +1

    बहुत आसान :) यदि आप यह सुनिश्चित करना चाहते हैं कि केवल एक विशिष्ट फ़ोल्डर हटा दिया गया है, तो इससे मदद मिलेगी: https://stackoverflow.com/questions/21142986/remove-filenames-from-specific-path – emjay

    0

    मैं बिन और obj वर्ष सी # खिड़कियों पर Git का उपयोग कर परियोजनाओं से फ़ोल्डरों को हटा दिया। साथ

    git filter-branch --tree-filter "rm -rf bin" --prune-empty HEAD 
    

    यह फ़ोल्डर स्थापित Git में usr/bin फ़ोल्डर को हटाने से Git स्थापना की अखंडता को नष्ट कर देता है सावधान रहें।

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