حذف فایل های بزرگ از گیت

مقدمه

در روزهای اولی که با git کار می‌کنیم ممکنه این اتفاق رخ بده که فایل‌هایی که نباید در مخزن گیت خودمون ذخیره کنیم رو کامیت کنیم. اگر بعد از این اتفاق اون فایل‌ها رو پاک کنیم و مجدد کامیت کنیم اون فایل‌ها از مخزن گیت ما حذف نمیشه و به عنوان تاریخچه اون مخزن همیشه باقی می‌مونه.

برای حل این مشکل راه‌های مختلفی وجود داره ولی تقریبا در همه اونها باید تاریخ رو در مخزن خودتون بازنویسی کنید.

بازنویسی تاریخ در مخزن گیت یعنی ویرایش کامیت‌های قدیمی.

یک راه حل برای رفع این مشکل استفاده از git-filter-branch است که به شما امکان تغییر در کامیت‌های گذشته رو می‌ده ولی ابزاری که من می‌خوام در موردش صحبت کنم BFG Repo-Cleaner است که یک فایل کوچک مبتنی بر ‍ java است که به شما کمک می‌کنه با سرعتی خیلی بیشتر (بین ۱۰ تا ۷۲۰ برابر به گفته خودش) و خیلی ساده‌تر به اون اهداف دست پیدا کنید.

در این مطلب من مایلم به صورت عملی یکی از پروژ‌ه‌های دوستانم که در زمینه کار با بودجه خانوار است و شامل فایل‌های اضافی هست رو بررسی کنم و فایل‌های اضافی را حذف کنم.

راه اندازی BFG Repo-Cleaner

برای استفاده از این نرم‌افزار باید JRE در سیستم عامل شما نصب باشه می‌تونید اینکار رو با پکیج منیجر سیستم‌عاملتون و یا با استفاده از این لینک انجام بدید.

$ sudo apt-get install default-jre# ubuntu
$ brew cask install java # mac

بعد از اون با اجرا دستور زیر نسخه جاوا نصب شده رو مشاهده می‌کنید:

$ java -version
java 17 2021-09-14 LTS
Java(TM) SE Runtime Environment (build 17+35-LTS-2724)
Java HotSpot(TM) 64-Bit Server VM (build 17+35-LTS-2724, mixed mode, sharing)

بعد از نصب جاوا باید نسخه نهایی BFG Repo-Cleaner رو از آدرس زیر دریافت کنید:

دانلود BFG Repo-Cleaner

دریافت مخزن گیتهاب و همه برنچ‌ها

برای اینکار باید مخزن خودتون رو با فلگ mirror دریافت کنید. این یک مخزن bare هست که در اون فایل‌های اصلی شما قابل مشاهده نیست ولی یک کپی کامل از دیتابیس گیت مخزن شماست.

$ git clone --mirror https://github.com/IPRCIRI/IRHEIS

در این مرحله خوبه که یک نسخه پشتبیان از مخزن خودتون ایجاد کنید تا در صورتی اشتباه کدهای اصلی شما سالم بمونند. در این مرحله می‌تونید فایل‌های بزرگ یا فایل‌های دیگه‌ای که به صورت اشتباه در مخزن اضافه شده است را حذف کنید.

حذف فایل‌های بزرگ از گیت

برای حذف فایل‌های بزرگ باید دستور زیر رو اجرا کنید.

$ java -jar bfg.jar --strip-blobs-bigger-than 10M IRHEIS.git

این دستور فایل‌های با حجم بیشتر از ۱۰ مگابایت رو حذف می کنه. با تغییر 10M به هر مقدار دیگه می‌نونیم حداقل حجم مورد نظر را تغییر بدیم.

بعد از اینکه فایل‌های مورد نظر حذف شد کافیه که به زباله‌گرد گیت دستور بدید که همه زباله‌های باقی مانده در این دیتابیس رو پاک کنه

$ cd IRHEIS.git
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive

حذف فایل‌های مشخص

در یکی از صحبت‌ها با دکتر عینیان که توسعه‌دهنده اصلی این مخزن بود به این نتیجه رسیدیم که به جای حذف ‌فایل‌های بزرگ همه فایل‌ها با پسوند‌های ‍‍‍xlsx csv rda png رو حذف کنیم.

برای اینکار BFG Repo-Cleaner دستور ‍‍--delete-files رو ارائه می‌کنه.

$ java -jar bfg.jar --delete-files "*.{xlsx,csv,rda,png}" IRHEIS.git

برای اینکار هم مجددا نیاز هست که از زباله‌گرد گیت کمک بگیریم.

$ cd IRHEIS.git
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive

انجام کارهای نهایی

اگر شما به پروژه دسترسی کامل داشته باشید تنها با پوش کردن کد خودتون می‌تونید کار رو خاتمه بدید. همه فایل‌های شما پاک شده و مخزن شما آماده استفاده است.

اگر مثل من به پروژه دسترسی نداشته باشید، باید یک fork ایجاد کنید و بعد از پوش کردن کد‌ها اون یک pull request به مخزن اصلی بفرستید.

بعد از اینکه به صورت کامل مرج شد، مخزن جدید هم تمیزتر از قبل آماده استفاده است.

برای مثال‌های بیشتر می‌تونید به وبسایت اصلی پروژه مراجعه کنید.

جمع‌بندی نهایی

بعد از پیاده‌سازی و حذف فایل‌ها حجم مخزن از ۳۲۰ مگابایات به ۴۴ مگابایت کاهش پیدا کرد. البته عمدا بخشی از فایل‌های دیتای مورد نیاز رو هم پاک کردیم که بعد از اضافه شدن شاید حداکثر ۵۰ مگابایت اضافه کند و با اون فرض اغراق آمیز هم حجم مخزن ۱/۳ شد.

برای هر پروژه‌ای ممکنه همچین مشکلاتی پیش بیاد بخصوص زمانی که هدف شما توسعه نرم‌افزار نباشه و کاربردها دیگه براتون مهم‌تر باشه.

خوشبختانه همیشه راه‌حل‌هایی برای اصلاح امور وجود داره ولی اگر فکر می‌کنید ممکنه بیش از پیش با گیت در ارتباط باشید توصیه می‌کنم که مجموعه ویدیو‌های آموزش گیت رو که در کانال یوتوبم گذاشتم رو ببینید.

و البته هیچ چیز به اندازه دنبال کردن و لایک کردن ویدیو‌ها در یوتوب من رو خوشحال نمی‌کنه :)