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


708

মাঝেমধ্যে আমি একটি ওয়েবসাইট প্রকল্পে একটি ডিভিডি-ফিপ ফেলেছি git commit -a -m ..., তারপরে অযত্নে এবং জ্যাপ করেছিলাম , রেপোটি ২.২ জিগ দ্বারা প্রস্ফুটিত হয়েছিল। পরের বার আমি কিছু সম্পাদনা করেছি, ভিডিও ফাইল মুছে ফেলেছি এবং সমস্ত প্রতিশ্রুতিবদ্ধ করেছি, তবে সংক্ষেপিত ফাইলটি এখনও ইতিহাসে আছে in

আমি জানি আমি সেই কমিটিগুলি থেকে শাখা শুরু করতে পারি এবং একটি শাখাটিকে অন্য একটি শাখায় পুনর্বাসিত করতে পারি। তবে 2 টি কমিটকে একত্রিত করার জন্য আমার কী করা উচিত যাতে বড় ফাইলটি ইতিহাসে প্রদর্শন না করে এবং আবর্জনা সংগ্রহের পদ্ধতিতে পরিষ্কার হয়?


9
এই নিবন্ধটি আপনাকে সহায়তার জন্য
এমবিও


1
মনে রাখবেন যে আপনার বড় ফাইলটি যদি কোনও সাবডিরে থাকে তবে আপনাকে সম্পূর্ণ আপেক্ষিক পথ নির্দিষ্ট করতে হবে।
জোহান

1
এছাড়াও সম্পর্কিত হেল্প.github.com/en/articles/…
ফ্রেডেরজ

বিএফজির নীচে থাকা অনেক উত্তর এর চেয়ে সহজ git filter-branch, তবে আমি এর বিপরীতটি সত্য বলে খুঁজে পেয়েছি।
2540625

উত্তর:


604

গিট ইতিহাস থেকে অযাচিত ফাইলগুলি সরিয়ে ফেলার জন্য বিশেষভাবে তৈরি করা সহজ, দ্রুত বিকল্প বিএফজি রেপো-ক্লিনার ব্যবহার করুন Usegit-filter-branch

সাবধানতার সাথে ব্যবহারের নির্দেশাবলী অনুসরণ করুন , মূল অংশটি এটি:

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

১০০ এমবি আকারের যে কোনও ফাইল (যা আপনার সর্বশেষ প্রতিশ্রুতিতে নেই) আপনার গিট সংগ্রহস্থলের ইতিহাস থেকে সরানো হবে। তারপরে আপনি git gcমৃত ডেটা পরিষ্কার করতে ব্যবহার করতে পারেন :

$ git gc --prune=now --aggressive

বিএফজি চলমানের চেয়ে কমপক্ষে 10-50x দ্রুত git-filter-branchএবং সাধারণত ব্যবহার করা সহজ।

সম্পূর্ণ প্রকাশ: আমি বিএফজি রেপো-ক্লিনার এর লেখক।


4
@ টোনি পুরো ক্লোনিং এবং ক্লিয়ারিংয়ের পদ্ধতিটি পুনরাবৃত্তি করার জন্য এটি আপনাকে দেখার উপযুক্ত বার্তাটি পুনরায় ঘটতে অনুরোধ করছে কিনা তা অবশ্যই দেখার বিষয়, তবে এটি প্রায় অবশ্যই কারণ আপনার দূরবর্তী সার্ভারটি নন-ফাস্ট-ফরোয়ার্ড আপডেটগুলি প্রত্যাখ্যান করার জন্য কনফিগার করা হয়েছে (যেমন, এটি আপনাকে থামাতে কনফিগার করা হয়েছে) ইতিহাস হারানো থেকে - যা আপনি ঠিক তেমন করতে চান)। আপনার সেটিংসটি রিমোটে পরিবর্তিত হওয়া বা এটির ব্যর্থ হওয়া দরকার, আপডেট হওয়া রেপো ইতিহাসকে একেবারে নতুন ফাঁকা রেপিতে ঠেলাও।
রবার্তো টাইলি

1
ধন্যবাদ আমি এটি 3 বার বিভিন্নবার চেষ্টা করেছি এবং সব একই বার্তায় ফলাফল পেয়েছি। সুতরাং আমি আরও ভাবছি যে আপনি দূরবর্তী সার্ভারটি নন-ফাস্ট-ফরোয়ার্ড আপডেটগুলি প্রত্যাখ্যান করার জন্য কনফিগার করা হচ্ছে ঠিক সে সম্পর্কে। আমি কেবলমাত্র আপডেট হওয়া রেপোটিকে একেবারে নতুন রেপোতে চাপ দেওয়ার কথা বিবেচনা করব। ধন্যবাদ!
টনি

7
@ রবার্তো টাইলি পারফেক্ট, আপনি আমার সময় বাঁচান, অনেক ধন্যবাদ। যাইহোক, git push --forceআপনার পদক্ষেপগুলি পরে করা উচিত , অন্যথায় দূরবর্তী রেপো এখনও পরিবর্তিত হয়নি।
li2

3
যোগ করতে +1 git push --force। লক্ষণীয় বিষয়: জোর ধাক্কা দূরবর্তী দ্বারা অনুমতি দেওয়া হতে পারে না (গিটল্যাব.কম, ডিফল্টরূপে। শাখাটি "অরক্ষিত" করতে হয়েছিল)।
ম্যাট্রিক্সম্যানএটিআইআরসেবা

25
আমি মনে করি ট্রাম্প জার্গনটি সরঞ্জাম আউটপুটগুলি অনেকটা বেশি।
ক্রিস

563

আপনি যদি অন্য বিকাশকারীদের কাছে ইতিহাস প্রকাশ করেন তবে আপনি যা করতে চান তা অত্যন্ত বিঘ্নজনক। আপনার ইতিহাসটি মেরামত করার পরে প্রয়োজনীয় পদক্ষেপগুলির জন্য ডকুমেন্টেশনে "আপস্ট্রিম রিবেস থেকে পুনরুদ্ধার"git rebase দেখুন ।

আপনার কাছে কমপক্ষে দুটি বিকল্প রয়েছে: git filter-branchএবং একটি ইন্টারেক্টিভ রিবেস, উভয় নীচে ব্যাখ্যা করা হয়েছে।

ব্যবহার git filter-branch

আমার একটি সাবভার্সিয়ন আমদানি থেকে বালি বাইনারি পরীক্ষার ডেটা নিয়ে একই রকম সমস্যা ছিল এবং গিট সংগ্রহস্থল থেকে ডেটা অপসারণ সম্পর্কে লিখেছিলাম ।

আপনার গিট ইতিহাসটি বলুন:

$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A     login.html
* cb14efd Remove DVD-rip
| D     oops.iso
* ce36c98 Careless
| A     oops.iso
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

মনে রাখবেন যে git lolaএটি একটি মানসম্মত নয় তবে অত্যন্ত উপকারী alias সঙ্গে --name-statusসুইচ, আমরা গাছ প্রতিটি কমিট সঙ্গে যুক্ত পরিবর্তন দেখতে পারেন।

"কেয়ারলেস" কমিট (যার SHA1 অবজেক্টের নাম ce36c98) ফাইলটি oops.isoহ'ল ডিভিডি- রিপটি দুর্ঘটনাক্রমে যুক্ত হয়েছিল এবং পরবর্তী কমিটে সরিয়ে দেওয়া হয়েছে, সিবি 14 ডিফডি। পূর্বোক্ত ব্লগ পোস্টে বর্ণিত কৌশলটি ব্যবহার করে, কার্যকর করার আদেশটি হ'ল:

git filter-branch --prune-empty -d /dev/shm/scratch \
  --index-filter "git rm --cached -f --ignore-unmatch oops.iso" \
  --tag-name-filter cat -- --all

বিকল্প:

  • --prune-emptyফিল্টার অপারেশনের ফলে খালি হয়ে যাওয়া ( যেমন গাছ পরিবর্তন করবেন না) প্রতিশ্রুতিগুলি সরান। সাধারণ ক্ষেত্রে, এই বিকল্পটি একটি ক্লিনার ইতিহাস তৈরি করে।
  • -dফিল্টার করা ইতিহাস নির্মাণের জন্য ব্যবহারের জন্য অস্থায়ী ডিরেক্টরিটির নাম দেয়। আপনি যদি কোনও আধুনিক লিনাক্স বিতরণ চালিয়ে যাচ্ছেন তবে একটি গাছ/dev/shm নির্দিষ্ট করে দেওয়ার ফলে দ্রুত কার্যকর হবে
  • --index-filterমূল ইভেন্ট এবং ইতিহাসের প্রতিটি পদক্ষেপে সূচকের বিরুদ্ধে চলে। oops.isoযেখানেই এটি পাওয়া যায় আপনি সরাতে চান তবে এটি সমস্ত কমিটিতে উপস্থিত নেই। কমান্ডটি git rm --cached -f --ignore-unmatch oops.isoডিভিডি-রিপ উপস্থিত থাকলে মুছে ফেলা হয় এবং অন্যথায় ব্যর্থ হয় না।
  • --tag-name-filterট্যাগের নামগুলি পুনরায় লেখার পদ্ধতি বর্ণনা করে। এর একটি ফিল্টার catহ'ল পরিচয় অপারেশন। উপরের নমুনার মতো আপনার ভান্ডারটিতে কোনও ট্যাগ নাও থাকতে পারে তবে আমি পুরো সাধারণতার জন্য এই বিকল্পটি অন্তর্ভুক্ত করেছি।
  • -- বিকল্পগুলির শেষটি নির্দিষ্ট করে git filter-branch
  • --allনিম্নলিখিত --সমস্ত refs জন্য সাধারণভাবে সংক্ষেপে হয়। আপনার সংগ্রহস্থল, উপরের নমুনার মতো, কেবলমাত্র একটি রেফ (মাস্টার) থাকতে পারে, তবে আমি সম্পূর্ণ সাধারণতার জন্য এই বিকল্পটি অন্তর্ভুক্ত করেছি।

কিছু মন্থন শেষে ইতিহাস এখন:

$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A     login.html
* e45ac59 Careless
| A     other.html
|
| * f772d66 (refs/original/refs/heads/master) Login page
| | A   login.html
| * cb14efd Remove DVD-rip
| | D   oops.iso
| * ce36c98 Careless
|/  A   oops.iso
|   A   other.html
|
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

লক্ষ্য করুন যে নতুন "কেয়ারলেস" কমিট কেবল যুক্ত করে other.htmlএবং "ডিভিডি-রিপ সরান" কমিট মাস্টার শাখায় আর নেই। refs/original/refs/heads/masterআপনি যদি ভুল করেন তবে লেবেলযুক্ত শাখায় আপনার মূল কমিট থাকে। এটিকে সরাতে, "একটি সংগ্রহস্থল সঙ্কুচিত করার জন্য চেকলিস্ট" এর ধাপগুলি অনুসরণ করুন

$ git update-ref -d refs/original/refs/heads/master
$ git reflog expire --expire=now --all
$ git gc --prune=now

একটি সহজ বিকল্পের জন্য, অযাচিত বিটগুলি বাতিল করতে ভাণ্ডারটি ক্লোন করুন।

$ cd ~/src
$ mv repo repo.old
$ git clone file:///home/user/src/repo.old repo

file:///...ক্লোন ইউআরএল ব্যবহার করে কেবল হার্ডলিঙ্ক তৈরি করার পরিবর্তে বস্তু অনুলিপি করা হয়।

এখন আপনার ইতিহাস:

$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A     login.html
* e45ac59 Careless
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

প্রথম দুটি কমিটের জন্য SHA1 অবজেক্টের নামগুলি ("সূচক" এবং "অ্যাডমিন পৃষ্ঠা") একই থাকায় কারণ ফিল্টার ক্রিয়াকলাপটি তাদের কমিটগুলিকে সংশোধন করেনি। "অমনযোগী" হারানো oops.isoএবং "লগইন পৃষ্ঠা", একটি নতুন পিতা বা মাতা পেয়েছিলাম ফলে তাদের SHA1s করেনি পরিবর্তন।

ইন্টারেক্টিভ রিবেস

এর ইতিহাস সহ:

$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A     login.html
* cb14efd Remove DVD-rip
| D     oops.iso
* ce36c98 Careless
| A     oops.iso
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

আপনি oops.iso"অযত্ন" থেকে সরাতে চান যদিও আপনি এটি কখনও যোগ করেন নি, এবং তারপরে "ডিভিডি-রিপ সরান" আপনার পক্ষে অকেজো। সুতরাং, আমাদের ইন্টারেক্টিভ রিবেসে যাওয়ার পরিকল্পনাটি হ'ল "অ্যাডমিন পৃষ্ঠা," সম্পাদনা "কেয়ারলেস" এবং "ডিভিডি-রিপ সরান" বাতিল করুন।

চলমান $ git rebase -i 5af4522নিম্নলিখিত বিষয়বস্তু দিয়ে একটি সম্পাদক শুরু করে।

pick ce36c98 Careless
pick cb14efd Remove DVD-rip
pick f772d66 Login page

# Rebase 5af4522..f772d66 onto 5af4522
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

আমাদের পরিকল্পনাটি কার্যকর করা হচ্ছে, আমরা এটিকে সংশোধন করি

edit ce36c98 Careless
pick f772d66 Login page

# Rebase 5af4522..f772d66 onto 5af4522
# ...

এটি হ'ল, আমরা "ডিভিডি-রিপ সরান" দিয়ে লাইনটি মুছুন এবং "কেয়ারলেস" এর editপরিবর্তে অপারেশনটি পরিবর্তন করুন pick

সম্পাদককে সংরক্ষণ-ছেড়ে দেওয়া নীচের বার্তা সহ কমান্ড প্রম্পটে আমাদের ফেলে দেয়।

Stopped at ce36c98... Careless
You can amend the commit now, with

        git commit --amend

Once you are satisfied with your changes, run

        git rebase --continue

বার্তাটি আমাদের যেমন বলেছে, আমরা সম্পাদনা করতে চাই এমন "অযত্ন" প্রতিশ্রুতিতে রয়েছি, সুতরাং আমরা দুটি কমান্ড চালাচ্ছি।

$ git rm --cached oops.iso
$ git commit --amend -C HEAD
$ git rebase --continue

প্রথমটি সূচক থেকে আপত্তিকর ফাইলটি সরিয়ে দেয়। দ্বিতীয়টি আপডেট হওয়া সূচকে "অযত্ন" পরিবর্তন করে বা সংশোধন করে এবং -C HEADপুরানো প্রতিশ্রুতি বার্তাটি পুনরায় ব্যবহার করতে গিটকে নির্দেশ দেয়। অবশেষে, git rebase --continueবাকি রিবেস অপারেশনটি নিয়ে এগিয়ে যায়।

এটি একটি ইতিহাস দেয়:

$ git lola --name-status
* 93174be (HEAD, master) Login page
| A     login.html
* a570198 Careless
| A     other.html
* 5af4522 Admin page
| A     admin.html
* e738b63 Index
  A     index.html

যা আপনি চান


4
গিট ফিল্টার-শাখা ব্যবহার করার সময় আমি কেন চাপ দিতে পারছি না, 'git@bitbucket.org: product / myproject.git' -র দিকে কিছু রেফ চাপাতে ব্যর্থ হয়েছি, আপনাকে ইতিহাস হারানো থেকে রক্ষা করতে, দ্রুত-অগ্রবর্তী আপডেটগুলি প্রত্যাখ্যান করা হয়েছিল রিমোটটি মার্জ করুন আবার ধাক্কা দেওয়ার আগে পরিবর্তন।
আগুং প্রসত্যও

11
যোগ -f(অথবা --force) আপনার বিকল্প git pushকমান্ড: "সাধারণত, কমান্ড একটি দূরবর্তী সুত্র যে স্থানীয় সেটি মুছে লিখতে ব্যবহৃত সুত্র একজন পূর্বপুরুষ নয় আপডেট করতে রাজি। এই পতাকা চেকটি অক্ষম করে। এর ফলে দূরবর্তী সংগ্রহস্থলটি কমিটগুলি হারাতে পারে; যত্ন সহকারে এটি ব্যবহার করুন। "
গ্রেগ বেকন

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

1
আমি উপরের যে কোনও প্রক্রিয়া করার পরে, রিমোট রিপোজিটরি (গিটহাবের উপরে) বড় ফাইলটি মুছবে না। কেবল স্থানীয় লোকজনই করেন। আমি জোর করে ধাক্কা দিয়েছি আর নাদা। আমি কী মিস করছি?
আজাতর

1
এটি ডায়ারগুলিতেও কাজ করে। ... "git rm --cached -rf --ignore-unmatch path/to/dir"...
rynop

198

এই সাধারণ কিন্তু শক্তিশালী কমান্ডটি ব্যবহার করবেন না কেন?

git filter-branch --tree-filter 'rm -f DVD-rip' HEAD

--tree-filterবিকল্প প্রকল্পের প্রতিটি চেকআউট পর নির্দিষ্ট কমান্ড রান এবং তারপর ফলাফল recommits। এই ক্ষেত্রে, আপনি প্রতিটি স্ন্যাপশট থেকে ডিভিডি-রিপ নামক একটি ফাইল সরিয়ে ফেলেন, এটি বিদ্যমান কিনা বা না থাকুক।

যদি আপনি জানেন যে কোন কমিটটি বিশাল ফাইলটি প্রবর্তন করেছে (বলুন 35dsa2), আপনি খুব বেশি ইতিহাসের পুনর্লিখন এড়াতে 35 ডিএসএ 2 সহ উচ্চতার সাথে প্রতিস্থাপন করতে পারেন ... এইভাবে আপনি যদি এখনও ঠেলাঠেলি না করেন তবে কমিটগুলি ডাইভারিং এড়ানো এড়াতে পারেন। @ আলফা_989 এর সৌজন্যে এই মন্তব্যটি এখানে ছেড়ে দেওয়া খুব গুরুত্বপূর্ণ বলে মনে হচ্ছে।

এই লিঙ্কটি দেখুন ।


3
এটি একটি ভাল সমাধান! আমি একটি গিস্ট তৈরি করেছি যা ফাইলগুলি তালিকাভুক্ত করার জন্য অজগর স্ক্রিপ্ট রয়েছে এবং গিট সিএমডি
পাঙ্কদাটা

5
বিএফজির চেয়ে অনেক বেশি ভাল। আমি bfg সঙ্গে একটি Git থেকে পরিষ্কার ফাইল করতে পারেনি, কিন্তু এই কমান্ড সাহায্য
podarok

4
এটা অসাধারণ. অন্যদের জন্য কেবল একটি নোট যে বড় ফাইল একাধিক শাখায় থাকলে আপনাকে এই শাখায় এই কাজটি করতে হবে।
জেমস

2
উইন্ডোজটিতে আমি পেয়েছি fatal: bad revision 'rm', যা আমি এর "পরিবর্তে ব্যবহার করে স্থির করেছি '। সামগ্রিক কমান্ড:git filter-branch --force --index-filter "git rm --cached -r --ignore-unmatch oops.iso" --prune-empty --tag-name-filter cat -- --all
মার্কোটামা

2
আপনি যদি commitফাইলটি কোথায় রেখেছেন (বলুন 35dsa2) জানেন তবে আপনি এটির HEADসাথে প্রতিস্থাপন করতে পারবেন 35dsa2..HEAD। এটি সমস্ত কমেটগুলি চেকআউট করে পুনরায় লেখার চেষ্টা করবে না তার tree-filterচেয়ে অনেক ধীর is index-filterআপনি যদি মাথা ব্যবহার করেন তবে এটি করার চেষ্টা করবে।
alpha_989

86

(আমি এই সমস্যার সবচেয়ে ভাল উত্তরটি দেখেছি: https://stackoverflow.com/a/42544963/714112 , গুগল অনুসন্ধানের র‌্যাঙ্কিংয়ে এই থ্রেডটি বেশি দেখা গেলেও এখানে অনুলিপি করা হয়েছে তবে অন্যটি তা করে না)

🚀 একটি নির্লজ্জভাবে দ্রুত শেল ওয়ান-লাইনার 🚀

এই শেল স্ক্রিপ্টটি ছোট থেকে বড় পর্যন্ত বাছাই করা সংগ্রহস্থলের সমস্ত ব্লব অবজেক্ট প্রদর্শন করে।

আমার নমুনা রেপোর জন্য, এটি এখানে পাওয়া অন্যান্যগুলির চেয়ে প্রায় 100 গুণ দ্রুত গতিতে চলেছে ।
আমার বিশ্বস্ত অ্যাথলন II এক্স 4 সিস্টেমটিতে এটি লিনাক্স কার্নেল সংগ্রহস্থলটি তার 5,622,155 টি অবজেক্টের সাথে এক মিনিটের মধ্যে পরিচালনা করে

বেস স্ক্রিপ্ট

git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ {print substr($0,6)}' \
| sort --numeric-sort --key=2 \
| cut --complement --characters=13-40 \
| numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

আপনি যখন কোডের উপরে চলে যান, আপনি ভাল মানব-পঠনযোগ্য আউটপুট পাবেন :

...
0d99bb931299  530KiB path/to/some-image.jpg
2ba44098e28f   12MiB path/to/hires-image.png
bd1741ddce0d   63MiB path/to/some-video-1080p.mp4

🚀 দ্রুত ফাইল অপসারণ 🚀

মনে করুন আপনি তারপরে ফাইলগুলি অপসারণ করতে aএবং bপ্রতিশ্রুতিবদ্ধ প্রতিটি কমিট থেকে HEAD, আপনি এই আদেশটি ব্যবহার করতে পারেন:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch a b' HEAD

3
যদি আপনার রেপোতে কোনও ট্যাগ থাকে তবে আপনি সম্ভবত --tag-name-filter catনতুন সংশ্লিষ্ট git filter-branch --index-filter 'git rm --cached --ignore-unmatch a b' --tag-name-filter cat HEAD
কমিটগুলি পুনরায় লেখার

3
ম্যাক নির্দেশাবলী এবং কিছু অন্যান্য তথ্য আসল লিঙ্কযুক্ত পোস্টে প্রদর্শিত হবে
55

3
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <filename>' HEADব্যাটের ডানদিকে ওয়ার্কর্ডার
ইলিজোনমার্ক

আমার প্রিয় উত্তর। ম্যাক ওএসে ব্যবহার করার জন্য একটি সামান্য ত্বক (gnu কমান্ড ব্যবহার করে)git rev-list --objects --all \ | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \ | awk '/^blob/ {print substr($0,6)}' \ | sort --numeric-sort --key=2 \ | gnumfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
ফ্লোরিয়ান ওসওয়াল্ড

রেভ-লিস্টের সাথে দুর্দান্ত স্ক্রিপ্ট তবে এটি আমার পক্ষে একটি উপাধিকার হিসাবে কাজ করে নি, কীভাবে করতে হবে কোনও ধারণা?
রবিন মনোলি

47

কার্যত প্রতিটি উত্তরের জন্য এসও-তে চেষ্টা করার পরে অবশেষে আমি এই রত্নটি খুঁজে পেয়েছিলাম যা দ্রুত আমার সংগ্রহস্থলের বড় ফাইলগুলি মুছে ফেলে এবং মুছে ফেলে এবং আমাকে আবার সিঙ্ক করার অনুমতি দেয়: http://www.zyxware.com/articles/4027/how-to-delete -files-স্থায়ীভাবে-থেকে-আপনার-স্থানীয়-এবং-দূরবর্তী-Git-ভান্ডার

আপনার স্থানীয় ওয়ার্কিং ফোল্ডারে সিডি করুন এবং নিম্নলিখিত কমান্ডটি চালান:

git filter-branch -f --index-filter "git rm -rf --cached --ignore-unmatch FOLDERNAME" -- --all

প্রদত্ত গিট সংগ্রহস্থল থেকে আপনি যে ফাইল বা ফোল্ডারটি সরাতে চান সেটির সাথে FOLDERNAME প্রতিস্থাপন করুন।

এটি শেষ হয়ে গেলে স্থানীয় সংগ্রহস্থলটি পরিষ্কার করার জন্য নিম্নলিখিত কমান্ডগুলি চালান:

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

দূরবর্তী সংগ্রহস্থলের সমস্ত পরিবর্তন এখন চাপুন:

git push --all --force

এটি দূরবর্তী সংগ্রহস্থল পরিষ্কার করবে।


আমার জন্য একটি কবজ মত কাজ।
রামন ভাসকনস্লোস

3
এটি আমার পক্ষেও কাজ করেছিল। সংগ্রহস্থলে একটি নির্দিষ্ট ফোল্ডার (আমার ক্ষেত্রে, ফাইলগুলির মধ্যে খুব বড় ফাইল বা একটি গিথুব রেপো থাকে) থেকে মুক্তি পাওয়া যায় তবে এটি উপস্থিত থাকলে স্থানীয় ফাইল সিস্টেমে রাখে।
skizzo

আমার জন্য কাজ! কোনও ইতিহাস অবশিষ্ট নেই যা সম্ভাব্য বিভ্রান্তিমূলক (যদি এখনই কেউ ক্লোন করবেন তবে) নিশ্চিত হয়ে নিন যে কোনও ভাঙা লিঙ্ক, নির্ভরতা ইত্যাদি আপডেট করার পরিকল্পনা আছে
রুহো রুটসি

38

এই আদেশগুলি আমার ক্ষেত্রে কাজ করেছে:

git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch oops.iso' --prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

এটি উপরের সংস্করণগুলির থেকে কিছুটা আলাদা।

যাঁদের এটি গিথুব / বিটবাকেটের দিকে ঠেলাতে হবে (আমি কেবল এটি বিটবাকেট দিয়ে পরীক্ষা করেছি):

# WARNING!!!
# this will rewrite completely your bitbucket refs
# will delete all branches that you didn't have in your local

git push --all --prune --force

# Once you pushed, all your teammates need to clone repository again
# git pull will not work

4
এটি উপরের থেকে কীভাবে আলাদা, এটি আরও ভাল কেন?
অ্যান্ডি হেডেন

1
কোনও কারণে mkljun সংস্করণটি আমার ক্ষেত্রে গিট স্থান হ্রাস পাচ্ছে না, আমি ইতিমধ্যে ব্যবহার করে সূচি থেকে ফাইলগুলি সরিয়েছি git rm --cached files। গ্রেগ বেকনের প্রস্তাবটি আরও সম্পূর্ণ, এবং এই খনিটির সাথেও সমান, তবে আপনি যখন একাধিকবার ফিল্টার-শাখা ব্যবহার করছেন তখন তিনি মামলাগুলির জন্য - ফোর্স সূচকটি মিস করেছেন এবং তিনি এত বেশি তথ্য লিখেছিলেন, আমার সংস্করণটি আবার শুরু হওয়ার মতো is এটা।
Kostanos

1
এটি সত্যই সহায়তা করেছে তবে নীচে @ lfender6445 অনুযায়ী পরিবর্তে আমার এখানে -fবিকল্পটি ব্যবহার করার দরকার ছিল-rfgit rm --cached -rf --ignore-unmatch oops.isogit rm --cached -r --ignore-unmatch oops.iso
drstevok

10

কেবল লক্ষ্য করুন যে এই আদেশগুলি খুব ধ্বংসাত্মক হতে পারে। আরও বেশি লোক যদি রেপোতে কাজ করে তবে তাদের সবাইকে নতুন গাছটি টানতে হবে। আপনার লক্ষ্যটি হ্রাস করতে না পারলে তিনটি মাঝারি কমান্ডের প্রয়োজন নেই। কারণ ফিল্টার শাখা সরানো ফাইলটির একটি ব্যাকআপ তৈরি করে এবং এটি সেখানে দীর্ঘ সময় থাকতে পারে।

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch YOURFILENAME" HEAD
$ rm -rf .git/refs/original/ 
$ git reflog expire --all 
$ git gc --aggressive --prune
$ git push origin master --force

11
আপনি নিজের জন্য প্রচুর ব্যথা তৈরি না করতে চাইলে এই আদেশগুলি চালাবেন না। এটি আমার মূল উত্স কোড ফাইলগুলি অনেকগুলি মুছে ফেলেছে। আমি ধরে নিয়েছি এটি জিআইটি-তে আমার প্রতিশ্রুতিবদ্ধ ইতিহাস থেকে কিছু বড় ফাইল মুছে ফেলবে (মূল প্রশ্ন অনুসারে) তবে, আমি মনে করি যে এই আদেশটি আপনার মূল উত্স কোড ট্রি (বড় পার্থক্য!) থেকে স্থায়ীভাবে ফাইলগুলি মুছে ফেলার জন্য তৈরি করা হয়েছে। আমার সিস্টেম: উইন্ডোজ, ভিএস ২০১২, গিট সোর্স কন্ট্রোল সরবরাহকারী।
কনটাঙ্গো

2
আমি এই আদেশটি ব্যবহার করেছি: git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch oops.iso' --prune-empty --tag-name-filter cat -- --allআপনার কোড থেকে প্রথমটির পরিবর্তে
Kostanos

9

git filter-branch --tree-filter 'rm -f path/to/file' HEAD আমার জন্য বেশ ভাল কাজ করেছে, যদিও আমি এখানে বর্ণিত একই সমস্যার মধ্যে দৌড়েছি , যা আমি এই পরামর্শটি অনুসরণ করে সমাধান করেছি ।

প্রো-গিট বইটির পুনর্লিখনের ইতিহাস সম্পর্কে একটি সম্পূর্ণ অধ্যায় রয়েছে - filter-branchপ্রতি প্রতিশ্রুতি বিভাগ থেকে / ফাইল সরানো সম্পর্কে একবার নজর দিন ।


8

আপনি যদি জানেন যে আপনার প্রতিশ্রুতিটি সাম্প্রতিক সময়ে পুরো গাছটি দিয়ে যাওয়ার পরিবর্তে নিম্নলিখিতটি করা উচিত: git filter-branch --tree-filter 'rm LARGE_FILE.zip' HEAD~10..HEAD


7

আমি এটি একটি বিটবুকিট অ্যাকাউন্ট দিয়ে ছুটে এসেছি, যেখানে আমি ঘটনাক্রমে আমার সাইটের জিনরমাস * .জেপা ব্যাকআপ সংরক্ষণ করেছি।

git filter-branch --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch MY-BIG-DIRECTORY-OR-FILE' --tag-name-filter cat -- --all

Relpace MY-BIG-DIRECTORYপ্রশ্নে ফোল্ডারের সাথে সম্পূর্ণরূপে আপনার ইতিহাস (পুনর্লিখন ট্যাগ সহ )।

উত্স: https://web.archive.org/web/20170727144429/http://naleid.com:80/blog/2012/01/17/finding-and-purging-big-files-from-git-history/


1
এই প্রতিক্রিয়াটি আমাকে সহায়তা করেছিল, উত্তরের স্ক্রিপ্টটি বাদে সামান্য সমস্যা রয়েছে এবং এটি আমাকে তৈরি করে সমস্ত শাখায় অনুসন্ধান করে না। তবে লিঙ্কের কমান্ডটি নিখুঁতভাবে এটি করেছে।
আলী বি

5

এটি আপনার ইতিহাস থেকে এটি সরিয়ে ফেলবে

git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch bigfile.txt' --prune-empty --tag-name-filter cat -- --all

এটি আমার জন্য ধন্যবাদ ধন্যবাদ !!
সোনজা ব্রিটিশ

এটি আমার ক্ষেত্রে কাজ করে। আমি আপনার মাস্টার শাখায় এটি চালাচ্ছি।
এস ডোমেং

4

আমি মূলত এই উত্তরে যা ছিল তা করেছি: https://stackoverflow.com/a/11032521/1286423

(ইতিহাসের জন্য, আমি এটি এখানে কপি-পেস্ট করব)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch YOURFILENAME" HEAD
$ rm -rf .git/refs/original/ 
$ git reflog expire --all 
$ git gc --aggressive --prune
$ git push origin master --force

এটি কাজ করে না, কারণ আমি জিনিসগুলির অনেক নাম পরিবর্তন এবং স্থানান্তর করতে পছন্দ করি। সুতরাং কিছু বড় ফাইল ফোল্ডারে ছিল যেগুলির নাম পরিবর্তন করা হয়েছে, এবং আমি মনে করি জিসি সেই ফাইলগুলির রেফারেন্স মুছে ফেলতে পারেনি কারণ সেই ফাইলগুলিতে treeনির্দেশিত বস্তুগুলিতে রেফারেন্স রয়েছে । এটি হত্যার আমার চূড়ান্ত সমাধানটি হ'ল:

# First, apply what's in the answer linked in the front
# and before doing the gc --prune --aggressive, do:

# Go back at the origin of the repository
git checkout -b newinit <sha1 of first commit>
# Create a parallel initial commit
git commit --amend
# go back on the master branch that has big file
# still referenced in history, even though 
# we thought we removed them.
git checkout master
# rebase on the newinit created earlier. By reapply patches,
# it will really forget about the references to hidden big files.
git rebase newinit

# Do the previous part (checkout + rebase) for each branch
# still connected to the original initial commit, 
# so we remove all the references.

# Remove the .git/logs folder, also containing references
# to commits that could make git gc not remove them.
rm -rf .git/logs/

# Then you can do a garbage collection,
# and the hidden files really will get gc'ed
git gc --prune --aggressive

আমার রেপো (দ্য .git) 32MB থেকে 388KB এ পরিবর্তিত হয়েছে, এমনকি ফিল্টার-শাখাটিও পরিষ্কার করতে পারেনি।


4

git filter-branchএটি একটি শক্তিশালী কমান্ড যা কমিটস ইতিহাস থেকে একটি বিশাল ফাইল মুছতে আপনি এটি ব্যবহার করতে পারেন। ফাইলটি কিছু সময়ের জন্য থাকবে এবং গিট এটি পরবর্তী আবর্জনা সংগ্রহের মধ্যে সরিয়ে ফেলবে। নীচে কমিটের ইতিহাস থেকে ফাইলগুলি মোছার সম্পূর্ণ প্রক্রিয়া রয়েছে । সুরক্ষার জন্য, নীচের প্রক্রিয়াটি প্রথমে একটি নতুন শাখায় কমান্ডগুলি চালায়। যদি ফলাফলটি আপনার প্রয়োজন মতো হয় তবে আপনি যে শাখায় পরিবর্তন করতে চান তা এটি পুনরায় সেট করুন।

# Do it in a new testing branch
$ git checkout -b test

# Remove file-name from every commit on the new branch
# --index-filter, rewrite index without checking out
# --cached, remove it from index but not include working tree
# --ignore-unmatch, ignore if files to be removed are absent in a commit
# HEAD, execute the specified command for each commit reached from HEAD by parent link
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch file-name' HEAD

# The output is OK, reset it to the prior branch master
$ git checkout master
$ git reset --soft test

# Remove test branch
$ git branch -d test

# Push it with force
$ git push --force origin master

2

গিট এক্সটেনশনগুলি ব্যবহার করুন , এটি একটি ইউআই সরঞ্জাম। এটিতে "বড় ফাইলগুলি অনুসন্ধান করুন" নামে একটি প্লাগইন রয়েছে যা ভান্ডারগুলিতে ল্যাজ ফাইলগুলি সন্ধান করে এবং এগুলিকে মারাত্মকভাবে সরানোর অনুমতি দেয়।

এই সরঞ্জামটি ব্যবহার করার আগে 'গিট ফিল্টার-শাখা' ব্যবহার করবেন না, যেহেতু এটি 'ফিল্টার-শাখা' দ্বারা সরানো ফাইলগুলি সন্ধান করতে সক্ষম হবে না (আল্টফের 'ফিল্টার-শাখা' রিপোজিটরি প্যাক ফাইলগুলি থেকে ফাইলগুলি পুরোপুরি সরিয়ে দেয় না) ।


বৃহত সংগ্রহস্থলের জন্য এই পদ্ধতিটি খুব ধীর। বড় ফাইলগুলি তালিকা করতে এক ঘন্টা সময় নিয়েছে। তারপরে আমি যখন ফাইলগুলি মুছতে যাই, এক ঘন্টা পরে প্রথম ফাইলটি মুছতে চাইলে প্রক্রিয়াজাতকরণের মাধ্যমে এটি কেবল 1/3 উপায়।
ক্রিস্টিয়ানপ

হ্যাঁ, এটি ধীর, তবে কাজটি করছে ... আপনি কি দ্রুত কিছু জানেন?
নীড়

1
এই পৃষ্ঠায় অন্য উত্তর অনুসারে এটি ব্যবহার করা হয়নি, তবে বিএফজি রেপো-ক্লিনার।
ক্রিশ্চিয়ানপ

2

আপনি branch filterকমান্ডটি ব্যবহার করে এটি করতে পারেন :

git filter-branch --tree-filter 'rm -rf path/to/your/file' HEAD


2

এই থ্রেডে খুব ভাল উত্তর রয়েছে তবে এর মধ্যে তাদের মধ্যে অনেকগুলি পুরানো। ব্যবহার git-filter-branchআর বাঞ্ছনীয়, কারণ এটি ব্যবহার করতে কঠিন এবং অতিশয় বড় ভান্ডার উপর ধীর।

git-filter-repo ব্যবহার করা অনেক দ্রুত এবং সহজ।

git-filter-repoপাইথন স্ক্রিপ্ট, গিথুব এ উপলব্ধ: https://github.com/newren/git-filter-repo

আপনার কেবল একটি ফাইল দরকার: পাইথন 3 স্ক্রিপ্ট গিট-ফিল্টার-রেপো। PATH ভেরিয়েবলের অন্তর্ভুক্ত এমন কোনও পথে এটি অনুলিপি করুন। উইন্ডোজে আপনাকে স্ক্রিপ্টের প্রথম লাইনটি পরিবর্তন করতে হতে পারে (INSTALL.md দেখুন)। আপনার সিস্টেমে পাইথন 3 ইনস্টলড থাকা দরকার তবে এটি কোনও বড় বিষয় নয়।

প্রথমে আপনি চালাতে পারেন

git filter-repo --analyze

এটি আপনাকে পরবর্তী কী করতে হবে তা নির্ধারণ করতে সহায়তা করে।

আপনি আপনার ডিভিডি-রিপ ফাইলটি যে কোনও জায়গায় মুছতে পারেন:

 git filter-repo --invert-paths --path-match DVD-rip

ফিল্টার-রেপো সত্যিই দ্রুত। ফিল্টার-শাখা দ্বারা আমার কম্পিউটারে প্রায় 9 ঘন্টা সময় নিয়ে যাওয়া একটি কাজ, ফিল্টার-রেপো দ্বারা 4 মিনিটের মধ্যে শেষ হয়েছিল। আপনি ফিল্টার-রেপো সহ আরও অনেক দুর্দান্ত জিনিস করতে পারেন। তার জন্য ডকুমেন্টেশন দেখুন।

সতর্কতা: আপনার ভাণ্ডারের অনুলিপিটিতে এটি করুন। ফিল্টার-রেপোর অনেক ক্রিয়া পূর্বাবস্থায় ফেরা যায় না। ফিল্টার-রেপো সমস্ত পরিবর্তিত কমিট (অবশ্যই) এবং তাদের সমস্ত বংশধরদের কমিটকে শেষ কমিটে পরিবর্তন করবে!


1

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

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

আমি একসাথে রেখেছি git forget-blob, একটি ছোট স্ক্রিপ্ট যা এই সমস্ত রেফারেন্সগুলি মুছে ফেলার চেষ্টা করে এবং তারপরে শাখায় প্রতিটি কমিট পুনর্লিখনের জন্য গিট ফিল্টার-শাখা ব্যবহার করে।

আপনার ব্লবটি সম্পূর্ণরূপে অবাস্তব হয়ে গেলে, git gcএটি থেকে মুক্তি পাবেন

ব্যবহার খুব সহজ git forget-blob file-to-forget। আপনি এখানে আরও তথ্য পেতে পারেন

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

স্ট্যাক ওভারফ্লো এবং কিছু ব্লগ এন্ট্রি থেকে উত্তরগুলির জন্য আমি এটি একসাথে রেখেছি। তাদের ক্রেডিট!


আপনার এটি হোমব্রিউতে পাওয়া উচিত
ক্যামেরন ই

0

অন্য git filter-branch(ধীর কিন্তু বিশুদ্ধ Git সমাধান) এবং BFG (সহজ এবং খুব performant), এছাড়াও আছে ভাল পারফরম্যান্সের সঙ্গে ফিল্টার আরেকটি টুল:

https://github.com/xoofx/git-rocket-filter

এর বর্ণনা থেকে:

git-filter-branchনিম্নলিখিত অনন্য বৈশিষ্ট্য সরবরাহ করার সময় গিট-রকেট-ফিল্টারের উদ্দেশ্য কমান্ডের সাথে সমান :

  • কমিটস এবং গাছগুলির দ্রুত পুনর্লিখন (এক্স 10 থেকে এক্স 100 এর আদেশ অনুসারে)।
  • - সংরক্ষণের ফাইল (ডিরেক্টরি বা ফাইল রাখে) এবং সাদা রঙের তালিকা - রিমুভ বিকল্পগুলির সাহায্যে উভয়ের জন্য অন্তর্নির্মিত সমর্থন।
  • গাছ-ফিল্টারিংয়ের জন্য প্যাটার্নের মতো .gitignore ব্যবহার করুন
  • কমিট ফিল্টারিং এবং ট্রি ফিল্টারিং উভয়ের জন্য দ্রুত এবং সহজ সি স্ক্রিপ্টিং
  • প্রতি ফাইল / ডিরেক্টরি প্যাটার্নে ট্রি-ফিল্টারিংয়ে স্ক্রিপ্টিংয়ের জন্য সমর্থন
  • মার্জ কমিটগুলি সহ খালি / অপরিবর্তিত প্রতিশ্রুতি স্বয়ংক্রিয়ভাবে ছাঁটাই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.