IlmHamroh
JavaScript Full-stack/7-qism. Git va GitHub asoslari14/36-dars20 daqiqa
Mundarija (34)

Git blame, log -S va log -L: kod arxeologiyasi

Qisqacha: git blame fayl har qatorni oxirgi marta qaysi commit, kim va qachon o'zgartirganini ko'rsatadi. Flaglar yordam beradi: -w bo'sh joy o'zgarishlarini, .git-blame-ignore-revs esa formatlash commitlarini chetlab o'tadi. Tarixdan qidirish uchun: git log -S "matn" shu matn paydo bo'lgan yoki yo'qolgan commitlarni topadi, git log -L esa bitta qator yoki blokning butun tarixini ko'rsatadi. Uchalasi birga "bu qator nega shunday?" degan savolga javob beradi.

Bu darsda

  • git blame natijasini ustunma-ustun o'qiysiz va -L, -w, -C flaglarini ishlatasiz.
  • Formatlash commitlarini .git-blame-ignore-revs bilan blame'dan yashirasiz.
  • git log -S va -G (pickaxe) farqini bilasiz va matn qachon paydo bo'lganini topasiz.
  • git log -L bilan bitta qatorning butun hayotini ko'rasiz.
  • GitHub'dagi Blame oynasini taniysiz.

Oldin bilishingiz kerak: Tarixni o'qish: git log, O'zgarishlarni ko'rish: git diff, .gitattributes va qator oxirlari.

1. Nega bu kerak?

«Bahor» menyusida shunday qator bor:

text
<p>Osh — 40 000 so'm</p>

Bir kuni mehmon so'radi: "O'tgan oy osh arzonroq edi-ku?" Jasur aka Aziz'ga murojaat qildi: "Narxni kim, qachon o'zgartirdi? Nega?" Aziz buni eslamaydi — saytni uch kishi tahrirlaydi.

Dasturchilar bunday savolni har kuni beradi, faqat boshqa ko'rinishda: "Bu kod nega bunday yozilgan? Buni olib tashlasam, nima buziladi? Bu xato qachon kirib qolgan?" Javob — tarixda. Tarixni o'qish darsida commitlarni ro'yxat qilib ko'rdik. Endi teskari yo'nalishda boramiz: aniq bir qatordan boshlab, uni yaratgan commitni topamiz.

Buni kod arxeologiyasi deyishadi. Arxeolog tuproq qatlamlarini birma-bir ochib, har qatlam qaysi davrga tegishli ekanini aniqlaydi. Biz ham fayl qatlamlarini — commitlarni — ochamiz. Uchta asbob bor:

flowchart TD
  Q{"Qanday savol?"} --> B["Bu qatorni kim<br/>oxirgi o'zgartirgan?"]
  Q --> S["Bu matn qachon<br/>paydo bo'lgan?"]
  Q --> L["Bu qator qanday<br/>o'zgarib kelgan?"]
  B --> B1["git blame"]
  S --> S1["git log -S / -G"]
  L --> L1["git log -L"]

Nimaga qarang: har savolning o'z asbobi bor. Ko'pincha ular ketma-ket ishlatiladi: blame — birinchi iz, log -S va log -L — chuqurroq qazish.

2. Tayyorgarlik: uch mualliflik tarix

Arxeologiya uchun tarix boy bo'lishi kerak. «Bahor»ni Birinchi repo darsi oxiridagi holatdan olib, uch kishi bir hafta ishlaganini taqlid qildik. Jasur aka va Malika — boshqa mualliflar. Bunday commitlarni --author bilan yaratish mumkin (masalan git commit --author="Jasur Rahimov <jasur@example.com>" ...). Sizning reposingizda keyingi darslardagi commitlar ham bor, shuning uchun hashlar boshqacha bo'ladi — mualliflar nomi bilan ishlaymiz.

bash
git log --format='%h %an: %s' -8
text
f969938 Aziz Karimov: Menyu: somsa narxini qo'sh
2469f9d Malika Tosheva: Aloqa: ish vaqtini bosh sahifadan ko'chir
a2ce4a3 Jasur Rahimov: Menyu: osh narxini 40 000 so'mga ko'tar
c9c2ffb Aziz Karimov: Menyu: narxlarni main ichiga ol va formatla
01d072d Aziz Karimov: Bosh sahifa: ish vaqtini qo'sh
5d79caa Malika Tosheva: CSS: paragraflar orasini kamaytir
d323519 Jasur Rahimov: Menyu: osh narxini 38 000 so'mga ko'tar
07b061d Aziz Karimov: Menyu: lag'mon narxini qo'sh

--format bilan o'z ko'rinishimizni berdik: %h — qisqa hash, %an — muallif nomi, %s — xabar (Tarixni o'qish darsidan). Menyu fayli hozir:

text
<h1>Menyu</h1>
<main>
  <p>Osh — 40 000 so'm</p>
  <p>Lag'mon — 28 000 so'm</p>
  <p>Somsa — 8 000 so'm</p>
</main>

3. git blame — har qatorning muallifi

3.1 Birinchi blame

bash
git blame menyu/index.html
text
^dab5bff (Aziz Karimov  2026-10-01 10:00:00 +0500 1) <h1>Menyu</h1>
c9c2ffbf (Aziz Karimov  2026-10-15 09:00:00 +0500 2) <main>
a2ce4a31 (Jasur Rahimov 2026-10-16 09:00:00 +0500 3)   <p>Osh — 40 000 so'm</p>
c9c2ffbf (Aziz Karimov  2026-10-15 09:00:00 +0500 4)   <p>Lag'mon — 28 000 so'm</p>
f969938f (Aziz Karimov  2026-10-18 09:00:00 +0500 5)   <p>Somsa — 8 000 so'm</p>
c9c2ffbf (Aziz Karimov  2026-10-15 09:00:00 +0500 6) </main>

git blame (inglizcha "ayblash") — faylning har qatori yoniga shu qatorni oxirgi marta o'zgartirgan commitni yozadi. Xuddi daftardagi har yozuv yonida "kim, qachon tuzatgan" degan imzo turgandek. Nomi qo'rqinchli, lekin maqsad aybdor izlash emas — kontekst topish. Har qator besh qismdan iborat:

Qism Misol Ma'nosi
Hash a2ce4a31 Qatorni oxirgi o'zgartirgan commit
Muallif Jasur Rahimov O'sha commit muallifi
Sana 2026-10-16 09:00:00 +0500 Commit sanasi
Raqam 3 Fayldagi qator raqami
Mazmun <p>Osh — 40 000 so'm</p> Qatorning o'zi

Birinchi qatordagi ^dab5bff — boshidagi ^ "chegara" belgisi: bu tarixning eng birinchi commiti, undan oldinga yurib bo'lmaydi.

Mehmonning savoliga birinchi javob tayyor: osh narxini oxirgi marta Jasur aka 16-oktabrda o'zgartirgan. Commitning o'zini git show bilan ochamiz: git show a2ce4a31.

3.2 Faqat kerakli qatorlar: -L

Katta faylda hamma qatorni ko'rish shart emas. -L boshi,oxiri:

bash
git blame -L 3,4 menyu/index.html
text
a2ce4a31 (Jasur Rahimov 2026-10-16 09:00:00 +0500 3)   <p>Osh — 40 000 so'm</p>
c9c2ffbf (Aziz Karimov  2026-10-15 09:00:00 +0500 4)   <p>Lag'mon — 28 000 so'm</p>

-L 3,+2 ham xuddi shunday — "3-qatordan boshlab 2 ta qator". Yana ikki qulay flag: -s muallif va sanani yashiradi (faqat hash va raqam), -e esa nom o'rniga email ko'rsatadi.

3.3 Eski versiyaning blame'i

Blame'ni istalgan eski commitda ham so'rash mumkin. Jasur akaning birinchi narx o'zgarishi (d323519) paytida fayl qanday edi?

bash
git blame d323519 -- menyu/index.html
text
^dab5bff (Aziz Karimov  2026-10-01 10:00:00 +0500 1) <h1>Menyu</h1>
d3235197 (Jasur Rahimov 2026-10-13 09:00:00 +0500 2) <p>Osh — 38 000 so'm</p>
07b061d7 (Aziz Karimov  2026-10-02 10:12:00 +0500 3) <p>Lag'mon — 28 000 so'm</p>

-- — "bundan keyin fayl yo'li keladi" (git log darsida ko'rgan edik). O'sha kuni osh 38 000 edi. Bu "qatlam-qatlam" qazish usuli: blame bir commitni ko'rsatadi, siz undan oldingi commitda yana blame so'raysiz.

Tekshirib ko'ring: Blame 3-qator uchun a2ce4a31 (Jasur Rahimov ...) dedi. Bu "osh qatorini Jasur aka yozgan" deganimi?

Javob

Yo'q. Blame qatorni oxirgi marta o'zgartirgan commitni ko'rsatadi. Jasur aka faqat narxni almashtirgan. Qatorning o'zi ancha oldin — f4238e7 da Aziz tomonidan yozilgan. Butun tarixni ko'rish uchun «git log -L» bo'limidagi asbob kerak.

4. Formatlash blame'ni "yashiradi"

4.1 Muammo

Blame natijasiga yana qarang. 4-qator — lag'mon narxi — c9c2ffbf, Aziz, 15-oktabr. Lekin lag'mon narxini 2-oktabrda yozishgan edi! 15-oktabrda nima bo'ldi?

O'sha kuni Aziz narxlarni <main> ichiga oldi va har qatorga ikki bo'sh joy chekinish qo'shdi. Mazmun o'zgarmadi, faqat bo'sh joy. Lekin Git uchun qator o'zgargan — va blame endi hamma narxlar uchun Aziz'ni ko'rsatadi. Loyihada Prettier (kod formatlovchi, Stylelint va Prettier darsida ishlatgansiz) bir marta ishga tushirilsa, minglab qatorning blame'i shu bitta "formatlash" commitiga o'tib ketadi.

4.2 -w — bo'sh joyga e'tibor berma

bash
git blame -w menyu/index.html
text
^dab5bff (Aziz Karimov  2026-10-01 10:00:00 +0500 1) <h1>Menyu</h1>
c9c2ffbf (Aziz Karimov  2026-10-15 09:00:00 +0500 2) <main>
a2ce4a31 (Jasur Rahimov 2026-10-16 09:00:00 +0500 3)   <p>Osh — 40 000 so'm</p>
07b061d7 (Aziz Karimov  2026-10-02 10:12:00 +0500 4)   <p>Lag'mon — 28 000 so'm</p>
f969938f (Aziz Karimov  2026-10-18 09:00:00 +0500 5)   <p>Somsa — 8 000 so'm</p>
c9c2ffbf (Aziz Karimov  2026-10-15 09:00:00 +0500 6) </main>

-w (whitespace) — "faqat bo'sh joy o'zgargan commitlarni o'tkazib yubor". 4-qator endi haqiqiy egasini ko'rsatdi: 07b061d7, 2-oktabr. <main> va </main> esa c9c2ffbf da qoldi — ular o'sha commitda haqiqatan yangi qo'shilgan.

4.3 .git-blame-ignore-revs — jamoa uchun doimiy yechim

-w faqat bo'sh joyni ko'radi. Formatlovchi esa ko'pincha qo'shtirnoqlarni ham, qator bo'linishini ham o'zgartiradi. Bundan tashqari, -w ni har safar yozish kerak. Git'da buning uchun kelishilgan fayl bor: .git-blame-ignore-revs — "blame e'tiborga olmaydigan commitlar ro'yxati".

Loyiha ildizida fayl yaratamiz. Formatlash commitining to'liq hashini git log --format=%H --grep="formatla" bilan topdik. Bu yerda %H — to'liq hash, --grep — xabar bo'yicha qidirish. Fayl mazmuni:

text
# Menyu: main ichiga olish va chekinish (formatlash)
c9c2ffbf08ed1d8628d24d995c54242b1c6c0034

Qoidalar: har qatorda bitta to'liq (40 belgili) hash, # bilan boshlangan qatorlar — izoh. docs.github.com ham har hash ustiga izoh yozishni tavsiya qiladi: bir yildan keyin "bu nima edi?" degan savol tug'ilmasin. Sinab ko'ramiz:

bash
git blame --ignore-revs-file .git-blame-ignore-revs menyu/index.html

Natija -w dagi bilan bir xil: lag'mon qatori 07b061d7 ga qaytdi. Har safar faylni yozmaslik uchun bir martalik sozlama:

bash
git config blame.ignoreRevsFile .git-blame-ignore-revs

Endi oddiy git blame menyu/index.html ham formatlash commitini o'tkazib yuboradi. Yana bir foydali sozlama — blame.markIgnoredLines. U "chetlab o'tilgan commit tufayli boshqa commitga yozilgan" qatorlarni ? bilan belgilaydi:

bash
git config blame.markIgnoredLines true
git blame -L 4,4 menyu/index.html
text
?07b061d (Aziz Karimov 2026-10-02 10:12:00 +0500 4)   <p>Lag'mon — 28 000 so'm</p>

? — "bu yerda aslida formatlash commiti bor edi, biz uni chetlab o'tdik". Faylni commit qilish unutilmasin — u butun jamoaga kerak. git config esa shaxsiy (local) sozlama: har bir dasturchi o'zi bir marta yozadi.

Maslahat: Formatlash commitini doim alohida qiling (Yaxshi commit darsidagi atomar commit qoidasi). Bizdagi c9c2ffb ham <main> qo'shdi, ham chekinish berdi. Shuning uchun uni e'tiborsiz qoldirgandan keyin ham <main> qatorlari unga yozilib turibdi. .gitattributes darsidagi "Qator oxirlarini tartibla" commiti ham shu ro'yxatga tushadigan nomzod: u har qatorni o'zgartirishi mumkin.

5. Ko'chirilgan kod: -C

Malika ish vaqti haqidagi ikki qatorni bosh sahifadan aloqa sahifasiga ko'chirdi. Blame nima deydi?

bash
git blame aloqa/index.html
text
b09fa2a4 (Aziz Karimov   2026-10-01 10:12:00 +0500 1) <h1>Aloqa</h1>
2469f9d4 (Malika Tosheva 2026-10-17 10:00:00 +0500 2) <p>Ish vaqti: har kuni 08:00 dan 23:00 gacha</p>
2469f9d4 (Malika Tosheva 2026-10-17 10:00:00 +0500 3) <p>Dam olish kuni yo'q, bayramlarda ham ochiqmiz</p>

Blame Malikani ko'rsatdi — u qatorlarni shu faylga qo'ygan. Lekin matnni u yozmagan. -C (copy) — "boshqa fayllardan ko'chirilgan qatorlarni ham izla":

bash
git blame -C aloqa/index.html
text
b09fa2a4 aloqa/index.html (Aziz Karimov 2026-10-01 10:12:00 +0500 1) <h1>Aloqa</h1>
01d072db index.html       (Aziz Karimov 2026-10-14 10:00:00 +0500 2) <p>Ish vaqti: har kuni 08:00 dan 23:00 gacha</p>
01d072db index.html       (Aziz Karimov 2026-10-14 10:00:00 +0500 3) <p>Dam olish kuni yo'q, bayramlarda ham ochiqmiz</p>

Yangi ustun paydo bo'ldi — fayl nomi. Git topdi: bu qatorlar asli index.html da, 01d072db commitida, Aziz tomonidan yozilgan.

-C ning cheklovlari bor. Bitta -C faqat o'sha commitda o'zgargan fayllardan qidiradi — Malika bir commitda ham o'chirdi, ham qo'shdi, shuning uchun topildi. Ikkita -C (-C -C) fayl yaratilgan commitdagi boshqa fayllardan ham, -C -C -C esa istalgan commitdagi fayllardan qidiradi. Har qo'shimcha -C sekinroq. Yana bir shart: ko'chirilgan bo'lak yetarlicha uzun bo'lishi kerak. Git hujjatiga ko'ra, standart chegara — 40 ta harf-raqam belgisi. Bitta qisqa qatorni Git ko'chirilgan deb tanimasligi mumkin.

6. git log -S va -G — pickaxe

6.1 Matn qachon paydo bo'lgan?

Blame faqat hozir faylda bor qatorlar haqida gapiradi. O'chirilgan qator-chi? Masalan: "Osh qachon 35 000 edi va qachon o'zgardi?" Hozirgi faylda 35 000 yo'q — blame yordam bermaydi.

Buning uchun git log -S:

bash
git log -S "35 000" --oneline
text
d323519 Menyu: osh narxini 38 000 so'mga ko'tar
f4238e7 Menyu: osh narxini qo'sh

-S "matn" — "shu matn necha marta uchrashi o'zgargan commitlarni ko'rsat". Oddiyroq aytganda: matn paydo bo'lgan yoki yo'qolgan commitlar. f4238e7 da 35 000 birinchi marta yozildi, d323519 da yo'qoldi. Bu asbob ingliz tilida pickaxe — "cho'kich" deyiladi: arxeolog uni tuproqni qazish uchun ishlatadi.

-p qo'shsangiz, har commitning diff'i ham chiqadi:

bash
git log -S "40 000" -p --oneline
text
a2ce4a3 Menyu: osh narxini 40 000 so'mga ko'tar
diff --git a/menyu/index.html b/menyu/index.html
index 20ae860..7eb8248 100644
--- a/menyu/index.html
+++ b/menyu/index.html
@@ -1,5 +1,5 @@
 <h1>Menyu</h1>
 <main>
-  <p>Osh — 38 000 so'm</p>
+  <p>Osh — 40 000 so'm</p>
   <p>Lag'mon — 28 000 so'm</p>
 </main>

6.2 Ko'chirilgan matn

-S bir fayldan ikkinchisiga ko'chishni ham ko'radi:

bash
git log -S "Ish vaqti" --oneline --stat
text
2469f9d Aloqa: ish vaqtini bosh sahifadan ko'chir
 aloqa/index.html | 2 ++
 index.html       | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)
01d072d Bosh sahifa: ish vaqtini qo'sh
 index.html | 2 ++
 1 file changed, 2 insertions(+)

01d072d da matn paydo bo'ldi. 2469f9d da index.html dan yo'qolib, aloqa/index.html da paydo bo'ldi. Qidiruvni bitta papka yoki faylga cheklash ham mumkin — oxiriga -- menyu kabi yo'l qo'shiladi.

6.3 -S va -G farqi

-G "matn" — o'xshash, lekin boshqacha savol beradi: "diff'ida shu matn bor qator qo'shilgan yoki o'chirilgan commitlar". Farqni "Osh" so'zida ko'ramiz:

bash
git log -S "Osh" --oneline
git log -G "Osh" --oneline
text
f4238e7 Menyu: osh narxini qo'sh
a2ce4a3 Menyu: osh narxini 40 000 so'mga ko'tar
c9c2ffb Menyu: narxlarni main ichiga ol va formatla
d323519 Menyu: osh narxini 38 000 so'mga ko'tar
f4238e7 Menyu: osh narxini qo'sh

Birinchi buyruq bitta commit topdi, ikkinchisi — to'rtta. Nega? "Osh" so'zi faylda bir marta, f4238e7 dan beri. Narx o'zgarganda "Osh" so'zining soni o'zgarmagan: bitta edi, bitta qoldi. -S faqat son o'zgarishini sezadi. -G esa "Osh" bor qator diff'da o'zgarganini ko'radi — narx o'zgarishi ham, formatlash ham shunday.

-S "matn" -G "matn"
Savol Matn qachon paydo bo'ldi yoki yo'qoldi? Matnli qator qachon o'zgardi?
Matn turi Oddiy satr Regex (qidiruv shabloni)
"Osh" misoli 1 commit 4 commit

Regex (regular expression) — matn qidirish shabloni: [0-9]+ — "bir yoki bir nechta raqam". Uni Fayl qidirish darsida grep bilan ko'rgansiz. -S odatda oddiy matn qidiradi. --pickaxe-regex flagi bilan u ham regex tushunadi:

bash
git log -S "Osh — [0-9]+" --oneline
git log -S "Osh — [0-9]+" --pickaxe-regex --oneline

Birinchi buyruq hech narsa topmadi — -S bu matnni so'zma-so'z qidirdi. Ikkinchisi f4238e7 ni topdi: "Osh — raqam" shabloni o'shanda paydo bo'lgan. Keyingi narx o'zgarishlarida shablonga mos qatorlar soni o'zgarmagan.

Tekshirib ko'ring: CSS faylidagi .aksiya klassi bir yil oldin o'chirilgan. Uni qaysi commit o'chirganini topish uchun blame mi, log -S mi?

Javob

git log -S ".aksiya". Blame faqat hozirgi faylda bor qatorlarni ko'rsatadi — o'chirilgan klass u yerda yo'q. -S esa matn soni o'zgargan commitlarni topadi: klass qo'shilgan va o'chirilgan commitlar ro'yxatda chiqadi, eng yangisi — o'chirilgani.

7. git log -L — bitta qatorning hayoti

7.1 Qator bo'yicha tarix

Blame bitta commitni ko'rsatadi, -S matn bo'yicha qidiradi. Ba'zan boshqa narsa kerak: aniq bir qatorning barcha o'zgarishlari ketma-ket. Bu — git log -L:

bash
git log -L '/Osh/,+1:menyu/index.html' --oneline -s
text
a2ce4a3 Menyu: osh narxini 40 000 so'mga ko'tar
c9c2ffb Menyu: narxlarni main ichiga ol va formatla
d323519 Menyu: osh narxini 38 000 so'mga ko'tar
07b061d Menyu: lag'mon narxini qo'sh
f4238e7 Menyu: osh narxini qo'sh

Yozuvni bo'laklaymiz: -L 'oraliq:fayl'. Oraliq ikki xil yoziladi:

  • Raqamlar bilan: 3,3 — 3-qator, 3,+2 — 3-qatordan ikki qator.
  • Shablon bilan: /Osh/,+1 — "Osh" bor birinchi qatordan bitta qator. Qator raqami keyin o'zgarsa ham, shablon to'g'ri qatorni topadi.

-s — "diff'ni ko'rsatma, faqat ro'yxat". Qator besh commitda o'zgargan. 07b061d ro'yxatda nega bor? U osh qatoriga tegmagan, lekin uning ostiga lag'mon qatorini qo'shgan — -L qator atrofidagi o'zgarishni ham ko'rsatishi mumkin.

7.2 Diff bilan

-s siz har commitning faqat shu qatorga tegishli diff'i chiqadi. Natijaning boshi (qolganini ... bilan qisqartirdik):

text
a2ce4a3 Menyu: osh narxini 40 000 so'mga ko'tar

diff --git a/menyu/index.html b/menyu/index.html
index 20ae860..7eb8248 100644
--- a/menyu/index.html
+++ b/menyu/index.html
@@ -3,1 +3,1 @@
-  <p>Osh — 38 000 so'm</p>
+  <p>Osh — 40 000 so'm</p>
c9c2ffb Menyu: narxlarni main ichiga ol va formatla

diff --git a/menyu/index.html b/menyu/index.html
index 20788b3..20ae860 100644
--- a/menyu/index.html
+++ b/menyu/index.html
@@ -4,0 +3,1 @@
+  <p>Osh — 38 000 so'm</p>
d323519 Menyu: osh narxini 38 000 so'mga ko'tar
...

Osh narxining butun hayoti bitta ekranda: 35 000 → 38 000 (Jasur aka) → formatlash → 40 000 (Jasur aka). Mehmonning savoliga to'liq javob: "O'tgan oy 38 000 edi, 16-oktabrda Jasur aka 40 000 qildi". Nega — commit xabarida. Xabar yetarli bo'lmasa, Jasur akaning o'zidan so'rash kerak. Mana shu yerda Yaxshi commit darsidagi "tanada nega'ni yozing" qoidasining qadri bilinadi.

-L funksiya nomi bilan ham ishlaydi (-L :funksiyaNomi:fayl). Bu JavaScript o'rganganingizda juda qulay bo'ladi.

8. GitHub'dagi Blame oynasi

Xuddi shu ma'lumot GitHub'da brauzerda ham bor. docs.github.com ga ko'ra:

  1. Repo sahifasida kerakli faylni oching.
  2. Fayl mazmuni ustidagi Blame tugmasini bosing.

Har qator yonida commit, muallif va vaqt ko'rinadi — terminaldagi blame'ning vizual ko'rinishi.

Yaxshi xabar: GitHub .git-blame-ignore-revs faylini o'zi o'qiydi — agar u repo ildizida bo'lsa. Undagi commitlar Blame oynasida chetlab o'tiladi va tepada "Ignoring revisions in .git-blame-ignore-revs" degan banner chiqadi. Hujjatda ikki muhim eslatma bor:

  • Chetlab o'tilgan commit qatorni o'zi yangi qo'shgan bo'lsa, u baribir ko'rinishi mumkin — bizdagi <main> qatorlari kabi.
  • Oddiy (hech narsasiz) blame'ni ko'rish uchun URL'dagi commit hashi oxiriga ~ qo'shiladi — banner yo'qoladi.

GitHub repolar bilan ishlashni Remote darsidan boshlaymiz. Portfolio'ingiz GitHub'ga ulangach, bu oynani o'zingiz ochasiz.

9. Ko'p uchraydigan xatolar

9.1 Git Bash'da -L '/shablon/' ishlamaydi

bash
git blame -L '/Osh/,+1' menyu/index.html
text
usage: git blame [<options>] [<rev-opts>] [<rev>] [--] <file>

Tarjimasi: "Foydalanish: git blame [variantlar] [revision variantlari] [revision] [--] <fayl>". Git buyruqni tushunmadi va to'g'ri yozilishini eslatdi. Lekin buyruqda xato yo'q! Sababi Git Bash'da: u / bilan boshlanadigan argumentni Linux uslubidagi fayl yo'li deb o'ylab, Windows yo'liga "tuzatib" yuboradi. Biz tekshirdik: /Osh/,+1 Git'ga D:/Dasturlash/Install/Git/Osh/,+1 bo'lib yetib bordi (bizda Git D: diskda; odatiy o'rnatishda boshi C:/Program Files/Git). Git esa bunday oraliqni tushunmaydi. macOS va Linux'da bu muammo yo'q.

Ikki yechim bor. Qator raqamini ishlating (-L 3,+2). Yoki buyruq oldiga MSYS_NO_PATHCONV=1 qo'ying — "yo'llarni o'zgartirma":

bash
MSYS_NO_PATHCONV=1 git blame -L '/Osh/,+1' menyu/index.html
text
a2ce4a31 (Jasur Rahimov 2026-10-16 09:00:00 +0500 3)   <p>Osh — 40 000 so'm</p>

git log -L '/Osh/,+1:menyu/index.html' esa Git Bash'da muammosiz ishladi: ichida : bor argumentni Git Bash o'zgartirmadi — buni ham sinab ko'rdik.

9.2 Fayl nomida xato

text
fatal: no such path 'menu/index.html' in HEAD

Tarjimasi: "HEAD da menu/index.html degan yo'l yo'q". Papka menyu. Blame faqat oxirgi commitda bor fayllar bilan ishlaydi. O'chirilgan fayl uchun eski commitni ko'rsating: git blame <hash> -- fayl.

9.3 Blame'ni "aybdor izlash" uchun ishlatish

Blame qatorni oxirgi o'zgartirgan odamni ko'rsatadi, xatoni kiritganini emas. Ehtimol u faqat formatlagan yoki bir harfni tuzatgan. Xulosa chiqarishdan oldin commitni git show bilan oching va kerak bo'lsa -w, -C, log -L bilan chuqurroq qarang. Yaxshi jamoada blame "kimdan so'rash kerak?" degan savolga javob beradi, "kim aybdor?" degan savolga emas.

9.4 -S ni "hamma o'zgarishlar" deb o'ylash

-S "Osh" narx o'zgarishlarini topmadi — so'z soni o'zgarmagan edi. Qator o'zgarishlarini izlasangiz — -G.

9.5 .git-blame-ignore-revs da qisqa hash

Faylga to'liq, 40 belgili hash yozing. git log --format=%H aynan shuni beradi.

10. Mashqlar

1-mashq (oson): Blame'ni o'qing

text
a2ce4a31 (Jasur Rahimov 2026-10-16 09:00:00 +0500 3)   <p>Osh — 40 000 so'm</p>
^dab5bff (Aziz Karimov  2026-10-01 10:00:00 +0500 1) <h1>Menyu</h1>
  1. Osh qatorini oxirgi marta kim va qachon o'zgartirgan?
  2. ^ belgisi nimani bildiradi?
  3. Commitning to'liq ma'lumotini qanday ko'rasiz?

Ishora: «Birinchi blame» bo'limidagi jadval.

Yechim
  1. Jasur Rahimov, 2026-yil 16-oktabr, soat 09:00 da, a2ce4a31 commitida.
  2. ^dab5bff — tarixning birinchi (ildiz) commiti: undan oldin hech narsa yo'q.
  3. git show a2ce4a31 — xabar, muallif va diff.

2-mashq (o'rta): To'g'ri asbobni tanlang

Bo'sh joylarni to'ldiring:

  1. "Lag'mon narxini haqiqatan kim yozgan, formatlash emas?" — git blame menyu/index.html.
  2. "Somsa so'zi qaysi commitda paydo bo'lgan?" — git log "Somsa" --oneline.
  3. "Osh qatori qanday o'zgarib kelgan?" — git log '/Osh/,+1:menyu/index.html'.
  4. "Aloqa sahifasidagi ish vaqti asli qaysi fayldan?" — git blame aloqa/index.html.

Ishora: dars boshidagi "Qanday savol?" diagrammasi.

Yechim
  1. -w — bo'sh joy o'zgarishlarini chetlab o'tadi; natijada 07b061d7.
  2. -S — bizda f969938 (HEAD -> main) Menyu: somsa narxini qo'sh.
  3. -L — besh commitli ro'yxat, -s bilan qisqa.
  4. -C — 01d072db index.html — bosh sahifadan ko'chirilgan.

3-mashq (qiyin): Formatlashdan keyingi tergov

Jamoada Prettier birinchi marta butun loyihada ishga tushirildi va a1b2c3d Format: Prettier commiti 300 ta faylni o'zgartirdi. Bir hafta o'tib hamma blame'da faqat shu commitni ko'ryapti.

  1. Muammoni jamoa uchun bir marta hal qiladigan fayl nima va unga nima yoziladi?
  2. Har bir dasturchi o'z kompyuterida nima qilishi kerak?
  3. GitHub'da nima o'zgaradi?
  4. Keyingi safar bunday muammo chiqmasligi uchun qanday odat kerak?

Ishora: «.git-blame-ignore-revs — jamoa uchun doimiy yechim» va «GitHub'dagi Blame oynasi» bo'limlari.

Yechim
  1. Loyiha ildizida .git-blame-ignore-revs: izoh qatori va formatlash commitining to'liq hashi (git log --format=%H --grep="Prettier" bilan topiladi). Fayl commit qilinadi.
text
# Prettier bilan butun loyihani formatlash
<40 belgili hash>
  1. Bir marta: git config blame.ignoreRevsFile .git-blame-ignore-revs. Bu local sozlama — repo bilan birga yurmaydi.
  2. Hech narsa qilish shart emas: GitHub ildizdagi faylni o'zi o'qiydi va Blame oynasida banner chiqaradi.
  3. Formatlashni doim alohida commit qilish va darhol hashini ro'yxatga qo'shish. Ko'p jamoalar Prettier'ni commitdan oldin avtomatik ishlatadi — shunda katta "formatlash commitlari" umuman bo'lmaydi. Buni Husky va lint-staged degan vositalar qiladi (Husky va lint-staged darsida o'rganamiz, hozir bilish shart emas).

4-mashq: Portfolio qadami — portfolio'ga blame himoyasi

  1. kurs/portfolio da sayt/index.html ga bir-ikki qator yozing (masalan ismingiz va maqsadingiz) va commit qiling.
  2. Faylni Prettier bilan formatlang (npx prettier --write sayt/index.html — Stylelint va Prettier darsidagi buyruq) va Bosh sahifa: Prettier bilan formatla xabari bilan alohida commit qiling. Prettier hech narsani o'zgartirmasa, qatorlarga qo'lda chekinish qo'shing.
  3. git blame sayt/index.html va git blame -w sayt/index.html ni solishtiring.
  4. .git-blame-ignore-revs yarating, commit qiling va blame.ignoreRevsFile ni sozlang. Oddiy git blame endi nima ko'rsatadi?
  5. Bonus: git log -S "o'z so'zingiz" --oneline bilan bu so'z qaysi commitda paydo bo'lganini toping.

mashqlar repo: shu darsning 1–3-mashq javoblarini mashqlar/07/14-arxeologiya/javoblar.md ga yozing va commit qiling: 07/14: blame va log -S mashqlari javoblarini qo'sh.

Yechim
bash
cd ~/kurs/portfolio
git blame sayt/index.html
git blame -w sayt/index.html
git log --format=%H -1 --grep="Prettier"

Oxirgi buyruq bergan hashni faylga yozing:

text
# Prettier bilan formatlash (faqat chekinish)
aa0e95ef98e6ca8aca64705dd6eac8499a2685f6
bash
git add .git-blame-ignore-revs
git commit -m "Git: formatlash commitini blame'dan yashir"
git config blame.ignoreRevsFile .git-blame-ignore-revs
git blame sayt/index.html
git log -S "Frontend" --oneline

Biz qisqa portfolio'da sinadik (Prettier o'rniga qo'lda chekinish qo'shdik). Formatlashdan keyingi oddiy blame:

text
^63190c1 (Aziz Karimov 2026-10-02 09:00:00 +0500 1) <!DOCTYPE html>
94172b7b (Aziz Karimov 2026-10-19 09:00:00 +0500 2) <main>
aa0e95ef (Aziz Karimov 2026-10-19 09:30:00 +0500 3)   <h1>Aziz Karimov</h1>
aa0e95ef (Aziz Karimov 2026-10-19 09:30:00 +0500 4)   <p>Frontend dasturchi bo'lishni o'rganyapman.</p>
94172b7b (Aziz Karimov 2026-10-19 09:00:00 +0500 5) </main>

Sozlamadan keyingi git blame da 3- va 4-qatorlar ham 94172b7b — haqiqiy yozilgan commit. git log -S "Frontend" esa 94172b7 Bosh sahifa: ism va maqsadni yoz ni topdi. Sizning hashlaringiz boshqa bo'ladi.

.git-blame-ignore-revs endi portfolio bilan birga GitHub'ga ham boradi — u yerdagi Blame oynasi ham formatlash commitini chetlab o'tadi.

11. Real ishda

  • Xato tuzatishdan oldin tajribali dasturchi avval blame qiladi: "bu g'alati kod nega yozilgan?" Ko'pincha commit xabarida sabab bor — masalan "Safari'dagi xato uchun". Uni bilmasdan "tozalab" tashlash eski xatoni qaytaradi.
  • VS Code blame'ni muharrir ichida ko'rsatadigan kengaytmalarga ega (masalan GitLens) — kursor turgan qator yonida muallif va sana chiqadi. Kengaytmalarni tanlashni Kengaytmalar darsida o'rgangansiz.
  • Ko'p katta ochiq loyihalarda .git-blame-ignore-revs fayli bor: bir marta butun kodni formatlagan commit tarixni "yashirmasin". Yangi loyihaga qo'shilganda ildizda shu faylni ko'rsangiz — endi uning vazifasini bilasiz.
  • log -S — xavfsizlik uchun ham. Kimdir tasodifan parol yoki kalitni commit qilib, keyin o'chirgan bo'lsa, git log -S "kalit" uni topadi. Demak u tarixda hali ham bor! Bunday sirni tarixdan butunlay tozalashni Tarixni qayta yozish darsida ko'rasiz.
  • Intervyuda so'rashadi: "Kodda bir qator nega shunday yozilganini qanday bilasiz?" Yaxshi javob: blame → commit → Pull Request muhokamasi.

Xulosa

  • git blame fayl — har qatorni oxirgi o'zgartirgan commit, muallif va sana; -L — faqat kerakli qatorlar.
  • -w bo'sh joyni, .git-blame-ignore-revs formatlash commitlarini chetlab o'tadi; GitHub bu faylni o'zi o'qiydi.
  • -C boshqa fayldan ko'chirilgan qatorlarning asl muallifini topadi.
  • git log -S "matn" — matn paydo bo'lgan yoki yo'qolgan commitlar; -G — matnli qator o'zgargan commitlar.
  • git log -L 'oraliq:fayl' — bitta qator yoki blokning butun tarixi.
  • Blame — kontekst izlash uchun, aybdor izlash uchun emas.

Keyingi dars: Branch nima: arzon ko'rsatkich — HEAD va refs darsidagi yorliqlar bilimi bilan branch yaratish, almashtirish va o'chirishni o'rganamiz.

Manbalar

  • Git hujjati: "git-blame" (-w, -C, --ignore-revs-file, blame.markIgnoredLines), "git-log" (-S, -G, --pickaxe-regex, -L) — git-scm.com/docs
  • GitHub Docs: "Viewing and understanding files" (Blame, .git-blame-ignore-revs) — docs.github.com
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Git blame, log -S va log -L: kod arxeologiyasi — IlmHamroh