تنظيف Git history الجزء 2

البيانات الحساسة أو استهلاك الكثير من الذاكرة: هناك أسباب وجيهة تريد تغيير محفوظات Git. في منشور المدونة هذا ، أوضحت كيفية مسح الملفات من سجل Git باستخدام BFG . تتمثل إحدى نقاط الضعف في BFG في عدم وجود دعم للمسارات المباشرة ، لذلك لا يمكنك على وجه التحديد إزالة الملفات أو المجلدات الموجودة في المجلدات الفرعية من السجل. مع ذلك ، حان الوقت للبحث عن حلول بديلة.


بالإضافة إلى فرع مرشح git غير الموصى به رسميًا ، يعد git-filter-repo أحد الأدوات لتنظيف السجل. بعد تثبيت قصير ، نقوم أولاً بتحليل المستودع والعثور ، على سبيل المثال ، على أكبر المجلدات في التاريخ:

git filter-repo --analyze

حسنا كن في المجلد .git/filter-repo/analysis تم إنشاء جميع أنواع ملفات TXT:

  • directories-all-sizes.txt
  • extensions-all-sizes.txt
  • path-all-sizes.txt
  • ...

إنه يستحق الملف directories-all-sizes.txt نلقي نظرة فاحصة:

=== All directories by reverse size ===

Format: unpacked size, packed size, date deleted, directory name

  4624417043 3796607988 <present> <toplevel>
  4475940396 3778033787 <present> wp-content
  4060236681 3694449320 <present> wp-content/uploads
   305163809   70576241 <present> wp-content/plugins
   123818107   15442735 <present> wp-includes
...

غالبًا ما تتجاهل بيانات HEAD الموجودة في السجل وإزالتها من عليها لفترة طويلة (على سبيل المثال ، مجلد وسائط WordPress wp-content/uploads/ أو دفع بطريق الخطأ node_modules- أو vendorبيندر).

توصي بشكل عام git-filter-repo بعد التنظيف ، الانتقال إلى مستودع جديد فارغ. هناك العديد من الأسباب المذكورة هنا, لماذا هذا منطقي ويتجنب العديد من المشاكل. ومع ذلك ، يمكن أن يحدث أنك تريد الدفع إلى نفس المستودع وهذا ممكن أيضًا مع بعض التلميحات.

الأهم من ذلك ، منصات استضافة التعليمات البرمجية الرئيسية جيثب و جيت لاب التوصية بمقاربات مختلفة ، بعضها يختلف عن بعضها البعض. على سبيل المثال ، نقوم بإزالة ملفات wp-content/uploads/ باتباع الخطوات التالية git-filter-repo من التاريخ:

mkdir tmp-repo
cd tmp-repo
git clone git@github.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
  mv /tmp/config-backup .git/config
  git push origin --force --all
# option 2: new repo
  git remote add origin git@github.com:foo/bar-new.git
  git push origin --force --all
cd ..
rm -rf tmp-repo

يمكننا الآن أيضًا التحقق من الحجم عن بُعد (قد يستغرق تغيير الحجم عبر واجهة برمجة التطبيقات وواجهة المستخدم ما يصل إلى 24 ساعة). للقيام بذلك ، افتح إعدادات المستودع (إذا كان المستودع تابعًا لمؤسسة ، يجب عليك أولاً إضافة حسابك الخاص إلى المؤسسة). الآن نرى الحجم:

GitHub: مساحة القرص قبل التنظيف
GitHub: مساحة القرص بعد التنظيف

يختلف الإجراء قليلاً في GitLab:

mkdir tmp-repo
cd tmp-repo
# option 1: same repo
  # Settings > General > Advanced > Export project > download tar.gz file into tmp-repo
  tar xzf 20*.tar.gz
  git clone --bare --mirror project.bundle
  cd project.git
  git filter-repo --invert-paths --path wp-content/uploads/
  cp ./filter-repo/commit-map /tmp/commit-map-1
  # copying the commit-map has to be done after every single command from git filter-repo
  # you need the commit-map files later
  git remote remove origin
  git remote add origin git@gitlab.com:foo/bar.git
  # Settings > Repository > Protected branches/Protected branches >
  # enable "Allowed to force push to main/master"
  git push origin --force 'refs/heads/*'
  git push origin --force 'refs/tags/*'
  git push origin --force 'refs/replace/*'
  # Settings > Repository > Protected branches/Protected branches >
  # disable "Allowed to force push to main/master"
  date
  # wait 30 minutes (😱)
  date
  # Settings > Repository > upload /tmp/commit-map-X
# option 2: new repo
  git clone git@gitlab.com:foo/bar.git .
  git filter-repo --invert-paths --path wp-content/uploads/
  git remote add origin git@gitlab.com:foo/bar-new.git
  # Settings > Repository > Protected branches/Protected branches >
  # enable "Allowed to force push to main/master"
  git push origin --force --all
  # Settings > Repository > Protected branches/Protected branches >
  # disable "Allowed to force push to main/master"
cd ..
rm -rf tmp-repo

بعد انتظار آخر لمدة 5 دقائق تقريبًا يمكننا الذهاب إلى الأسفل Settings > Usage Quotas عرض مساحة التخزين:

GitLab: مساحة القرص قبل التنظيف
GitLab: مساحة القرص بعد التنظيف

بعد الإزالة ، من المهم أن يشارك جميع المطورين المعنيين في الخطوات النهائية: إذا أجرى المستخدم الآن دفعة عادية بنسخته المحلية الخاصة ، فسيؤدي ذلك إلى ترحيل الملفات الكبيرة مرة أخرى إلى المستودع المركزي. لذلك ، يوصى بالخيارات الثلاثة التالية:

  • "استنساخ جديد للرجل الفقير"
    • rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
    • للملفات التي تم تغييرها (حسب التطبيق): git checkout -- . أو. git add -A . && git commit -m "Push obscure file changes." && git push
  • "بدء من لا شيء"
    • rm -rf repo && git clone xxx .
  • "سحب قبيح باستخدام تغيير العنوان الأساسي"
    • git pull -r
    • هنا لا يزال لديك سجل غير نظيف ، ولكن في معظم الحالات لم تعد تكتب عن طريق الخطأ المستودع البعيد بالمتغير المحلي الكبير

في سياق الحصص الحالية (خاصة بسبب القيود الجديدة في GitLab ) ، من المفيد دائمًا التحقق من حجم محفوظات مستودعاتك وتنظيفها إذا لزم الأمر:

جيثب مجانيGitLab مجاني
الحد الأقصى لحجم الملف100 ميغا بايت
الحد الأقصى لحجم الريبو5000 ميغا بايت
الحد الأقصى لعدد الريبو
الحد الأقصى للحجم الإجمالي5000 ميغا بايت

أخيرًا ، من المفيد أيضًا إلقاء نظرة على متغير مجاني مستضاف ذاتيًا مثل جيتي لرمي. مع القليل من الجهد يمكنك على خادم ضئيلة للغاية مثيل Git مستضاف ذاتيًا (واجهة المستخدم الرسومية لكل SSL مؤمن, دعم متضمن ، السيطرة على واجهة برمجة تطبيقات قوية) المضيف ، وهي ممتازة أيضًا تهيئة وهو أيضًا متفوق من حيث حماية البيانات. هنا ، بالمناسبة ، يمكنك أيضًا استخدام ملفات git-filter-repo ببساطة تبسيط المستودعات:

mkdir tmp-repo
cd tmp-repo
git clone git@git.tld.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
  mv /tmp/config-backup .git/config
  git push origin --mirror
  # login on the remote command line and run in the repo-folder
  sudo -u git git reflog expire --expire=now --all
  sudo -u git git gc --aggressive --prune=now
  # if you face memory limit issues, modify the git configuration
  sudo -u git git config --global pack.windowMemory "100m"
  sudo -u git git config --global pack.packSizeLimit "100m"
  sudo -u git git config --global pack.threads "1"
  # if in web ui the size does not change, make a slight
  # modification to a file and push again normally
# option 2: new repo
  git remote add origin git@git.tld.com:foo/bar-new.git
  git push origin --force --all
cd ..
rm -rf tmp-repo

هنا على وجه التحديد هو الأمر sudo -u git git gc --aggressive --prune=now مهم (تشغيل كرون git gc وإلا لديه واحد طويل جدًا وقت التقليم من 2 أسابيع).

عودة