এটি করার একটি উপায় হ'ল বিপরীতমুখী - আপনি যে ফাইলটি রাখতে চান সেই ফাইলটি বাদ দিয়ে সবকিছু সরিয়ে দিন।
মূলত, সংগ্রহস্থলের একটি অনুলিপি তৈরি করুন, তারপরে git filter-branch
আপনি যে ফাইল / ফোল্ডার রাখতে চান তা বাদ দিয়ে সমস্ত কিছু সরিয়ে ফেলুন।
উদাহরণস্বরূপ, আমার একটি প্রকল্প রয়েছে যা থেকে আমি ফাইলটি tvnamer.py
একটি নতুন সংগ্রহস্থলে বের করতে চাই :
git filter-branch --tree-filter 'for f in *; do if [ $f != "tvnamer.py" ]; then rm -rf $f; fi; done' HEAD
এটি git filter-branch --tree-filter
প্রতিটি প্রতিশ্রুতিবদ্ধ হওয়া, কমান্ড চালানো এবং ফলাফলের ডিরেক্টরি সামগ্রী পুনরায় স্বীকার করতে ব্যবহার করে। এটি অত্যন্ত ধ্বংসাত্মক (যাতে আপনার ভাণ্ডারের অনুলিপিটিতে কেবল এটি করা উচিত!) এবং কিছুক্ষণ সময় নিতে পারে (300 টি কমিট এবং প্রায় 20 টি ফাইল সহ একটি সংগ্রহস্থলের প্রায় 1 মিনিট)
উপরের কমান্ডটি প্রতিটি সংশোধনীর জন্য নিম্নলিখিত শেল-স্ক্রিপ্টটি চালিত করে, যা আপনাকে অবশ্যই সংশোধন করতে হবে (এটির পরিবর্তে এটি আপনার সাব ডিরেক্টরিটি বাদ দিতে tvnamer.py
):
for f in *; do
if [ $f != "tvnamer.py" ]; then
rm -rf $f;
fi;
done
সবচেয়ে বড় স্পষ্ট সমস্যা হ'ল এটি সমস্ত প্রতিশ্রুতিবদ্ধ বার্তাগুলি ছেড়ে দেয়, যদিও তারা বাকী ফাইলের সাথে সম্পর্কিত না হয়। স্ক্রিপ্ট গিট-রিমুভ-খালি-কমিট করে , এটি ঠিক করে দেয় ..
git filter-branch --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; fi'
আপনাকে যে কোনও কিছু দিয়ে আবার -f
বল প্রয়োগ করতে হবে (মূলত এটি একটি ব্যাকআপ)filter-branch
refs/original/
অবশ্যই এটি কখনই নিখুঁত হতে পারে না, উদাহরণস্বরূপ, যদি আপনার প্রতিশ্রুতিবদ্ধ বার্তাগুলি অন্য ফাইলগুলি উল্লেখ করে তবে এটি প্রায় একটি গিট কারেন্টের অনুমতি দেয় (যতদূর আমি সচেতন থাকি))
আবার, কেবল আপনার সংগ্রহশালার অনুলিপিটিতে এটি চালান! - তবে সংক্ষেপে, সমস্ত ফাইল অপসারণ করতে "thisismyfilename.txt":
git filter-branch --tree-filter 'for f in *; do if [ $f != "thisismyfilename.txt" ]; then rm -rf $f; fi; done' HEAD
git filter-branch -f --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; fi'