Git द्वारा बनाई गई बड़ी .pack फ़ाइल को निकालें


112

मैंने एक शाखा में फ़ाइलों के लोड की जाँच की और विलय कर दिया और फिर उन्हें निकालना पड़ा और अब मैं एक बड़ी। Px फ़ाइल के साथ बचा हुआ हूँ जिसे मैं नहीं जानता कि कैसे छुटकारा पाऊँ।

मैंने सभी फ़ाइलों का उपयोग करके हटा दिया git rm -rf xxxxxxऔर मैंने --cachedविकल्प भी चलाया ।

क्या कोई मुझे बता सकता है कि मैं एक बड़ी। Pk फ़ाइल को कैसे निकाल सकता हूँ जो वर्तमान में निम्नलिखित निर्देशिका में है:

.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack

क्या मुझे अभी उस शाखा को हटाने की आवश्यकता है जो मेरे पास अभी भी है लेकिन अब मैं उपयोग नहीं कर रहा हूं? या कुछ और है जिसे मुझे चलाने की आवश्यकता है?

मुझे यकीन नहीं है कि इससे कितना फर्क पड़ता है लेकिन यह फाइल के खिलाफ एक पैडलॉक दिखाता है।

धन्यवाद


संपादित करें

यहाँ मेरे bash_history के कुछ अंश दिए गए हैं, जिनसे मुझे यह अंदाज़ा होना चाहिए कि मैं इस स्थिति में आने में कैसे कामयाब रहा (इस बिंदु पर मैं एक शाखा पर काम कर रहा हूँ जिसे 'माय-ब्रांच' कहा जाता है और मुझे एक फ़ोल्डर मिल गया है जिसमें अधिक फ़ोल्डर हैं / फ़ाइलें):

git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/     (not sure why I ran this as well but I did)

मैंने सोचा था कि मैं भी निम्नलिखित भाग गया लेकिन यह दूसरों के साथ bash_history में दिखाई नहीं देता:

git rm -rf --cached unwanted_folder/

मैंने यह भी सोचा था कि मैं git gcपैक फ़ाइल को साफ करने की कोशिश करने के लिए कुछ git कमांड्स (जैसे ) चलाता हूं, लेकिन वे .bash_history फ़ाइल में दिखाई नहीं देते हैं।


क्या आप स्पष्ट कर सकते हैं कि आपने उन्हें कैसे हटाया? यदि वे अभी भी प्रतिबद्ध इतिहास में हैं, तो वे अभी भी आपकी पैक फाइलों में हैं।
loganfsmyth

हाय @loganfsmyth, मैंने बैश इतिहास स्क्रिप्ट्स को जोड़ा है जो उम्मीद में मदद करेगा।
user1116573

जवाबों:


201

मुद्दा यह है कि भले ही आपने फ़ाइलों को हटा दिया हो, फिर भी वे पिछले संशोधनों में मौजूद हैं। यह पूरी बात है, यह है कि यदि आप कुछ हटाते हैं, तो भी आप इसे इतिहास तक पहुँच कर प्राप्त कर सकते हैं।

आप जो करना चाहते हैं, उसे पुनर्लेखन इतिहास कहा जाता है, और इसमें git filter-branchकमांड शामिल है ।

GitHub ने अपनी साइट पर इस मुद्दे की अच्छी व्याख्या की है। https://help.github.com/articles/remove-sensitive-data

अपने प्रश्न का अधिक सीधे उत्तर देने के लिए, आपको मूल रूप से चलाने की आवश्यकता है जो इस कमांड को unwanted_filename_or_folderउसी के अनुसार बदला गया है:

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch unwanted_filename_or_folder' --prune-empty

यह रेपो के सक्रिय इतिहास से फाइलों के सभी संदर्भों को हटा देगा।

अगला चरण, जीसी चक्र को निष्पादित करने के लिए फ़ाइल के सभी संदर्भों को समाप्त करने के लिए मजबूर करना और पैकफाइल से शुद्ध करना। इन कमांड में कुछ भी बदलने की जरूरत नहीं है।

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
# or, for older git versions (e.g. 1.8.3.1) which don't support --stdin
# git update-ref $(git for-each-ref --format='delete %(refname)' refs/original)
git reflog expire --expire=now --all
git gc --aggressive --prune=now

3
मैंने इसे इस रूप में स्वीकार कर लिया है कि अगर भविष्य में इस सवाल पर आने वाले किसी व्यक्ति के लिए यह आसान हो जाता है, हालांकि मैंने वास्तव में एक ताजा गिट रेपो बनाकर उस समय मेरी समस्या को हल किया
user1116573

3
मैं नहीं जानता कि आप कैसे इस के साथ आए लेकिन ... आप आदमी हैं। धन्यवाद।
यहेजकेल विक्टर

5
इस जवाब ने मुझे सही दिशा में इशारा किया। लेकिन असल में फ़ाइलों को हटाने के 3 और आदेशों की जरूरत है 1) git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin2) git reflog expire --expire=now --all3)git gc --prune=now
अरोद

3
मुझे bfgबहुत आसान लगता है। यह सरकारी गितुब
टिमो

2
@ टिमो नए जवाब जोड़ना अच्छा है, अगर समय के साथ चीजें बदल गई हैं। इसका लाभ उठाएं!
loganfsmyth

12

परिदृश्य A : यदि आपकी बड़ी फ़ाइलों को केवल एक शाखा में जोड़ा गया है, तो आपको चलाने की आवश्यकता नहीं है git filter-branch। आपको बस शाखा को हटाने और कचरा संग्रह चलाने की आवश्यकता है:

git branch -D mybranch
git reflog expire --expire-unreachable=all --all
git gc --prune=all

परिदृश्य बी : हालांकि, यह आपके बैश इतिहास के आधार पर दिखता है, कि आपने मास्टर में परिवर्तन को मर्ज किया था। यदि आपने परिवर्तनों को किसी के साथ साझा नहीं किया है ( git pushअभी तक नहीं)। सबसे आसान बात यह होगी कि बड़ी फ़ाइलों वाली शाखा के साथ मर्ज करने से पहले मास्टर को रीसेट करना होगा। यह आपकी शाखा से सभी कमिट्स को समाप्त कर देगा और मर्ज के बाद मास्टर किए गए सभी कमिट्स। तो हो सकता है कि आप बदलावों को खो दें - बड़ी फ़ाइलों के अलावा - जो आप वास्तव में चाहते थे:

git checkout master
git log # Find the commit hash just before the merge
git reset --hard <commit hash>

फिर परिदृश्य A से चरण चलाएँ।

परिदृश्य सी : यदि आप जिस शाखा को रखना चाहते हैं, उसके बाद शाखा से अन्य परिवर्तन या मास्टर में परिवर्तन हुए हैं, तो मास्टर को रिबेट करना सबसे अच्छा होगा और चुनिंदा तरीके से वे कमिटमेंट शामिल हैं जो आप चाहते हैं:

git checkout master
git log # Find the commit hash just before the merge
git rebase -i <commit hash>

अपने संपादक में, उन पंक्तियों को हटा दें जो बड़े फ़ाइलों को जोड़ने वाले कमिट के अनुरूप हैं, लेकिन बाकी सब कुछ जैसा है वैसा ही छोड़ दें। सेव करके छोड़ो। आपकी मास्टर शाखा में केवल वही होना चाहिए जो आप चाहते हैं, और कोई बड़ी फाइल नहीं। ध्यान दें कि इसके git rebaseबिना -pमर्ज के कमिट्स खत्म हो जाएंगे, इसलिए आपको बाद में मास्टर के लिए एक रैखिक इतिहास के साथ छोड़ दिया जाएगा <commit hash>। यह शायद आपके लिए ठीक है, लेकिन यदि नहीं, तो आप कोशिश कर सकते हैं -p, लेकिन git help rebaseकहते हैं combining -p with the -i option explicitly is generally not a good idea unless you know what you are doing

तब परिदृश्य A से आदेश चलाएँ।


वहाँ परिदृश्य एक का एक प्रकार है यहाँ के साथ, एक अतिरिक्त अनपेक्षित समस्या तथापि।

परिदृश्य ए ने एक अस्थायी खदान फ़ाइल की एक बड़ी राशि को हटाने के लिए, मेरी हल की हुई समस्या को हल किया। रिपॉजिटरी को एक बिल्ड सर्वर द्वारा प्रबंधित किया गया था और यह .गित / ऑब्जेक्ट्स / पैक फ़ोल्डर के अंदर अवांछित फ़ाइल निर्माण का कारण बनता है। मैं अपनी डिस्क से मूल्यवान जीबी को मुक्त कर सकता हूं।
xrissz

7

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

इतिहास से फाइलें हटाना

बीएफजी को उनकी वेबसाइट से डाउनलोड करें। सुनिश्चित करें कि आपके पास जावा स्थापित है, फिर एक दर्पण क्लोन और शुद्ध इतिहास बनाएं। YOUR_FILE_NAMEउस फ़ाइल के नाम से प्रतिस्थापित करना सुनिश्चित करें जिसे आप हटाना चाहते हैं:

git clone --mirror git://example.com/some-big-repo.git
java -jar bfg.jar --delete-files YOUR_FILE_NAME some-big-repo.git
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push

एक फ़ोल्डर हटाएँ

ऊपर के समान लेकिन उपयोग करें --delete-folders

java -jar bfg.jar --delete-folders YOUR_FOLDER_NAME some-big-repo.git

अन्य विकल्प

BFG इनकी तरह भी कट्टर विकल्प ( डॉक्स देखें ) के लिए अनुमति देता है :

इतिहास से 100M से बड़ी सभी फ़ाइलों को निकालें:

java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git

जरूरी!

जब बीएफजी चल रहा है, दोनों कि सावधान रहना होगा YOUR_FILE_NAMEऔर YOUR_FOLDER_NAMEवास्तव में सिर्फ फ़ाइल / फ़ोल्डर नाम हैं। वे रास्ते नहीं हैं , इसलिए कुछ foo/bar.jpgकाम नहीं करेगा! इसके बजाय निर्दिष्ट नाम वाली सभी फाइलों / फ़ोल्डरों को रेपो इतिहास से हटा दिया जाएगा, चाहे वे जिस भी पथ या शाखा में मौजूद हों।


मुझे आश्चर्य है कि अगर मैं इस bfgउपकरण को स्थानीय गिट रेपो में लागू करना चाहता हूं , तो कमांड को कैसे दिखना चाहिए?
एंजेल टोडोरोव

5

एक विकल्प:

git gcमैन्युअल रूप से एक या कुछ पैक फ़ाइलों में कई पैक फ़ाइलों को संघनित करने के लिए चलाएँ । यह ऑपरेशन लगातार है (यानी बड़े पैक की फाइल अपने संपीड़न व्यवहार को बनाए रखेगी) इसलिए समय-समय पर एक भंडार को संपीड़ित करना फायदेमंद हो सकता हैgit gc --aggressive

एक और विकल्प कोड को बचाने के लिए है। कहीं और। .िट को हटा दें और फिर से इस मौजूदा कोड का उपयोग करना शुरू करें, जिससे एक नया गिट रिपॉजिटरी ( git init) बनाया जा सके।


हाय माइकल, मैंने दौड़ने की कोशिश की git gcऔर सिर्फ एक-दो पैक फाइलों के लिए नीचे उतर गया, लेकिन बड़े वाले अभी भी उनमें से एक हैं और मैं इससे छुटकारा पाना चाहूंगा ताकि मैं फ़ोल्डर को बाहरी रूप से आसान बना सकूं (इससे पहले ज़िप 1) -2Mb, अब 55Mb)। जब तक कोई मुझे और कुछ नहीं सुझा सकता है, मुझे लगता है कि मुझे एक ताजा पकड़ बनानी पड़ सकती है। मुझे लगता है कि इसका मतलब है कि मैं उन शाखाओं तक पहुंच खो दूंगा जो वर्तमान में मेरे पास हैं ...?
user1116573

2
मैंने कोशिश करना छोड़ दिया और .it फ़ोल्डर को हटा दिया और जैसा आपने कहा था एक नया गिट रिपॉजिटरी बनाया। मैं इसे सबक सीखा हुआ समझूंगा। धन्यवाद माइकल।
user1116573

4
यह बहुत मतलब नहीं है। आप सिर्फ वर्तमान रिपॉजिटरी को समेकित करने और प्रक्रिया में पैक फ़ाइलों को हटाने के लिए गिट क्यों नहीं बता सकते हैं?
jml

4

निम्न कमांड को चलाएं, PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATAजिस फाइल को आप हटाना चाहते हैं, उसके पथ के साथ प्रतिस्थापित करना, न कि केवल इसका फ़ाइल नाम। ये तर्क देंगे:

  1. प्रक्रिया करने के लिए बाध्य करें, लेकिन जांच न करें, हर शाखा और टैग का पूरा इतिहास
  2. निर्दिष्ट फ़ाइल को निकालें, साथ ही परिणाम के रूप में उत्पन्न कोई भी खाली कमिट
  3. अपने मौजूदा टैग को अधिलेखित करें
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" --prune-empty --tag-name-filter cat -- --all

यह रेपो के सक्रिय इतिहास से फ़ाइलों के सभी संदर्भों को बलपूर्वक हटा देगा।

अगला चरण, जीसी चक्र को निष्पादित करने के लिए फ़ाइल के सभी संदर्भों को समाप्त करने और पैक फ़ाइल से शुद्ध करने के लिए मजबूर करने के लिए। इन कमांड में कुछ भी बदलने की जरूरत नहीं है।

git update-ref -d refs/original/refs/remotes/origin/master
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --prune=now

अंत में दूसरे भाग से मुझे 28M रेपो नीचे 158M मिला। Google पर लगभग कुछ और काम नहीं किया। धन्यवाद।
श्रीधर सरनोबत

मैंने उपरोक्त चरणों का पालन किया, और "git पुश ओरिजिन --force --all" के रूप में धकेल दिया और अभी भी मेरी दूरस्थ शाखाओं (मास्टर, डेवलप और फीचर / ASD-1010) को साफ नहीं किया। जब मैं रिमोट रेपो से ताज़गी देता था, तो .pack फाइलें अभी भी मौजूद थीं। मैं इस साफ को सभी दूरस्थ गिट शाखाओं को कैसे प्रतिबिंबित कर सकता हूं ??
साम्बित स्वैन

1

मैं शो के लिए थोड़ा लेट हो गया हूं, लेकिन यदि उपरोक्त उत्तर ने प्रश्न हल नहीं किया तो मुझे दूसरा रास्ता मिल गया। बस .pack से विशिष्ट बड़ी फ़ाइल को हटा दें। मेरे पास यह मुद्दा था जहां मैंने गलती से 2GB फ़ाइल में जाँच की थी। मैंने इस लिंक में बताए गए चरणों का पालन किया: http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/


इस विधि को करने के बाद यह परियोजना के पूरे इतिहास को पूरी तरह से हटा देगा, या यह केवल निर्दिष्ट फ़ाइल को हटा देगा।
समीम आफताब अहमद

-3

यह एक कोडिंग की तुलना में अधिक उपयोगी समाधान है। फ़ाइल को ज़िप करें। फ़ाइल दृश्य प्रारूप में ज़िप खोलें (अनज़िपिंग से अलग)। .Pack फ़ाइल हटाएँ। फ़ोल्डर को अनज़िप और बदलें। एक जादू की तरह काम करता है!

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