4-bo‘lim

Git ichida nima saqlanadi?

.git papkasining tuzilishi, blob, tree va commit obyektlari, SHA-1 xesh va HEAD ko'rsatkichi.

🕑 19 daqiqa o‘qish 📄 884 so‘z 👁 5 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. .git papkasi
  2. SHA-1 xesh
  3. Uch xil obyekt
  4. Obyektlarni o'z ko'zingiz bilan ko'rish
  5. Ota-kommit va tarix
  6. HEAD nima?
  7. Obyektlar diskda qanday saqlanadi
  8. index fayli - sahna
  9. Barcha obyektlarni ko'rish
  10. Nima uchun buni bilish kerak?
  11. Eng katta fayllarni topish
  12. Xulosa

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 #

Terminal
ls -a .git
Natija
HEAD  config  description  hooks/  index  info/  logs/  objects/  refs/
ElementNima uchun kerak
HEADHozir qaysi tarmoqda turganimizni ko'rsatadi
configShu repozitoriy sozlamalari
indexSahna (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
Git - kalit-qiymat ombori

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.

Terminal
echo "Salom, Git!" | git hash-object --stdin
Natija
9d7b8f2c3e5a1b4d6f8092c4e7a1b3d5f7920c4e
Terminal
# Bitta harf o'zgarsa
echo "Salom, git!" | git hash-object --stdin
Natija
2f8e1a9c4b7d3e6f0a2c5b8d1e4f7a0c3b6d9e12

Bir harf o'zgardi - xesh butunlay boshqacha.

Xeshni qisqartirish

40 belgini yozish shart emas. Odatda birinchi 7 belgi yetarli:

Terminal
git show 9d7b8f2

Git qolganini o'zi topadi. Faqat noaniqlik bo'lganda ko'proq belgi so'raydi.

Uch xil obyekt #

commit muallif, sana, xabar, ota-kommit, tree havolasi tree papka: fayl nomlari va ularning xeshlari blob README.md mazmuni blob index.php mazmuni tree manba/ papkasi Har bir obyekt - o'z xeshi bilan nomlangan alohida fayl
Kommit daraxtga, daraxt fayl mazmunlariga ishora qiladi
ObyektNima saqlaydi
blobFayl mazmuni (nomi emas!)
treePapka: fayl nomlari va ularning blob xeshlari
commitBitta tree ga havola, muallif, sana, xabar, ota-kommit
tagKommitga annotatsiyali havola (17-bo'limda)
Blob fayl nomini bilmaydi

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 #

Terminal
git log --oneline
Natija
c9d2e71 Kitoblar sahifasi qo'shildi
1f4c6d9 Loyiha boshlandi
Terminal
git cat-file -t c9d2e71    # turi
git cat-file -p c9d2e71    # mazmuni
Natija
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!

Terminal
git cat-file -p 8b7d4f2
Natija
100644 blob a45bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c    README.md
040000 tree 3c6e9a1d4f7b0c2e5a8d1f4b7c0e3a6d9b2c5f81    manba

Bu tree - papka ro'yxati. Har bir satr: huquqlar, tur, xesh, nom.

Terminal
git cat-file -p a45bd7f
Natija
# Kutubxona tizimi
Kitoblarni boshqarish tizimi.

Mana - haqiqiy fayl mazmuni.

Butun zanjir
Natija
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.

1f4c6d9 birinchi 5a8b3f0 c9d2e71 parent parent main HEAD Strelkalar orqaga qaraydi - kommit faqat otasini biladi, bolasini emas
Kommitlar bir tomonlama bog'langan zanjir hosil qiladi
Kommit xeshini o'zgartirib bo'lmaydi

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.

Terminal
cat .git/HEAD
Natija
ref: refs/heads/main
Terminal
cat .git/refs/heads/main
Natija
c9d2e71a4f8b2c5d9e0f3a6b1c4d7e0f2a5b8c31

Ya'ni:

Natija
HEAD  →  refs/heads/main  →  c9d2e71 (kommit)
Tarmoq - shunchaki fayl

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 #

Terminal
find .git/objects -type f | head -5
Natija
.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.

Terminal
git count-objects -v
Natija
count: 4
size: 16
in-pack: 0
packs: 0
size-pack: 0
Paketlash (packfile)

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:

Terminal
git gc

Odatda Git buni o'zi kerak bo'lganda bajaradi.

index fayli - sahna #

Sahna aslida .git/index nomli ikkilik faylda saqlanadi:

Terminal
git ls-files --stage
Natija
100644 a45bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c 0    README.md
100644 e7c9f1a3b5d8206f4a7c0e3b6d9f2a5c8b1e4d70 0    manba/index.php

Bu ro'yxat - keyingi kommitga kiradigan fayllar.

Barcha obyektlarni ko'rish #

Terminal
git rev-list --objects --all
Natija
c9d2e71a4f8b2c5d9e0f3a6b1c4d7e0f2a5b8c31
1f4c6d9e8a2b5c7d0f3a6b9c2e5d8f1a4b7c0d3e
8b7d4f2a91c3e5760b8d2f4a6c9e1b3d5f70a2c4
a45bd7f9c2e18d3b6045f7a9c1e3b5d7f9028a4c README.md
e7c9f1a3b5d8206f4a7c0e3b6d9f2a5c8b1e4d70 manba/index.php
3c6e9a1d4f7b0c2e5a8d1f4b7c0e3a6d9b2c5f81 manba

Nima uchun buni bilish kerak? #

Amaliy foyda

Bu bilim quyidagi hollarda yordam beradi:

  1. "Kommitni yo'qotdim" - obyekt hali .git/objects da turibdi, git reflog bilan topiladi
  2. "Reponing hajmi katta" - qaysi blob og'irlik qilayotganini topish mumkin
  3. Rebase va reset - nima uchun xesh o'zgarishini tushunasiz
  4. Konflikt - Git nima uchun aynan shu joyda chalkashib qolganini bilasiz
  5. Xotirjamlik - Git ma'lumotni o'chirmaydi, faqat havolani yo'qotadi

Eng katta fayllarni topish #

Terminal
git rev-list --objects --all \
  | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
  | awk '$1 == "blob" { print $3, $4 }' \
  | sort -rn | head -5
Natija
4823910 rasmlar/banner.psd
1240588 hujjatlar/taqdimot.pdf
 892341 manba/vendor/kutubxona.js
 154200 rasmlar/logo.png
  48210 manba/style.css
Katta faylni kommit qilmang

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.

Amaliy topshiriq
  1. Yangi repozitoriy yarating va bitta kommit qiling.
  2. .git/objects ichida nechta fayl paydo bo'lganini sanang (uchta bo'lishi kerak: blob, tree, commit).
  3. git cat-file -p HEAD bilan kommit mazmunini ko'ring.
  4. Undagi tree xeshini nusxalang va uni ham cat-file -p bilan oching.
  5. Blob xeshini toping va fayl mazmunini ko'ring.
  6. echo "test" | git hash-object --stdin ni ikki marta ishga tushiring - xesh bir xil ekaniga ishonch hosil qiling.
  7. cat .git/HEAD va tarmoq faylini o'qing.
  8. Yangi kommit qiling va parent maydoni 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 tree da saqlanadi.
  • Har bir kommitda parent havolasi 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 -p bilan istalgan obyektni ochib ko'rish mumkin.

Keyingi bo'limda tarixni ko'rish va o'zgarishlarni solishtirishni o'rganamiz.

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.