গিট / গিটহাবের ইতিহাস থেকে ফোল্ডার এবং এর সামগ্রীগুলি সরিয়ে ফেলুন


318

আমি আমার গিটহাব অ্যাকাউন্টে একটি সংগ্রহস্থলের কাজ করছিলাম এবং এটি হ'ল সমস্যা।

  • নোড.জেএস প্রকল্পে একটি ফোল্ডার সহ কয়েকটি এনপিএম প্যাকেজ ইনস্টল করা আছে
  • প্যাকেজগুলি node_modulesফোল্ডারে ছিল
  • Folder ফোল্ডারটি গিট রিপোজিটরিতে যুক্ত করা হয়েছে এবং কোডটি গিথুবকে ঠেলে দিয়েছে (সেই সময় এনপিএম অংশের বিষয়ে ভাবেননি)
  • অনুধাবন করা হয়েছে যে কোডটির একটি অংশ হওয়ার জন্য আপনার অবশ্যই সেই ফোল্ডারটির দরকার নেই
  • এই ফোল্ডারটি মোছা হয়েছে, এটি ধাক্কা দিয়েছে

সেই সময়ে, মোট গিট রেপোর আকার প্রায় 6MB ছিল যেখানে আসল কোডটি (সেই ফোল্ডার বাদে সমস্তটি ) কেবলমাত্র 300 কেবি এর কাছাকাছি ছিল ।

এখন আমি শেষ পর্যন্ত যা খুঁজছি তা হ'ল গিটের ইতিহাস থেকে সেই প্যাকেজ ফোল্ডারের বিশদ থেকে মুক্তি পাওয়ার উপায় যদি কেউ এটি ক্লোন করেন তবে তাদের 6 এমবি মূল্যবান ইতিহাস ডাউনলোড করতে হবে না যেখানে কেবল আসল ফাইলগুলি তারা পাবে শেষ প্রতিশ্রুতি হিসাবে 300KB হবে।

আমি এর জন্য সম্ভাব্য সমাধানগুলি সন্ধান করেছি এবং এই 2 টি পদ্ধতির চেষ্টা করেছি

গিস্টটি দেখে মনে হয়েছিল এটি স্ক্রিপ্ট চালানোর পরে এটি যেখানে কাজ করেছিল, এটি দেখিয়েছিল যে এটি সেই ফোল্ডারটি থেকে মুক্তি পেয়েছে এবং তারপরে এটি দেখিয়েছে যে 50 টি পৃথক কমিট সংশোধিত হয়েছিল। তবে এটি আমাকে কোডটি ঠেকাতে দেয়নি। আমি যখন এটির দিকে চাপ দেওয়ার চেষ্টা করেছি, তখন এটি বলেছিল Branch up to dateতবে এটি দেখিয়েছিল যে একটিতে 50 টি কমিট সংশোধিত হয়েছিল git status। অন্যান্য 2 টি পদ্ধতিও সাহায্য করে নি।

এখন যদিও এটি দেখিয়েছে যে এটি folder ফোল্ডারের ইতিহাস থেকে মুক্তি পেয়েছে, যখন আমি আমার লোকালহোস্টে rep রেপোর আকারটি যাচাই করেছি, এটি এখনও প্রায় 6MB এর কাছাকাছি ছিল। (আমি refs/originalফোল্ডারটিও মুছলাম কিন্তু রেপোর আকারের পরিবর্তন দেখতে পাইনি)।

আমি যে বিষয়টি স্পষ্ট করতে চাইছি তা হ'ল, যদি কেবল প্রতিশ্রুতিবদ্ধ ইতিহাস না থেকে মুক্তি পাওয়ার উপায় থাকে (যা আমি মনে করি কেবল এটি ঘটেছে) তবে সেই ফাইলগুলি গিটও ধরে নিচ্ছে যে কেউ রোলব্যাক করতে চায়।

এর জন্য একটি সমাধান উপস্থাপন করা হয়েছে এবং এটি আমার লোকালহোস্টে প্রয়োগ করা হয়েছে তবে সেই গিথহাব রেপোতে পুনরুত্পাদন করা যায় না, এটি কি রেপো ক্লোন করা সম্ভব, প্রথম প্রতিশ্রুতিবদ্ধ রোলব্যাকটি কৌশলটি সম্পাদন করে এবং এটি ধাক্কা দেয় (বা এর অর্থ এই যে গিটটি হবে এখনও সেই সমস্ত কমিটের ইতিহাস রয়েছে? - ওরফে 6 এমবি)।

আমার এখানে শেষ লক্ষ্যটি হ'ল গিটটি থেকে ফোল্ডার সামগ্রীগুলি থেকে মুক্তি পাওয়ার সর্বোত্তম উপায়টি সন্ধান করা যাতে কোনও ব্যবহারকারীকে 6 এমবি মূল্যের জিনিসপত্র ডাউনলোড করতে না হয় এবং সম্ভবত অন্যান্য কমিটগুলি কখনও কখনও মডিউলগুলির ফোল্ডারে স্পর্শ না করে (এটি খুব সুন্দর) গিটের ইতিহাসে অনেকগুলি)।

কিভাবে আমি এটি করতে পারব?


3
নীচের উত্তরের যে কোনও উত্তর যদি আপনার সমস্যার সমাধান করে তবে সম্ভবত আপনার প্রশ্নের উত্তর হিসাবে সেটিকে গ্রহণ করার বিষয়টি বিবেচনা করা উচিত। meta.stackexchange.com/questions/5234/…
স্টারবিয়াম্রেনবোলাবস

: সেরা উত্তর stackoverflow.com/a/32886427/5973334
Kuzeko

উত্তর:


556

আপনি যদি এখানে কপি-পেস্ট কোড করতে পারেন:

এটি 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

গিট আসলে কী করে:

--tree-filterকমান্ডটি চালনা করে প্রথম পংক্তিটি হাইড (আপনার বর্তমান শাখা) হিসাবে একই গাছের ( ) একই গাছের সমস্ত রেফারেন্সের মাধ্যমে পুনরায় হয় rm -rf node_modules। এই কমান্ডটি নোড_মডিউলগুলি ফোল্ডার মুছে ফেলবে ( -rছাড়া -r, rmফোল্ডারগুলি মুছবে না), ব্যবহারকারীকে কোনও প্রম্পট দেওয়া হয়নি ( -f)। যুক্ত --prune-emptyমুছে ফেলা নিষ্ক্রিয় (কিছুই পরিবর্তন না) পুনরাবৃত্তিতে কমিট করে।

দ্বিতীয় লাইনটি সেই পুরানো শাখার রেফারেন্স মুছে দেয়।

বাকি কমান্ডগুলি অপেক্ষাকৃত সহজবোধ্য।


3
শুধু একটি পার্শ্ব নোট: আমি ব্যবহার git count-objects -v ফাইলগুলি আসলে অপসারণ করা হয়েছে কিনা তা পরীক্ষা করে তবে আমি পুনরায় সংগ্রহস্থলটি ক্লোন না করা পর্যন্ত সংগ্রহের আকার একই থাকে। গিট আমার মনে হয় এমন সমস্ত মূল ফাইলের একটি অনুলিপি তৈরি করে।
ডেভিড ইকার্দি

4
একটি প্রাচীন-প্রাচীন গিট সঙ্গে, এটি সম্ভবত পড়া উচিত --force-with-lease, না --force
গ্রুইস

4
এই কমান্ডগুলির কোনওটি উইন্ডোতে কাজ করে না। বা কমপক্ষে উইন্ডোজ 10 নয়, দয়া করে ওএস পোস্ট করুন যা "কাট এবং পেস্ট করুন" কাজ করে
ডেভিড

3
উইন্ডোজ 10 ব্যবহারকারীদের জন্য, এটি উইন্ডোজের জন্য বাশের অধীনে দুর্দান্তভাবে কাজ করে (আমি উবুন্টু ব্যবহার করেছি)
আন্দ্রেজ কিসেলিকা

3
আমি এটি উইন্ডোজ শেল এবং গিট ব্যাশ দিয়ে চেষ্টা করেছি, এবং কাজ করে নি। প্রথম কমান্ড পাস, দ্বিতীয় কমান্ড ব্যর্থ!
মোহি এল্ডিন

240

আমি দেখতে পেয়েছি যে --tree-filterঅন্যান্য উত্তরে ব্যবহৃত বিকল্পটি খুব ধীর হতে পারে, বিশেষত প্রচুর কমিটের সাহায্যে বৃহত সংগ্রহস্থলগুলিতে।

--index-filterঅপশনটি ব্যবহার করে গিটের ইতিহাস থেকে ডিরেক্টরিটি সম্পূর্ণরূপে অপসারণ করার জন্য আমি এই পদ্ধতিটি ব্যবহার করি , যা আরও দ্রুত চালিত হয়:

# 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

3
এত দ্রুত কেন আপনি ব্যাখ্যা করতে পারেন?
নোকট

7
@knocte: ডক্স থেকে ( git-scm.com/docs/git-filter- ব্র্যাঞ্চ )। "- ইন্ডেক্স-ফিল্টার: ... গাছের ফিল্টারের মতোই তবে গাছটি চেক আউট করে না, যা এটি আরও দ্রুত করে তোলে"
লী নেদার্তন

23
কেন এটি গৃহীত উত্তর নয়? এটি এত পুঙ্খানুপুঙ্খ।
ম্যাড পদার্থবিদ

2
উইন্ডোতে যদি এটি করা হয় তবে আপনার একক উদ্ধৃতির পরিবর্তে ডাবল উদ্ধৃতি প্রয়োজন।
ক্রিস মর্নেস

12
পাসিং --quietকরতে git rmফ্যাক্টর 4. দ্বারা অন্তত আমার লেখা উপরে আপ sped
ctusch

46

উপরের জনপ্রিয় উত্তরের পাশাপাশি আমি উইন্ডোজ- সিস্টেমগুলির জন্য কয়েকটি নোট যুক্ত করতে চাই । আদেশ

git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
  • কোনও পরিবর্তন ছাড়াই পুরোপুরি কাজ করে ! অতএব, আপনি অবশ্যই ব্যবহার করা উচিত নয়Remove-Item , delবা অন্য কিছু পরিবর্তে rm -rf

  • আপনি একটি ফাইল বা ডিরেক্টরির ব্যবহার করার একটা ঝোঁক পাথ নির্দিষ্ট করার প্রয়োজন হলে স্ল্যাশ মত./path/to/node_modules


ডিরেক্টরিতে যদি একটি থাকে তবে এটি উইন্ডোজে কাজ করবে না। (বিন্দু) নামে।
কর্নেলিউ সেরেডিয়ুক 11

4
এবং আমি সমাধানটি খুঁজে পেয়েছি। Rm কমান্ডের জন্য ডাবল ইনভার্টেড-কমা ব্যবহার করুন: "rm -rf নোড.মডিউলস"।
কর্নেলিউ সেরেডিয়ুক

23

আমি খুঁজে পাওয়া সবচেয়ে সেরা এবং সবচেয়ে সঠিক পদ্ধতিটি ছিল bfg.jar ফাইলটি ডাউনলোড করা: https://rtyley.github.io/bfg-repo-cleaner/

তারপরে কমান্ডগুলি রান করুন:

git clone --bare https://project/repository project-repository
cd project-repository
java -jar bfg.jar --delete-folders DIRECTORY_NAME  # i.e. 'node_modules' in other examples
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
খুব সহজ :) আপনি যে শুধুমাত্র একটি নির্দিষ্ট ফোল্ডারের মুছে ফেলা হবে, এই ইচ্ছার সাহায্যের নিশ্চিত কর করতে চান: stackoverflow.com/questions/21142986/...
emjay

8

এটি প্রদর্শিত হয় যে এর আপ-টু-ডেট উত্তরটি সরাসরি ব্যবহার নাfilter-branch করা (অন্তত গিট নিজেই এটির আর সুপারিশ করে না), এবং এটি কোনও বাহ্যিক সরঞ্জামে স্থগিত করে। বিশেষত, গিট-ফিল্টার-রেপো বর্তমানে প্রস্তাবিত। এই সরঞ্জামটির লেখক যুক্তি সরবরাহ করে কেন filter-branchসরাসরি ব্যবহার করে সমস্যার দিকে পরিচালিত করতে পারে সে সম্পর্কে করে ।

dirইতিহাস থেকে মুছে ফেলার জন্য উপরের মাল্টি-লাইন স্ক্রিপ্টগুলির বেশিরভাগগুলি আবার এইভাবে লিখিত হতে পারে:

git filter-repo --path dir --invert-paths

স্পষ্টতই, সরঞ্জামটি আরও শক্তিশালী। আপনি লেখক, ইমেল, পুনর্নবীকরণ এবং আরও অনেক কিছু দ্বারা সম্পূর্ণ ফিল্টার প্রয়োগ করতে পারেন ( সম্পূর্ণ ম্যানপেজ এখানে )। তদতিরিক্ত, এটি দ্রুত । ইনস্টলেশন সহজ - এটি বিভিন্ন ফর্ম্যাটে বিতরণ করা হয়


দুর্দান্ত সরঞ্জাম! উবুন্টু ২০.০৪-তে ভাল কাজ করে, আপনি কেবল pip3 install git-filter-repoস্টেডলিব-ও কোনও নির্ভরতা ইনস্টল না করেই পারেন। উবুন্টু 18 এ এটি ডিস্ট্রোর গিট সংস্করণের সাথে বেমানান Error: need a version of git whose diff-tree command has the --combined-all-paths option, তবে এটি চালানো যথেষ্ট সহজdocker run -ti ubuntu:20.04
kubanczyk

7

সম্পূর্ণ অনুলিপি এবং পেস্টের রেসিপি, কেবলমাত্র মন্তব্যে (অনুলিপি-পেস্ট সমাধানের জন্য) যুক্ত করে তাদের পরীক্ষা করার পরে:

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

এর পরে, আপনি .gitignore থেকে "নোড_মডিউল /" লাইনটি সরাতে পারেন


তাহলে কেন আপনি সরিয়ে node_modulesফেলবেন .gitignore? যাতে তারা দুর্ঘটনাক্রমে আবার সংঘবদ্ধ হতে পারে ??
অ্যাডামস্কি

1
এটি গিটিগনোর থেকে সরানো হয় না, এটি গিটিগনোরতে যুক্ত হয়। প্রতিশ্রুতিবদ্ধ বার্তাটি "গিট ইতিহাস" বলেছে, "গিটিগনোর" নয় :) :)
ড্যানি টুপেনি

কিন্তু মন্তব্য বলছেন যে তোমরা অপসারণ করতে পারেন node_modulesথেকে .gitignore
জাভর

7

উইন্ডোজ ব্যবহারকারীর জন্য, দয়া করে অন্য কোনও ব্যাকআপ ইতিমধ্যে উপস্থিত থাকলে কমান্ডটি জোর করে যুক্ত করার "পরিবর্তে ব্যবহার করার জন্য নোট করুন ।'-f

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

3

আমি উইন্ডোতে গিট ব্যবহার করে পুরানো সি # প্রকল্পগুলি থেকে বিন এবং আপত্তি ফোল্ডারগুলি সরিয়েছি। সতর্কতার সহিত

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

এটি গিট ইনস্টল ফোল্ডারে ইউএসআর / বিন ফোল্ডারটি মোছার মাধ্যমে গিট ইনস্টলেশনটির অখণ্ডতা নষ্ট করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.