4-bo‘lim
Git ichida nima saqlanadi?
.git papkasining tuzilishi, blob, tree va commit obyektlari, SHA-1 xesh va HEAD ko'rsatkichi.
Ushbu bo‘lim mundarijasi
Git ni "sehrli qora quti" deb o'ylash mumkin. Aslida uning ichki tuzilishi juda sodda - va uni tushunganingizdan keyin Git bilan ishlash ancha oson bo'ladi.
.git papkasi #
ls -a .git
HEAD config description hooks/ index info/ logs/ objects/ refs/
| Element | Nima uchun kerak |
|---|---|
HEAD | Hozir qaysi tarmoqda turganimizni ko'rsatadi |
config | Shu repozitoriy sozlamalari |
index | Sahna (staging area) - ikkilik fayl |
objects/ | Barcha ma'lumot shu yerda |
refs/ | Tarmoq va teg ko'rsatkichlari |
logs/ | Ko'rsatkichlar tarixi (reflog) |
hooks/ | Avtomatik ishga tushuvchi skriptlar |
Aslida Git juda sodda ma'lumotlar bazasi: siz unga mazmun berasiz, u sizga kalit (xesh) qaytaradi. Keyin shu kalit bilan mazmunni qaytarib olasiz.
Qolgan hamma narsa - shu asosning ustiga qurilgan qulayliklar.
SHA-1 xesh #
Git har bir obyektni mazmunidan hisoblangan 40 belgili xesh bilan nomlaydi.
echo "Salom, Git!" | git hash-object --stdin
9d7b8f2c3e5a1b4d6f8092c4e7a1b3d5f7920c4e
# Bitta harf o'zgarsa
echo "Salom, git!" | git hash-object --stdin
2f8e1a9c4b7d3e6f0a2c5b8d1e4f7a0c3b6d9e12
Bir harf o'zgardi - xesh butunlay boshqacha.
40 belgini yozish shart emas. Odatda birinchi 7 belgi yetarli:
git show 9d7b8f2
Git qolganini o'zi topadi. Faqat noaniqlik bo'lganda ko'proq belgi so'raydi.
Uch xil obyekt #
| Obyekt | Nima saqlaydi |
|---|---|
| blob | Fayl mazmuni (nomi emas!) |
| tree | Papka: fayl nomlari va ularning blob xeshlari |
| commit | Bitta tree ga havola, muallif, sana, xabar, ota-kommit |
| tag | Kommitga annotatsiyali havola (17-bo'limda) |
Bu muhim nozik jihat. blob faqat mazmunni saqlaydi.
Fayl nomi tree da yoziladi.
Shuning uchun ikkita bir xil mazmunli fayl (masalan, ikkita bo'sh .gitkeep)
bitta blob ni ulashadi - joy tejaladi.
Obyektlarni o'z ko'zingiz bilan ko'rish #
git log --oneline
c9d2e71 Kitoblar sahifasi qo'shildi
1f4c6d9 Loyiha boshlandi
git cat-file -t c9d2e71 # turi
git cat-file -p c9d2e71 # mazmuni
commit
tree 8b7d4f2a91c3e5760b8d2f4a6c9e1b3d5f70a2c4
parent 1f4c6d9e8a2b5c7d0f3a6b9c2e5d8f1a4b7c0d3e
author Husanboy Qodirov <[email protected]> 1749556800 +0500
committer Husanboy Qodirov <[email protected]> 1749556800 +0500
Kitoblar sahifasi qo'shildi
Kommit ichida faqat havolalar va matn bor. Fayllar yo'q!
git cat-file -p 8b7d4f2
100644 blob a45bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c README.md
040000 tree 3c6e9a1d4f7b0c2e5a8d1f4b7c0e3a6d9b2c5f81 manba
Bu tree - papka ro'yxati. Har bir satr: huquqlar, tur, xesh, nom.
git cat-file -p a45bd7f
# Kutubxona tizimi
Kitoblarni boshqarish tizimi.
Mana - haqiqiy fayl mazmuni.
commit → tree → blob
xabar papka mazmun
Har bir kommitdan boshlab butun loyihaga yetib borish mumkin. Va aksincha - hech qanday obyekt "yo'qolib qolmaydi", chunki hammasi zanjir bilan bog'langan.
Ota-kommit va tarix #
Har bir kommitda parent maydoni bor - undan oldingi kommit xeshi.
Kommit xeshi uning butun mazmunidan hisoblanadi: tree, muallif, sana, xabar va ota-kommit xeshi.
Demak, eski kommitni o'zgartirsangiz - uning xeshi o'zgaradi. Undan keyingi
barcha kommitlarning parent maydoni ham noto'g'ri bo'lib qoladi va
ular ham qayta yaratiladi.
Shuning uchun "tarixni qayta yozish" (rebase, amend) ehtiyotkorlik talab qiladi - 13-bo'limda batafsil ko'ramiz.
HEAD nima? #
HEAD - "siz hozir qayerdasiz" degan ko'rsatkich.
cat .git/HEAD
ref: refs/heads/main
cat .git/refs/heads/main
c9d2e71a4f8b2c5d9e0f3a6b1c4d7e0f2a5b8c31
Ya'ni:
HEAD → refs/heads/main → c9d2e71 (kommit)
Git tarmog'i - bu 41 baytli matn fayli, ichida bitta xesh.
Shuning uchun tarmoq yaratish bir zumda bajariladi - yangi fayl yoziladi, xolos. Boshqa tizimlarda esa butun loyiha nusxalanardi.
Obyektlar diskda qanday saqlanadi #
find .git/objects -type f | head -5
.git/objects/1f/4c6d9e8a2b5c7d0f3a6b9c2e5d8f1a4b7c0d3e
.git/objects/8b/7d4f2a91c3e5760b8d2f4a6c9e1b3d5f70a2c4
.git/objects/a4/5bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c
.git/objects/c9/d2e71a4f8b2c5d9e0f3a6b1c4d7e0f2a5b8c31
Xeshning birinchi ikki belgisi - papka nomi, qolgani - fayl nomi. Bu bitta papkada juda ko'p fayl to'planib qolmasligi uchun.
git count-objects -v
count: 4
size: 16
in-pack: 0
packs: 0
size-pack: 0
Obyektlar ko'payganda Git ularni packfile ga jamlaydi va siqadi. Bu vaqtda o'xshash fayllar orasidagi farq saqlanadi - joy sezilarli tejaladi.
Buni qo'lda ham chaqirish mumkin:
git gc
Odatda Git buni o'zi kerak bo'lganda bajaradi.
index fayli - sahna #
Sahna aslida .git/index nomli ikkilik faylda saqlanadi:
git ls-files --stage
100644 a45bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c 0 README.md
100644 e7c9f1a3b5d8206f4a7c0e3b6d9f2a5c8b1e4d70 0 manba/index.php
Bu ro'yxat - keyingi kommitga kiradigan fayllar.
Barcha obyektlarni ko'rish #
git rev-list --objects --all
c9d2e71a4f8b2c5d9e0f3a6b1c4d7e0f2a5b8c31
1f4c6d9e8a2b5c7d0f3a6b9c2e5d8f1a4b7c0d3e
8b7d4f2a91c3e5760b8d2f4a6c9e1b3d5f70a2c4
a45bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c README.md
e7c9f1a3b5d8206f4a7c0e3b6d9f2a5c8b1e4d70 manba/index.php
3c6e9a1d4f7b0c2e5a8d1f4b7c0e3a6d9b2c5f81 manba
Nima uchun buni bilish kerak? #
Bu bilim quyidagi hollarda yordam beradi:
- "Kommitni yo'qotdim" - obyekt hali
.git/objectsda turibdi,git reflogbilan topiladi - "Reponing hajmi katta" - qaysi blob og'irlik qilayotganini topish mumkin
- Rebase va reset - nima uchun xesh o'zgarishini tushunasiz
- Konflikt - Git nima uchun aynan shu joyda chalkashib qolganini bilasiz
- Xotirjamlik - Git ma'lumotni o'chirmaydi, faqat havolani yo'qotadi
Eng katta fayllarni topish #
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '$1 == "blob" { print $3, $4 }' \
| sort -rn | head -5
4823910 rasmlar/banner.psd
1240588 hujjatlar/taqdimot.pdf
892341 manba/vendor/kutubxona.js
154200 rasmlar/logo.png
48210 manba/style.css
Bir marta kommit qilingan fayl abadiy tarixda qoladi - hatto keyin o'chirsangiz ham. Repozitoriy hajmi doim katta bo'lib qolaveradi.
Katta ikkilik fayllar uchun Git LFS ishlating yoki ularni umuman repozitoriyga qo'ymang.
- Yangi repozitoriy yarating va bitta kommit qiling.
.git/objectsichida nechta fayl paydo bo'lganini sanang (uchta bo'lishi kerak: blob, tree, commit).git cat-file -p HEADbilan kommit mazmunini ko'ring.- Undagi
treexeshini nusxalang va uni hamcat-file -pbilan oching. - Blob xeshini toping va fayl mazmunini ko'ring.
echo "test" | git hash-object --stdinni ikki marta ishga tushiring - xesh bir xil ekaniga ishonch hosil qiling.cat .git/HEADva tarmoq faylini o'qing.- Yangi kommit qiling va
parentmaydoni paydo bo'lganini ko'ring.
Xulosa #
- Git - mazmunni xesh bo'yicha saqlaydigan sodda kalit-qiymat ombori.
- Uchta asosiy obyekt: blob (mazmun), tree (papka), commit (surat).
- Blob fayl nomini bilmaydi - nom
treeda saqlanadi. - Har bir kommitda
parenthavolasi bor - shundan tarix hosil bo'ladi. - Kommit xeshi butun mazmundan hisoblanadi - uni o'zgartirib bo'lmaydi.
HEAD- hozir qaysi tarmoqda turganimizni ko'rsatuvchi fayl.- Tarmoq - bitta xesh yozilgan kichkina fayl, shuning uchun juda arzon.
git cat-file -pbilan istalgan obyektni ochib ko'rish mumkin.
Keyingi bo'limda tarixni ko'rish va o'zgarishlarni solishtirishni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.