Git فایلها را اول جدا و بعد فشرده در packfile نگه میدارد. gc زبالهها را جمع میکند. این فصل وقتی لازم میشود که مخزن باد کرده یا fsck خطا میدهد.
🎯 اهداف یادگیری
- loose object را از packfile تشخیص دهی
gcوrepackرا با احتیاط اجرا کنیfsckرا برای سلامت دیتابیس به کار ببری- reftable را بهعنوان backend مدرن refs بشناسی
🗄️ objects
دو شکل:
- Loose:
.git/objects/ab/cdef...یک فایل per شیء - Packed:
pack-....pack+.idx— دلتا فشرده، سریع برای fetch
git count-objects -vH git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail git cat-file -t 9f3a1c git cat-file -s 9f3a1c
git gc looseها را pack میکند، unreachable را بعد از grace period دور میریزد. git gc --prune=now تهاجمی است.
روی سرور شلوغ gc را در maintenance پنجره بزن. git maintenance start زمانبندی امنتری است.
🔗 refs: files در برابر reftable
سنت: هر شاخه یک فایل در .git/refs/heads + packed-refs. با صدها هزار ref (Gerrit، monorepo) کند میشود.
git init --ref-format=reftable /tmp/rt
Reftable در مسیر Git ۳.۰ production-ready است. GitHub در مقیاس خودش از سیستمهای مشابه بهره میبرد. برای پروژهٔ معمولی files کافی است.
🩺 fsck و recover
git fsck --full git fsck --lost-found
dangling commit اغلب کامیتهای rebaseشدهاند — گاهی نجات با git show <hash> و شاخه ساختن.
اگر index.lock ماند (کریش VS Code): فقط وقتی هیچ فرایند Git/Code روی مخزن نیست حذفش کن.
🧹 تاریخچهٔ سنگین
git rev-list --objects --all \ | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \ | awk '/^blob/' | sort -k3 -n | tail
بعد git filter-repo برای حذف باینری accidental. همه باید re-clone کنند.
Mid — چرا clone دوم سریعتر است؟ pack از قبل دلتا شده؛ looseها در مسیر critical نیستند.
Senior — unreachable چه زمانی میمیرد؟ reflog expire (پیشفرض ~90 روز) بعد prune. تا آن موقع reset --hard قابل برگشت است.
✅ چکلیست فهم
count-objects -vHرا خواندهای- میدانی gc unreachable را بعد از reflog میکشد
- reftable را با SHA-256 قاطی نمیکنی (دو محور جدا)
فصل بعد: مخازن بزرگ، partial clone، Scalar، monorepo.