जीआईटी रिपॉजिटरी से अप्रयुक्त वस्तुओं को कैसे हटाया जाए?


89

मैंने गलती से जोड़ा, प्रतिबद्ध किया और एक बहुत बड़ी बाइनरी फ़ाइल को अपने बहुत नवीनतम कमिट के साथ जीआईटी रिपॉजिटरी में धकेल दिया।

मैं Git को उस वस्तु (ओं) को कैसे हटा सकता / सकती हूं जो उस प्रतिबद्ध के लिए बनाई गई थीं ताकि मेरी .gitनिर्देशिका फिर से एक आकार में सिकुड़ जाए?

संपादित करें : आपके उत्तर के लिए धन्यवाद; मैंने कई उपाय आजमाए। किसी ने काम नहीं किया। उदाहरण के लिए GitHub से किसी ने इतिहास से फाइलें हटा दी हैं, लेकिन .gitनिर्देशिका का आकार कम नहीं हुआ है:

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(

13
मॉडरेटर्स के लिए सिर्फ एक अनुस्मारक, यह प्रश्न 100% SO पर है, सुपरयुसर नहीं।
वॉन सीएपी


जैसा कि यहां बताया गया है ( stackoverflow.com/questions/685319/… ), क्या आपने अपने जीसी के बाद रीपैक की कोशिश की? उदाहरण के लिए git-repack -aइसके बाद git-prune-packed। देखें blog.felipebalbi.com/2007/12/19/...
VonC

2
@ जोनास: और क्या होगा, अगर आपने वह सब किया, तो आप अपने रेपो को क्लोन कर लेते हैं? क्या आप तब वांछित कम आकार के साथ एक क्लोन प्राप्त कर सकते हैं?
वॉन सी पी

1
@Jonas: सब है कि तुमने किया था के बाद ( filter-branch, gc, repack, ...), नहीं, तुम नहीं देखना चाहिए किसी भी बुरा सब पर करते हैं। यह एक संकेत है कि सफाई अपेक्षित रूप से नहीं हुई।
वॉन सीपीसी

जवाबों:


127

मैंने इसका अन्यत्र उत्तर दिया, और यहाँ से नकल करूँगा क्योंकि मुझे इस पर गर्व है!

... और आगे की हलचल के बिना, मैं आपके लिए यह उपयोगी स्क्रिप्ट प्रस्तुत कर सकता हूं, git-gc-all, आपके सभी गिट कचरे को हटाने की गारंटी जब तक वे अतिरिक्त कॉन्फ़िगरेशन चर के साथ नहीं आ सकते:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "$@"

- प्रगतिशील विकल्प मददगार हो सकता है।

नोट: यह सभी अपरिचित चीज़ों को हटा देगा, इसलिए मेरे पास रोना मत आना अगर आप बाद में फैसला करते हैं कि आप उनमें से कुछ को रखना चाहते थे!

आपको भी कुछ इस तरह से चलाने की आवश्यकता हो सकती है, ओह प्रिय, गिट जटिल है !!

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n1 --no-run-if-empty git update-ref -d

मैंने यह सब एक पटकथा में यहाँ रखा है:

http://sam.nipl.net/b/git-gc-all-ferocious


जैसा कि stackoverflow.com/questions/1904860/… , +1 पर फिर से आपको।
VonC

18
उत्कृष्ट: D मेरी दुष्ट योजना क्लोनिंग उत्तरों द्वारा अधिक अंक प्राप्त करने के लिए काम की है !! 1;)
सैम वाटकिंस

हाँ! इसने काम किया, लेकिन मुझे पूरी स्क्रिप्ट चलानी पड़ी। केवल gc कमांड (कॉन्फिग ऑप्शन के साथ) रन करना पर्याप्त नहीं था।
डेनियल


4
स्क्रिप्ट के लिए बहुत बहुत धन्यवाद! बोनस की जानकारी: xargsगैर-मान्यता प्राप्त विकल्प के कारण OS X पर कमांड एक त्रुटि उत्पन्न करता है। सबसे सरल समाधान: होमबॉव के माध्यम से जीएनयू xargs स्थापित करें brew install findutilsऔर इसके xargsद्वारा प्रतिस्थापित करें gxargs
क़किलिहक २ '’१q

26

आप git reflog expire --allगलत है यह उन रिफ्लॉग प्रविष्टियों को हटाता है जो एक्सपायरी समय से अधिक पुरानी होती हैं, जो 90 दिनों तक चूक जाती हैं। का उपयोग करें git reflog expire --all --expire=now

इसी तरह के एक सवाल का मेरा जवाब वास्तव में भंडार से अप्रयुक्त वस्तुओं की स्क्रबिंग की समस्या से निपटता है।


18

1) फ़ाइल को git रेपो (और फाइलसिस्टम नहीं) से निकालें:

  • git rm --cached path/to/file

2) उपयोग करके रेपो को सिकोड़ें:

  • git gc,

  • या git gc --aggressive

  • या git prune

या उपरोक्त का एक संयोजन जैसा कि इस प्रश्न में सुझाव दिया गया है: गिट रिपोसिटरी आकार को कम करें


10

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

यदि आप बाइनरी को अन्य लोगों के लिए रेपो में उपलब्ध रखना चाहते हैं, तो आप जो चाहते हैं वह करने का कोई वास्तविक तरीका नहीं है। यह सभी या बहुत ज्यादा नहीं है।



6

Hy!

Git केवल उन वस्तुओं को प्राप्त करता है जिनकी वास्तव में आवश्यकता होती है जब क्लोनिंग रिपॉजिटरी (यदि मैं इसे सही ढंग से समझता हूं)

तो आप गलती से जोड़ी गई फ़ाइल को हटाने की अंतिम प्रतिबद्ध में संशोधन कर सकते हैं, फिर अपने परिवर्तनों को दूरस्थ रिपॉजिटरी (सर्वर पर पुरानी प्रतिबद्ध को भी अधिलेखित करने के लिए -f विकल्प के साथ) पर धकेलें

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

वैकल्पिक रूप से यदि आप सर्वर से अनावश्यक फ़ाइलों को हटाना चाहते हैं, तो आप सर्वर पर रिपॉजिटरी को हटा सकते हैं और अपनी नई क्लोन कॉपी (जिसमें पूरा इतिहास है) को धक्का दे सकते हैं



4
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all

Filenameआप जिस रिपॉजिटरी से हटाना चाहते हैं , उसके लिए बदलना याद रखें ।


0

2020 में गिट-फिल्टर-ब्रांच के लिए प्रलेखन इसके उपयोग को हतोत्साहित करता है और गिट-फिल्टर-रेपो जैसे विकल्प का उपयोग करने की सिफारिश करता है । इसका इस्तेमाल BFG की जगह भी किया जा सकता है ।

ध्यान दें कि git पुस्तक में Rewriting History का अध्याय अपडेट नहीं किया गया है। संवेदनशील डेटा को हटाने के लिए न तो GitHub की सिफारिश की गई है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.