Git LFS — katta fayllar bilan ishlash

~15 daq · Git · Amaliy va Professional mavzular

Muammodan boshlaylik

O'yin yoki dizayn loyihasi: 3D modellar, Photoshop fayllari, videolar — har biri 50–500 MB. Bir oy ishdan keyin:

git clone git@github.com:studiya/oyin.git
Receiving objects:  23% (1203/5230), 2.31 GiB | 4.20 MiB/s

Clone — 40 daqiqa, 12 GB. Va bu — tarixdagi har bir versiya uchun: qahramon.psd 30 marta o'zgartirilgan — 30 ta nusxa, har biri 200 MB.

GitHub esa push ni umuman rad etadi:

remote: error: File assets/intro.mp4 is 312.00 MB; this exceeds GitHub's file size limit of 100.00 MB

Git — matn uchun yaratilgan. Kod fayllari kichik, diff lari ixcham. Katta binar fayllar uchun — Git LFS (Large File Storage).


Muammo nimada

Git har bir fayl versiyasini to'liq saqlaydi (1-dars). Matn uchun — muammo emas: siqilgan va deltalar bilan kichik. Binar fayllar uchun:

  • Siqilmaydi (rasm va videolar allaqachon siqilgan)
  • Delta ishlamaydi — bitta pikselni o'zgartirish butun yangi nusxani beradi
  • Har bir clone — barcha versiyalar
 Oddiy Git:                       Git LFS:
 .git/objects/                    .git/objects/
   qahramon.psd  v1  200 MB          qahramon.psd → ko'rsatkich (130 bayt)
   qahramon.psd  v2  200 MB          ...
   qahramon.psd  v3  200 MB       LFS serveri:
   ...                               v1, v2, v3... (faqat kerakli yuklanadi)

Git LFS qanday ishlaydi

LFS katta faylni kichik matnli ko'rsatkich (pointer) bilan almashtiradi:

version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 209715200
  • Git repozitoriysida — faqat shu 130 baytlik fayl
  • Haqiqiy 200 MB — alohida LFS serverida (GitHub buni avtomatik beradi)
  • checkout paytida LFS faqat kerakli versiyani yuklaydi
  • Ishchi papkada siz oddiy faylni ko'rasiz — hech qanday farq sezilmaydi

O'rnatish va sozlash

1. O'rnatish (bir marta)

  • Windows — Git for Windows tarkibida bor
  • macOS — brew install git-lfs
  • Linux — sudo apt install git-lfs
git lfs install          # foydalanuvchi uchun bir marta

2. Qaysi fayllarni LFS ga

git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "assets/models/**"

Bu .gitattributes ga (52-dars) yozadi:

*.psd filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
assets/models/** filter=lfs diff=lfs merge=lfs -text

[!WARNING] .gitattributes ni birinchi commit qiling — katta fayllardan oldin. Aks holda fayllar oddiy Git ga tushib qoladi (va tarixda abadiy qoladi).

git add .gitattributes
git commit -m "chore: Git LFS sozlandi"

3. Odatdagidek ishlash

git add assets/intro.mp4
git commit -m "feat: intro video"
git push
Uploading LFS objects: 100% (1/1), 312 MB | 8.4 MB/s, done.

Hech qanday yangi buyruq — add, commit, push odatdagidek.

Tekshirish

git lfs ls-files             # LFS dagi fayllar
git lfs status
git lfs env                  # sozlamalar

Clone va pull

git clone git@github.com:studiya/oyin.git

LFS o'rnatilgan bo'lsa — joriy versiya fayllari avtomatik yuklanadi. O'rnatilmagan bo'lsa — ishchi papkada ko'rsatkich matnlari qoladi (rasm o'rniga 130 baytlik matn fayli). Yechim: git lfs install → git lfs pull.

Faqat kerakli fayllar

Dasturchiga 10 GB videolar kerak emas — faqat kod:

GIT_LFS_SKIP_SMUDGE=1 git clone git@github.com:studiya/oyin.git
cd oyin
git lfs pull --include="assets/textures/**"

Mavjud fayllarni LFS ga ko'chirish

Katta fayllar allaqachon tarixda bo'lsa, git lfs track faqat yangi commitlarga ta'sir qiladi. Tarixni qayta yozish:

git lfs migrate import --include="*.psd,*.mp4" --everything
git push --force-with-lease --all

[!WARNING] migrate import butun tarixni qayta yozadi — barcha commit hash lari o'zgaradi (17-dars). Jamoa bilan kelishib qiling: hamma o'z ishini push qilsin, migratsiyadan keyin esa hamma repozitoriyni qaytadan clone qilsin.


Cheklovlar va narxlar

Qiymat (GitHub)
Oddiy Git: bitta fayl 100 MB (50 MB dan ogohlantirish)
LFS: bitta fayl Tarifga qarab 2–5 GB
LFS saqlash va trafik (bepul) Cheklangan (taxminan 1 GB atrofida)
Ko'proq Pullik "data pack" lar

LFS trafigi — har bir clone va CI build ham sarflaydi. CI da LFS fayllar kerak bo'lmasa — yuklamang (actions/checkout da lfs: false — standart).


LFS kerakmi?

✅ Ha:

  • Dizayn manbalari (PSD, Figma eksport, Sketch)
  • 3D modellar, o'yin resurslari
  • Video va audio
  • ML modellar va katta datasetlar (yoki maxsus vositalar — DVC)
  • Tez-tez o'zgaradigan katta binar fayllar

❌ Yo'q / boshqa yechim:

  • Veb-sayt rasmlari (bir necha yuz KB) — oddiy Git; yoki yaxshirog'i — optimallashtiring
  • Build natijalari, node_modules, .exe relizlar — .gitignore (11-dars), relizlar — GitHub Releases (41-dars)
  • Foydalanuvchi yuklagan fayllar — S3 kabi ob'ekt omborlari, Git emas
  • Baza zaxiralari — Git emas

Nima uchun shunday?

Nima uchun Git katta fayllarni o'zi yaxshi boshqara olmaydi — LFS alohida qo'shimcha?

Chunki Git ning eng kuchli tomoni — har bir nusxada to'liq tarix (taqsimlangan model, 1-dars) — katta binar fayllar uchun eng zaif tomoniga aylanadi. Kod uchun to'liq tarix — bir necha megabayt va bebaho foyda (log, blame, bisect internetsiz). 200 MB lik fayl va 30 ta versiyasi uchun esa — 6 GB, va ularning 29 tasi deyarli hech qachon kerak bo'lmaydi. LFS aynan shu fayllar uchun modelni o'zgartiradi: tarix (ko'rsatkichlar) — hamma joyda, og'ir mazmun — markazda, faqat talab bo'yicha. Kod uchun — taqsimlangan, katta resurslar uchun — markazlashgan. Har biri o'z ishiga mos.


Xulosa

Eslab qoling:

  • Git binar fayllarni yomon saqlaydi: har versiya — to'liq nusxa; GitHub — 100 MB chegara
  • LFS — repozitoriyda kichik ko'rsatkich, haqiqiy fayl — LFS serverida
  • git lfs install (bir marta) → git lfs track "*.psd" → .gitattributes ni avval commit
  • Keyin — oddiy add, commit, push
  • LFS siz clone — ko'rsatkich matnlari; git lfs pull
  • GIT_LFS_SKIP_SMUDGE=1 + lfs pull --include — faqat kerakli fayllar
  • git lfs migrate import — tarixni qayta yozadi, jamoa bilan kelishib
  • Relizlar — GitHub Releases; yuklamalar — S3; build natijalari — .gitignore

Keyingi dars

54-dars: GitHub CLI — gh tool bilan terminaldan GitHub boshqarish