Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. Review'da nimaga qarash kerak
- 2.1 Tartib muhim
- 2.2 Qancha va qanchalik tez
- 3. Izoh yozish
- 3.1 Conventional Comments
- 3.2 Savol shaklida va sababi bilan
- 3.3 Izoh belgisini kod bilan tekshirish
- 4. Kanon tajribasi: PR #9 dagi review
- 4.1 Vaziyat
- 4.2 To'rtta izoh
- 4.3 Umumiy review va o'z PR'ini tasdiqlash
- 4.4 Muallif javoblari
- 4.5 Ochiq muhokama bilan merge
- 5. Suggestion bilan muammo:
- 6. Review olish: muallif tomoni
- 6.1 Javob berish naqshlari
- 6.2 Izoh — kodga, sizga emas
- 6.3 Ikkinchi review: git range-diff
- 6.4 Push qilishdan oldin — o'zingiz review qiling
- 7. Qachon tasdiqlash kerak
- 8. Hujumchi nigohi
- 9. Loyiha qadami: «Review madaniyati» bo'limi
- 10. Ko'p uchraydigan xatolar
- 10.1 Uslub haqida bahs
- 10.2 Belgisiz izoh
- 10.3 PR'ni review'da kattalashtirish
- 10.4 Muallif muhokamani o'zi yopadi
- 10.5 Force push'dan keyin hammasini qayta o'qish
- 10.6 Review kutib turish
- 11. Mashqlar
- 1-mashq (oson): bo'shliqlarni to'ldiring
- 2-mashq (o'rta): review xulosasi
- 3-mashq (qiyin): ikkinchi review'ni qisqartiring
- 12. Real ishda
- Xulosa
- Manbalar
Code review berish va olish: nimaga qarash, qanday yozish, qachon tasdiqlash
Qisqacha: Code review — kod
mainga tushishidan oldin boshqa odam uni o'qib, savol va taklif qoldirishi. Yaxshi reviewer avval to'g'rilik, xavfsizlik va testlarga qaraydi, uslubni esa linterga qoldiradi. Har izohga belgi qo'yadi:muammo:(merge'dan oldin tuzatish shart),taklif:,savol:,nit:(mayda),maqtov:— shunda muallif nima majburiy ekanini darhol ko'radi. Muallif har izohga javob beradi, katta taklifni alohida issue'ga chiqaradi, tuzatishdan keyin reviewergit range-diffbilan faqat o'zgargan joyni o'qiydi. Kurs tajribasida bitta PR'ga 4 ta qator izohi yozildi, muhokamalar yopilmaguncha GitHub merge'ni rad etdi.
Bu darsda
- Review'da nimaga va qaysi tartibda qarashni bilasiz.
- Izohni Conventional Comments belgilari bilan, savol shaklida va sababi bilan yozasiz.
- Kurs sinov reposidagi haqiqiy review'ni boshidan oxirigacha o'qiysiz.
- Muallif sifatida izohlarga javob berasiz va
git range-diffbilan ikkinchi review'ni qisqartirasiz. - Tasdiqlash (approve) mezonlarini
CONTRIBUTING.mdga yozasiz.
Oldin bilishingiz kerak: GitHub'da code review amaliyoti, Yaxshi PR tayyorlash, Interaktiv rebase: PR'dan oldin tarixni tozalash, Branch himoyasi va rulesets.
1. Nega bu kerak?
GitHub'da code review amaliyoti darsida tugmalarni o'rgandik: qatorga izoh, suggestion bloki, Approve, Request changes. Tugmani bosish oson. Qiyini — nimani yozish.
Tasavvur qiling. Aziz Nodiraning PR'iga uchta izoh yozdi: "bu yomon", "nomini o'zgartir", "nega bunday?". Nodira kechgacha hammasini tuzatdi. Keyin bilsa, ikkitasi shunchaki Azizning didi ekan. Asl xato — bazadagi qulf muammosi — umuman tilga olinmagan. Ikki kishining bir kuni ketdi, xato esa main ga o'tib ketdi.
Review'ning qiymati izohlar sonida emas. U uch savolga javob beradi:
- Bu kod to'g'ri ishlaydimi va hech narsani buzmaydimi?
- Keyingi odam uni tushunadimi?
- Jamoa bu PR'dan nimadir o'rgandimi?
Hayotiy o'xshatish: shifokorlar konsiliumi. Ikkinchi shifokor bemorning rentgenini ko'radi. U birinchisining yozuv uslubini tuzatmaydi — tashxisni tekshiradi. Kelishmasa, "menimcha, bu yerda boshqa narsa bor, tahlil qilib ko'raylikmi?" deydi. Hurmat bilan, aniq va bemor foydasi uchun.
Code review (kod ko'rib chiqish) — PR'dagi o'zgarishni boshqa dasturchi o'qib, merge'dan oldin savol, taklif va qaror qoldirishi. Bu darsda — jarayonning odam tomoni: nimaga qarash, qanday yozish, qanday qabul qilish.
2. Review'da nimaga qarash kerak
2.1 Tartib muhim
Reviewer'ning vaqti cheklangan. Shuning uchun eng qimmat xatolardan boshlanadi:
| Navbat | Savol | Misol |
|---|---|---|
| 1. To'g'rilik | Vazifani bajaradimi, chekka holatlar? | null, bo'sh ro'yxat, 31-kun |
| 2. Xavfsizlik va ma'lumot | Sir, huquq, migratsiya xavfi bormi? | qulf, DELETE shartsiz |
| 3. Testlar | Xulq testlanganmi, test yiqila oladimi? | regressiya testi |
| 4. Dizayn | Kod to'g'ri joydami, ortiqcha murakkabmi? | yangi klass kerakmi |
| 5. O'qilishi | Nomlar, izohlar, tuzilma | x2 o'rniga qoldiq |
| 6. Uslub | Bo'shliq, qo'shtirnoq | — linter qiladi |
Oxirgi qatorga qarang. Bo'shliq va qo'shtirnoq haqida odam izoh yozmasligi kerak. Buni ESLint va Prettier npm run lint da qiladi. Mashina qila oladigan ishni odam qilmasin — reviewer diqqati muhim narsaga qolsin.
Google'ning ochiq "Code Review Developer Guide" qo'llanmasida ham shunday ro'yxat bor (google.github.io/eng-practices, 2026-11-04 da ochib o'qildi). Unda dizayn, funksionallik, murakkablik, testlar, nomlash, izohlar, uslub, izchillik va hujjatlar, oxirida esa "yaxshi joylar" bandi bor. Google dizayndan boshlaydi, biz to'g'rilikdan — tartibni jamoa tanlaydi. Oxirgi bandga e'tibor bering: yaxshi qilingan joyni ham aytish kerak.
2.2 Qancha va qanchalik tez
Review sifati PR hajmiga bog'liq. 50 qatorni sinchiklab o'qishadi, 2 000 qatorni — yuzaki. Kanon loyihasining CONTRIBUTING.md faylida chegara yozilgan: taxminan 200–400 qator o'zgarish, kattasi bir nechta ketma-ket PR'ga bo'linadi (Yaxshi PR tayyorlash darsi).
Tezlik ham muhim. PR uch kun kutsa, muallif boshqa ishga o'tadi, konteksti yo'qoladi, main oldinga ketadi. Kanon kelishuvi: 1 ish kuni ichida javob. Bu "1 kunda tasdiqlash" degani emas. "Ko'rdim, ertaga tushdan keyin chuqur o'qiyman" degan qisqa javob ham hisob.
Tekshirib ko'ring: PR'da 3 ta muammo bor: SQL so'rovida foydalanuvchi filtri yo'q, bitta o'zgaruvchi nomi noaniq, bir joyda qo'shtirnoq aralash. Qaysi biriga birinchi izoh yozasiz, qaysi biriga umuman yozmaysiz?
Javob
Birinchi — filtr yo'qligi: bu xavfsizlik va to'g'rilik masalasi, bir foydalanuvchi boshqasining ma'lumotini ko'rishi mumkin. Nom — nit: darajasidagi izoh. Qo'shtirnoq — izoh yozilmaydi: linter yoki Prettier bunga javob beradi. Agar linter uni ushlamagan bo'lsa, linter sozlamasini tuzatish kerak, har PR'da qo'lda aytish emas.
3. Izoh yozish
3.1 Conventional Comments
Izoh o'qilganda muallifning birinchi savoli: "Buni tuzatishim shartmi?" Javob izohning boshida tursin. Buning uchun Conventional Comments kelishuvi bor (conventionalcomments.org, 2026-11-04 da ochib o'qildi):
<belgi> [bezaklar]: <mavzu>
[muhokama]Asl belgilar inglizcha: praise, nitpick, suggestion, issue, todo, question, thought, chore, note. Bezak (decoration) — qavs ichidagi aniqlik: (blocking) — merge'ni to'xtatadi, (non-blocking) — to'xtatmaydi, (if-minor) — "o'zgarish kichik bo'lsa, tuzating".
Kanon loyihasi ularning o'zbekcha qisqa to'plamini oldi:
| Belgi | Ma'nosi | Merge'ni to'xtatadimi |
|---|---|---|
muammo: |
xato, xavf — tuzatish shart | ha |
taklif: |
yaxshiroq yo'l bor | yo'q |
savol: |
tushunmadim, tushuntiring | javobgacha — ha |
nit: |
mayda, did masalasi | yo'q |
maqtov: |
yaxshi qilingan joy | yo'q |
nit — inglizcha nitpick ("mayda-chuyda topish") so'zidan. "nit: bu yerda bo'sh qator ortiqcha" — muallif xohlasa tuzatadi, xohlamasa yo'q.
savol: alohida o'rinda. U o'zi to'xtatmaydi, lekin ruleset muhokama yopilishini talab qilsa (Branch himoyasi darsi), javobsiz savol merge'ni ushlab turadi. Pastda kanon tajribasida buni ko'ramiz.
3.2 Savol shaklida va sababi bilan
Bir xil fikrni ikki xil yozish mumkin:
| Buyruq | Savol va sabab |
|---|---|
| "Bu xato." | "savol: muddat bo'lmasa nima qaytadi? undefined < bugun — false, bu ataylabmi?" |
| "Konstantaga chiqar." | "taklif: 4 ni BELGI_TOKEN deb nomlasak, keyingi odam nega 4 ekanini biladi." |
| "Yaxshi." | "maqtov: sukut qiymati raqamlar bilan asoslangan — review'da savol qolmadi." |
Savol shakli ikki narsa beradi. Birinchidan, siz ham adashishingiz mumkin — balki muallif bilgan narsani siz bilmaysiz. Ikkinchidan, muallif himoyaga o'tmaydi, o'ylaydi. "Biz" va "-sak" ("chiqarsak") shakli ham shu uchun: kod jamoaniki.
Sabab — eng muhim qism. "Konstantaga chiqar" o'rgatmaydi. "Chunki keyingi odam nega 4 ekanini bilmaydi" — o'rgatadi, keyingi PR'da muallif buni o'zi qiladi.
3.3 Izoh belgisini kod bilan tekshirish
Belgi qo'yilgan izohni dastur ham tushunadi. Quyidagi funksiya izoh boshidagi belgini o'qib, merge'ni to'xtatadimi — shuni aytadi:
const TOXTATADI = new Set(["muammo", "savol"]);
const BELGILAR = ["muammo", "taklif", "savol", "nit", "maqtov"];
function izohniOqi(matn) {
const m = matn.match(/^\*{0,2}([a-z']+)\*{0,2}:/);
const belgi = m && BELGILAR.includes(m[1]) ? m[1] : "belgisiz";
return { belgi, toxtatadi: TOXTATADI.has(belgi) };
}
console.log(izohniOqi("**savol:** Map chegarasiz o'sadimi?"));
console.log(izohniOqi("nit: bo'sh qator ortiqcha"));
console.log(izohniOqi("Bu yomon."));Konsolda:
{ belgi: 'savol', toxtatadi: true }
{ belgi: 'nit', toxtatadi: false }
{ belgi: 'belgisiz', toxtatadi: false }Uchinchi qatorga e'tibor bering: "Bu yomon." belgisiz — dastur ham, muallif ham uning og'irligini bilmaydi. 2-mashqda shu funksiyadan butun review xulosasini chiqarasiz.
Tekshirib ko'ring: "nit: bu funksiya foydalanuvchi parolini log'ga yozyapti" — belgida nima xato?
Javob
Parol log'ga tushishi — xavfsizlik muammosi, mayda emas. Belgi muammo: bo'lishi kerak. nit: deb yozilsa, muallif uni ixtiyoriy deb o'tkazib yuborishi mumkin. Belgi izohning og'irligini aytadi — u to'g'ri tanlanmasa, butun tizim yolg'on gapiradi.
4. Kanon tajribasi: PR #9 dagi review
4.1 Vaziyat
Bisect darsida 31-qism nuqsonlari bitta commitda yopilgan edi. Kanon uni sinov reposida PR #9 orqali yubordi: 19 fayl, +457 / −54 qator (github.com/Sarvarbek0704/ilmhamroh-git-sinov/pull/9). Sinov reposida loyiha vazifalar-api/ papkasida turadi — repo 07-qism sayti bilan umumiy.
Kanon PR'ni reviewer ko'zi bilan o'qib, kodning aniq qatorlariga to'rtta izoh qoldirdi. Izohlar gh api bilan yuborildi; matni pastda — aynan.
4.2 To'rtta izoh
src/ai/chidamli.ts, 59-qator — breaker'lar Map i:
**savol:** `#breakerlar` Map'i chegarasiz o'sadimi? Agar model nomi so'rovdan (foydalanuvchidan) kelsa, har yangi nom — yangi yozuv, xotira sizishi. Hozir kalitlar faqat config'dan (`AI_MODEL`, `AI_ZAXIRA_MODEL`, `embedding`) kelishini to'g'ri tushundimmi?Bu — xavfsizlik savoli. Kalit tashqaridan kelsa, hujumchi har so'rovda yangi model nomi yuborib, xotirani to'ldirishi mumkin. Izoh ayblamaydi: "to'g'ri tushundimmi?" deb so'raydi.
src/ai/qadamlar.ts, 196-qator — token taxmini:
**taklif:** 4 belgi = 1 token inglizcha uchun o'rtacha. 31-qism #13 o'lchovida o'zbekcha matn ~1.7× ko'p token oldi — demak taxmin kvotani kamroq yeydi. `BELGI_TOKEN = 4` deb nomlab, izohda shu raqamni yozib qo'ysak — keyingi odam o'zgartirishni biladi. Merge'ga to'sqinlik qilmaydi.Oxirgi gap — "merge'ga to'sqinlik qilmaydi". Belgi buni allaqachon aytgan, lekin ochiq yozish ortiqcha emas.
Migratsiya fayli, 17-qator — LOCK TABLE … IN EXCLUSIVE MODE:
**savol:** `EXCLUSIVE` qulf ko'chirish davomida DEFAULT'ga yozuvchilarni to'xtatadi. DEFAULT'da qatorlar ko'p bo'lsa (masalan oylab soat noto'g'ri bo'lgan bo'lsa) qancha vaqt? Cron 03:00 da — yuk past, lekin o'lchov bormi?Bu — ma'lumot xavfi savoli: qulf qancha ushlanadi? "O'lchov bormi?" — raqam so'raydi, fikr emas.
src/ai/ai.module.ts, 42-qator — deadline sukuti:
**maqtov:** sukut qiymatining asoslanishi raqamlar bilan (60.9 s / 121.8 s, jonli 0.9–1.8 s) — review'da "nega 25?" degan savolga javob shu yerda. Shunday qoldiring.Maqtov — bezak emas. U muallifga "aynan shu odatni davom ettir" deydi. Keyingi PR'da ham sukut qiymatlari asoslangan bo'ladi.
4.3 Umumiy review va o'z PR'ini tasdiqlash
Qator izohlaridan keyin umumiy review keladi. Avval kanon gh pr review 9 --approve -b 'LGTM' bilan tasdiqlashga urindi. Javob — "Can not approve your own pull request" (to'liq chiqishni Jamoa workflow'lari darsida ko'rgansiz). LGTM — Looks Good To Me, "menimcha yaxshi": tasdiqdagi eng qisqa izoh. Sinov reposida bitta akkaunt bor — muallif ham, reviewer ham o'sha. Shuning uchun u yerda ruleset'dagi tasdiqlar soni 0. Jamoada esa kamida 1 tasdiq va CODEOWNERS review (Git va monorepo darsi).
Tasdiq o'rniga umumiy izoh (Comment) yuborildi:
Umumiy: o'zgarish bitta mavzuda (31 nuqsonlari), har tuzatishga test bor, bisect jurnali PR tavsifida — review oson bo'ldi.
- **muammo** yo'q.
- 2 ta **savol** (Map hajmi, qulf vaqti) — javobdan keyin muhokamalarni yopaman.
- 1 ta **taklif** (token konstantasi) — ixtiyoriy, alohida issue bo'lishi mumkin.
Tasdiqlay olmayman (o'z PR'im — GitHub ruxsat bermaydi), shuning uchun ruleset'da talab qilingan tasdiqlar soni 0; jamoada — kamida 1.Umumiy izohning tuzilishini o'qing: birinchi gap — PR'ning kuchli tomoni; keyin izohlar soni va og'irligi bo'yicha jamlangan. Muallif bitta qarashda biladi: majburiy narsa yo'q, ikki savolga javob kerak.
4.4 Muallif javoblari
Muallif uch izohga javob berdi. Map haqidagi savolga:
Ha, kalitlar faqat config'dan: `s.model` ni faqat `ZaxiraliProvayder` qo'yadi (`AI_ZAXIRA_MODEL`), so'rov tanasida model maydoni yo'q. Agar keyin foydalanuvchiga model tanlash berilsa — avval ruxsat ro'yxati, shunda Map ham chegaralanadi. Hozircha 3 ta kalit.Qulf haqidagi savolga:
O'lchov: lokal tajribada (2 qator) qulf ko'zga ko'rinmaydigan darajada qisqa; ko'p qatorli holat O'LCHANMAGAN. Amalda DEFAULT bo'sh turishi kerak — endi bo'lim xatosi metrikaga chiqadi (`fon_ishlari_xatolari_jami`), ya'ni DEFAULT to'lib ketishidan oldin alert keladi. Katta DEFAULT uchun ko'chirishni paketlarga bo'lish — alohida ish, hozir kerak emas.E'tibor bering: "ko'p qatorli holat O'LCHANMAGAN". Muallif bilmaganini yashirmadi. Bu — yaxshi javobning belgisi: nima tekshirilgan, nima yo'q, xavf qanday kuzatiladi.
Taklifga esa muallif kod o'zgartirmadi. Avval alohida issue ochdi (#10, "refactor(ai): token taxmini — nomlangan konstanta va o'zbekcha koeffitsient"), keyin javob yozdi:
Rozi, lekin bu PR doirasidan tashqari — alohida issue ochdim ("refactor(ai): token taxmini…").Bu — muhim naqsh. Review'da kelgan har yaxshi g'oya shu PR'da bajarilishi shart emas. Aks holda PR o'sib boradi, review qayta boshlanadi, merge kunlab cho'ziladi. G'oya yo'qolmasin — issue'ga yoziladi.
4.5 Ochiq muhokama bilan merge
Javoblar yozildi, lekin muhokamalar hali yopilmagan. Kanon gh pr merge 9 --squash ga urindi va "is not mergeable: the base branch policy prohibits the merge" ("PR merge qilinmaydi: asosiy branch siyosati taqiqlaydi") javobini oldi. Bu chiqishni ham Jamoa workflow'lari darsida o'qigansiz; endi uning sababini review tomondan ko'ramiz. Sabab — ruleset'dagi required_review_thread_resolution parametri: hamma muhokamalar (review thread — izoh va unga javoblar zanjiri) hal qilingan bo'lishi shart.
Kanon to'rtta muhokamani GraphQL resolveReviewThread so'rovi bilan yopdi (har biriga true qaytdi) va squash merge o'tdi:
{"commit":"22a1226","mergedAt":"2026-11-03T19:21:42Z","state":"MERGED"}Sinov reposida "muhokamani yopish"ni ham muallifning o'zi qildi — boshqa odam yo'q edi. Jamoada qoida boshqacha: "hal qilindi"ni izoh egasi bosadi. Savol bergan odam javobni o'qib, rozi bo'lgandagina yopadi. Muallif o'zi yopsa, savol "javob berildi" emas, "yashirildi" bo'lib qoladi.
Butun aylanish bitta rasmda:
flowchart TD
A[PR ochildi] --> B[Reviewer: qator izohlari]
B --> C{muammo yoki savol bormi?}
C -->|yo'q| D[Approve]
C -->|ha| E[Muallif: javob yoki tuzatish]
E --> F{Taklif katta?}
F -->|ha| G[Alohida issue]
F -->|yo'q| H[Push, range-diff]
G --> I[Izoh egasi yopadi]
H --> I
I --> C
D --> J[Squash merge]Diagrammadagi halqa — C → E → I → C. Har aylanishda ochiq savollar kamayadi. Tasdiq faqat ular tugaganda.
Tekshirib ko'ring: Reviewer
savol:yozdi. Muallif javob yozdi va darhol o'zi "Resolve conversation" ni bosdi. Ruleset endi merge'ga ruxsat beradi. Texnik jihatdan hammasi joyida — jarayonda nima noto'g'ri?
Javob
Savol bergan odam javobni hali o'qimagan. Muhokama "javob berildi" emas, "yopib qo'yildi" holatida: reviewer rozi bo'lmasligi mumkin edi. GitHub hujjatiga ko'ra PR muallifi ham, repoga yozish huquqi bor har kim ham muhokamani yopa oladi (docs.github.com, "Commenting on a pull request", 2026-11-04). Ruleset faqat "yopilganmi" deb tekshiradi, kim yopganini emas — shuning uchun bu qoida jamoa kelishuvi bilan ushlanadi: yopishni izoh egasi bosadi.
5. Suggestion bilan muammo:
Ikkinchi misol — README qayta tuzilgan PR #15 (README va loyiha hujjatlari darsida shu PR'ni yozamiz). Reviewer 57-qatorda haqiqiy xato topdi:
**muammo:** `package.json` da `"license": "MIT"`, lekin repoda (vazifalar-api ichida) `LICENSE` fayli YO'Q. Litsenziya matnisiz "MIT" deyish yetarli emas — MIT'ning yagona sharti: mualliflik huquqi va ruxsat matni nusxalarda saqlansin. Taklif:
```suggestion
MIT — [LICENSE](LICENSE).
```Izohning tuzilishi namunali: belgi (muammo:), fakt (package.json da MIT, fayl yo'q), nega muhim (MIT sharti), tayyor tuzatish (suggestion bloki — GitHub'da code review darsidan). Muallif tugmani bosib qabul qilishi mumkin edi.
Lekin muallif boshqacha javob berdi:
Topilma to'g'ri. LICENSE fayli va litsenziya tanlovi — alohida PR (open source darsi bilan birga), suggestion o'sha PR bilan qo'llanadi: bu PR faqat README tuzilishi. Issue ochdim.Nega? Suggestion faqat README'dagi bitta qatorni tuzatadi. Haqiqiy muammo — LICENSE faylining yo'qligi — boshqa ish: litsenziya tanlash, matnni qo'shish. Agar suggestion hozir qabul qilinsa, README mavjud bo'lmagan faylga havola beradi. Muallif issue #16 ochdi, u keyinroq litsenziya PR'ida yopildi.
Saboq: muammo: har doim "shu PR'da tuzat" degani emas. Ba'zan to'g'ri javob — "topilma to'g'ri, mana issue". Muhimi — muammo yo'qolmadi va izoh egasi bilan kelishildi.
6. Review olish: muallif tomoni
6.1 Javob berish naqshlari
Har izohga javob bo'lsin. Javobsiz izoh reviewer uchun "o'qimadi" degani. Kanon tajribasidagi uch naqsh:
| Vaziyat | Javob |
|---|---|
| Rozisiz, tuzatdingiz | "Tuzatdim — edbf6e9." (commit bilan) |
| Rozisiz, lekin doiradan tashqari | "Rozi, alohida issue ochdim (#10)." |
| Rozi emassiz | Sabab va dalil: o'lchov, hujjat, test |
Uchinchi qator eng qiyini. "Men shunday xohlayman" — dalil emas. "Bu yerda Map chegaralangan, chunki kalitlar faqat config'dan" — dalil. Kelisha olmasangiz, uchinchi odamni chaqiring yoki qisqa qo'ng'iroq qiling. Kelishilgan qarorni esa PR'ga yozib qo'ying (Jamoada muloqot darsida).
6.2 Izoh — kodga, sizga emas
Birinchi review'lar og'ir botishi tabiiy. O'n izoh — "men yomon dasturchiman" degani emas. Bu kod ikkinchi ko'zdan o'tdi va yaxshilandi degani. Tajribali dasturchilarning PR'lariga ham izohlar keladi. Kanon PR'ining o'zida to'rtta izoh bor edi — va u yaxshi PR edi.
Ikki amaliy odat yordam beradi:
- Darhol javob yozmang. Izoh achchiq tuyulsa, avval tuzatishni qiling, javobni keyin yozing.
- Ohangni emas, mazmunni o'qing. "Bu xato" deb yozgan reviewer ham ko'pincha haq. U ohangni bilmasligi mumkin — buni keyinroq, alohida, xushmuomalalik bilan aytish mumkin.
6.3 Ikkinchi review: git range-diff
Muallif izohlar bo'yicha tuzatdi va tarixni tozaladi — --fixup va rebase --autosquash bilan (Interaktiv rebase darsi), keyin git push --force-with-lease (Ajralgan tarix darsi). Reviewer endi nimani o'qiydi? Butun PR'ni qaytadanmi?
Yo'q. git range-diff ikki versiyadagi commitlarni juftlab, faqat farqni ko'rsatadi. Kichik o'quv repo'da sinab ko'ramiz. pr-yarat.sh skripti (mashq papkasida) uchta papka yaratadi: markaz.git (GitHub o'rnida), nodira (PR muallifi) va aziz (reviewer). Skript muallif va sanalarni qotiradi — SHA'lar sizda ham bir xil chiqadi.
Avval Aziz PR'ni o'qiydi:
bash pr-yarat.sh pr && cd pr/aziz
git log --oneline main..origin/fix/muddat
git diff --stat main...origin/fix/muddat6a63fef (origin/fix/muddat) test: bajarilgan vazifa
7c3e768 fix: bajarilgan vazifa kechikkan hisoblanmaydi
muddat.js | 1 +
muddat.test.js | 3 +++
2 files changed, 4 insertions(+)Ikki commit: tuzatish va test. Aziz taklif: yozdi: "bajarilmagan vazifa uchun ham test qo'shsak — ikki tomonni tekshiradi". Nodira testga ikkinchi holatni qo'shib, --fixup qildi, autosquash va force push. Aziz yangiladi:
git fetch origin
git range-diff main origin/fix/muddat@{1} origin/fix/muddatBiz ishga tushirdik (fetch chiqishidan faqat yangilangan branch qatori qoldirildi — From … qatorida kompyuterdagi yo'l bor edi):
+ 6a63fef...edbf6e9 fix/muddat -> origin/fix/muddat (forced update)
1: 7c3e768 = 1: 7c3e768 fix: bajarilgan vazifa kechikkan hisoblanmaydi
2: 6a63fef ! 2: edbf6e9 test: bajarilgan vazifa
@@ muddat.test.js (new)
+import { kechikkanmi } from "./muddat.js";
+const v = { muddat: "2026-11-01", bajarildi: true };
+console.log(kechikkanmi(v, "2026-11-02") === false ? "ok" : "XATO");
++const w = { muddat: "2026-11-01", bajarildi: false };
++console.log(kechikkanmi(w, "2026-11-02") === true ? "ok" : "XATO");Qanday o'qiladi:
origin/fix/muddat@{1}— reflog'dagi oldingi qiymat, ya'ni force push'dan oldingi versiya. Uch argument: umumiy asos (main), eski uch, yangi uch.=— commit mazmuni o'zgarmagan. Birinchi commitni qayta o'qish shart emas.!— o'zgargan. Pastida "diff'ning diff'i": birinchi ustundagi+yangi versiyada qo'shilgan qatorni bildiradi.
Aziz faqat ikki qatorni o'qidi. Katta PR'da bu soatlarni tejaydi.
GitHub'da ham yordam bor: PR lentasida force push yozuvi chiqadi, undagi "force-pushed" havolasi eski va yangi uchni solishtiradi (GitHub changelog, 2018-11-15; 2026-11 holatida docs.github.com da alohida sahifa topilmadi). Lekin u ikki uchning oddiy diff'i: shu orada main dan rebase qilingan bo'lsa, main dagi begona o'zgarishlar ham aralashib chiqadi. range-diff esa commitlarni juftlab, faqat PR ichidagi farqni ko'rsatadi.
Maslahat: Commit juda kichik bo'lsa va ko'p o'zgarsa,
range-diffuni "o'chirildi" (<) va "yangi" (>) deb ikki qatorda ko'rsatishi mumkin — biz 3-mashqda aynan shunday chiqishni oldik.--creation-factor(sukut — 60, Git 2.54 hujjati) qanchalik o'zgargan commitni "o'sha commit" deb hisoblashni belgilaydi;--creation-factor=100ularni juftlashga undaydi.
6.4 Push qilishdan oldin — o'zingiz review qiling
Eng arzon review — o'zingizniki. PR ochishdan oldin git diff main... ni boshidan oxirigacha o'qing, xuddi begona kodni o'qigandek. Unutilgan console.log, izohga olingan kod, tasodifiy fayl shu yerda chiqadi. Yaxshi PR tayyorlash darsida buni self-review deb atadik.
7. Qachon tasdiqlash kerak
Approve — "men bu kodni main da ko'rishga roziman" degani. Kanon CONTRIBUTING.md sidagi mezon to'rt banddan iborat:
- To'g'ri ishlaydi (tavsifdagi vazifani bajaradi).
- Test bor (xato tuzatilgan bo'lsa — avval yiqiladigan regressiya testi).
- Xavfsizlik va ma'lumotlarga xavf yo'q.
- Keyingi odam tushunadi.
Ro'yxatda "menga yoqadi" yo'q. Google qo'llanmasi ("The Standard of Code Review", 2026-11-04 da ochib o'qildi) buni shunday aytadi: PR kodning umumiy holatini yaxshilasa — tasdiqlang, hatto mukammal bo'lmasa ham. Sababi: "there is no such thing as "perfect" code—there is only better code" — "mukammal kod yo'q, faqat yaxshiroq kod bor". Mukammallik kutsangiz, hech narsa merge bo'lmaydi.
Uch holat amalda:
| Holat | Qaror |
|---|---|
Faqat nit: va taklif: |
Approve (izohlar bilan) |
savol: bor, javob muhim |
Comment, javobdan keyin Approve |
Kamida bitta muammo: |
Request changes |
nit: lar bilan Approve qilish odobli. Muallif ularni tuzatadi yoki yo'q — merge'ni kutib turish shart emas.
Tekshirib ko'ring: Reviewer PR'ni o'qib chiqdi, hech qanday izoh yozmadi va darhol Approve bosdi. PR 1 200 qator. Bu yaxshi review'mi?
Javob
Ehtimol yo'q. 1 200 qatorni izohsiz tasdiqlash ko'pincha "o'qimadim, lekin ishonaman" degani — buni ba'zan "rubber stamp" (muhr bosish) deyishadi. To'g'ri yo'l: PR'ni bo'lishni so'rash yoki qaysi qismlarni chuqur o'qiganini yozish ("migratsiya va servisni o'qidim, UI'ga qaramadim"). Tasdiq — mas'uliyat: xato chiqsa, reviewer ham "ko'rgan" bo'ladi.
8. Hujumchi nigohi
Review — faqat sifat emas, xavfsizlik darvozasi ham. Hujumchi zararli kodni PR orqali kiritishga urinadi: ochiq loyihaga hissa qo'shuvchi sifatida yoki buzilgan akkaunt orqali.
Qayerga qaraydi:
- Lock fayl va bog'liqliklar.
package-lock.jsonda paket manzili begona registrga almashtirilgan, yoki yangi kichik paket qo'shilgan. Reviewer'lar lock faylni odatda o'qimaydi — hujumchi shuni biladi. - CI fayllari.
.github/workflows/dagi o'zgarish sirlarni tashqariga yuborishi mumkin. Kanon loyihasida bunday fayllar CODEOWNERS orqali alohida egaga bog'langan. - Ko'rinmas belgilar. Unicode yo'nalish belgilari kodni ekranda bir xil, kompilyatorda boshqacha ko'rsatadi — "Trojan Source" hujumi, CVE-2021-42574; o'xshash ko'rinadigan boshqa alifbo harflari bilan varianti — CVE-2021-42694 (trojansource.codes, 2026-11-04 da ochib o'qildi). GitHub 2021-yil oktabrdan beri faylda yo'nalish belgilari bo'lsa ogohlantirish ko'rsatadi (GitHub changelog, 2021-10-31).
Himoya: lock fayl va CI o'zgarishiga alohida reviewer, bog'liqlik qo'shilsa — "nega aynan shu paket?" savoli, muammo: belgisi bilan.
9. Loyiha qadami: «Review madaniyati» bo'limi
Yaxshi PR tayyorlash darsida CONTRIBUTING.md ning boshi va «Ish oqimi» bo'limini yozgan edingiz. Endi shu faylga review qoidalarini qo'shamiz. Kanon faylidan aynan — «Ish oqimi» dan keyin:
## Review madaniyati
- Izoh — kodga, odamga emas. Savol shaklida yozing: "Bu yerda `null` kelishi mumkinmi?" — "Bu xato" dan yaxshiroq.
- Muhimligini belgilang ([Conventional Comments](https://conventionalcomments.org/)): `muammo:` (merge'dan oldin tuzatish shart), `taklif:`, `savol:`, `nit:` (mayda, ixtiyoriy), `maqtov:`.
- 1 ish kuni ichida javob bering. Tasdiq mezoni: to'g'ri ishlaydi, test bor, xavfsizlik va ma'lumotlarga xavf yo'q, keyingi odam tushunadi.Uch qator — bu darsning qisqa mazmuni. Uzun qoidalar o'qilmaydi; qisqasi har PR'da eslanadi.
Tekshiring: fayl docs/hissa-qoshish branch'ida, git status da CONTRIBUTING.md o'zgargan.
git switch docs/hissa-qoshish
git status --shortHali commit qilmang. Keyingi darsda CONTRIBUTING.md ning qolgan bo'limlari, SECURITY.md va README qo'shiladi — keyin ikki PR bilan yuboramiz.
10. Ko'p uchraydigan xatolar
10.1 Uslub haqida bahs
Review'da 20 ta izoh, hammasi bo'shliq va qo'shtirnoq haqida. Davosi: Prettier va ESLint qoidalarini bir marta kelishib, npm run lint ga qo'ying. Linter qoidasi bo'lmagan did masalasi — faqat nit:.
10.2 Belgisiz izoh
"Bu yerni o'zgartirish kerak" — majburiymi, ixtiyoriymi? Muallif bilmaydi, hammasini tuzatadi yoki hammasini e'tiborsiz qoldiradi. Davosi: har izohga belgi.
10.3 PR'ni review'da kattalashtirish
"Shu yerda turganingda, X ni ham qayta yozib yubor". PR ikki baravar o'sadi, review boshidan boshlanadi. Davosi: kanondagidek — "rozi, alohida issue".
10.4 Muallif muhokamani o'zi yopadi
Savolga javob yozib, darhol "Resolve" bosish. Reviewer javobni ko'rmaydi ham. Davosi: yopishni izoh egasiga qoldiring. Ruleset muhokama yopilishini talab qilsa — bu yanada muhim.
10.5 Force push'dan keyin hammasini qayta o'qish
Reviewer ikkinchi aylanishda butun PR'ni yana o'qiydi va charchaydi. Davosi: git range-diff yoki GitHub lentasidagi "force-pushed" havolasi.
10.6 Review kutib turish
PR uch kun javobsiz. Davosi: jamoa kelishuvi (1 ish kuni), kun boshida va tushdan keyin review uchun vaqt ajratish. Muallif ham reviewer'ni aniq so'rasin — "kimdir ko'rar" degan PR hech kimga tegishli emas.
11. Mashqlar
Mashqlar kurs/mashqlar/32/11-review/ da. 2-mashq yechimi Node 24.21.0 da, 3-mashq yechimi Git 2.54.0 da tekshirilgan (biz ishga tushirdik).
1-mashq (oson): bo'shliqlarni to'ldiring
- Merge'dan oldin tuzatilishi shart bo'lgan izoh belgisi —
- Mayda, ixtiyoriy izoh belgisi —
- Force push'dan oldingi va keyingi commitlarni juftlab solishtiradigan buyruq —
git range-diffchiqishida "mazmun o'zgarmagan" belgisi —- Hamma muhokamalar hal bo'lishini talab qiladigan ruleset parametri —
Yechim
- muammo — xato yoki xavf; to'xtatadi.
- nit — nitpick; muallif xohlasa tuzatadi.
- range-diff —
git range-diff main eski-uch yangi-uch. - = —
!esa "o'zgargan",</>— "o'chgan" / "yangi". - required_review_thread_resolution — kanon ruleset'ida yoqilgan; shuning uchun PR #9 merge'i bir marta rad etildi.
2-mashq (o'rta): review xulosasi
reviewXulosasi(izohlar) funksiyasini yozing. izohlar — { matn, yopilgan } obyektlari. Funksiya qaytarsin: qaror — kamida bitta yopilmagan muammo: bo'lsa "Request changes", aks holda yopilmagan savol: bo'lsa "Comment", aks holda "Approve"; va soni — har belgi nechta (yopilgan-yopilmaganidan qat'i nazar). Belgini «Izoh belgisini kod bilan tekshirish» bo'limidagi izohniOqi() dagidek o'qing. Ishora: sanash uchun reduce va obyekt (massiv metodlari); shartlar uchun some.
Yechim
const BELGILAR = ["muammo", "taklif", "savol", "nit", "maqtov"];
function belgiOl(matn) {
const m = matn.match(/^\*{0,2}([a-z']+)\*{0,2}:/);
return m && BELGILAR.includes(m[1]) ? m[1] : "belgisiz";
}
function reviewXulosasi(izohlar) {
const ochiq = izohlar
.filter((i) => !i.yopilgan)
.map((i) => belgiOl(i.matn));
const soni = izohlar.reduce((s, i) => {
const b = belgiOl(i.matn);
s[b] = (s[b] ?? 0) + 1;
return s;
}, {});
let qaror = "Approve";
if (ochiq.some((b) => b === "muammo")) qaror = "Request changes";
else if (ochiq.some((b) => b === "savol")) qaror = "Comment";
return { qaror, soni };
}
const pr9 = [
{ matn: "**savol:** Map chegarasiz o'sadimi?", yopilgan: false },
{ matn: "**taklif:** BELGI_TOKEN = 4", yopilgan: false },
{ matn: "**savol:** qulf qancha vaqt?", yopilgan: false },
{ matn: "**maqtov:** sukut asoslangan", yopilgan: false },
];
console.log(reviewXulosasi(pr9));
pr9[0].yopilgan = true;
pr9[2].yopilgan = true;
console.log(reviewXulosasi(pr9).qaror);
console.log(reviewXulosasi([{ matn: "muammo: LICENSE yo'q" }]).qaror);Konsolda:
{ qaror: 'Comment', soni: { savol: 2, taklif: 1, maqtov: 1 } }
Approve
Request changesBirinchi qator — PR #9 ning javoblardan oldingi holati: ikki savol ochiq, qaror "Comment" — kanonda ham aynan shunday umumiy review yuborilgan. Savollar yopilgach — "Approve" (sinov reposida GitHub buni rad etardi, chunki muallif o'zi; jamoada — reviewer bosadi). Uchinchisi — PR #15 dagi muammo:: yopilgan yo'q, ya'ni undefined — ochiq hisoblanadi.
3-mashq (qiyin): ikkinchi review'ni qisqartiring
kurs/mashqlar/32/11-review/pr-yarat.sh «Ikkinchi review» bo'limidagi repo'larni yaratadi. Endi Aziz boshqa izoh yozdi: "taklif: muddati yo'q vazifa ham kechikkan emas — buni aniq yozsak". Bu tuzatish birinchi commitga tegishli.
bash pr-yarat.sh pr, keyincd pr/nodira.muddat.jsdagi shartnivazifa.bajarildi || !vazifa.muddatga o'zgartiring.- Tuzatishni birinchi commitga
--fixupqiling va autosquash bilan birlashtiring. --force-with-leasebilan yuboring.cd ../aziz, yangilang varange-diffbilan nima o'zgarganini ko'ring. Qaysi commit=, qaysi biri!?
Ishora: Interaktiv rebase darsi — git commit --fixup HEAD~1 va GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash main (muharrirsiz). SHA'lar darsdagidek chiqishi uchun Nodiraning muallif va committer ma'lumotlarini va sanasini qotiring (yechimda).
Yechim
bash pr-yarat.sh pr && cd pr/nodira
export GIT_AUTHOR_NAME="Nodira Rahimova"
export GIT_AUTHOR_EMAIL="nodira@example.com"
export GIT_COMMITTER_NAME="Nodira Rahimova"
export GIT_COMMITTER_EMAIL="nodira@example.com"
export GIT_AUTHOR_DATE="2026-11-02T15:00:00+05:00"
export GIT_COMMITTER_DATE="2026-11-02T15:00:00+05:00"
Y='if (vazifa.bajarildi || !vazifa.muddat)'
sed -i "s/if (vazifa.bajarildi)/$Y/" muddat.js
git commit -q -a --fixup HEAD~1
GIT_SEQUENCE_EDITOR=: git rebase -q -i --autosquash main
git push -q --force-with-lease
cd ../aziz
git fetch -q origin
git range-diff --creation-factor=100 \
main origin/fix/muddat@{1} origin/fix/muddatBiz ishga tushirdik (pr-yarat.sh chiqishi yozilmagan):
1: 7c3e768 ! 1: 43d999a fix: bajarilgan vazifa kechikkan hisoblanmaydi
@@ Commit message
## muddat.js ##
@@
export function kechikkanmi(vazifa, bugun) {
-+ if (vazifa.bajarildi) return false;
++ if (vazifa.bajarildi || !vazifa.muddat) return false;
return vazifa.muddat < bugun;
}
2: 6a63fef = 2: c55743f test: bajarilgan vazifaBirinchi commit ! — ichida bitta qator almashgan: -+ eski versiyadagi qo'shilgan qator, ++ yangi versiyadagisi. Ikkinchi commit =, garchi SHA'si o'zgargan bo'lsa ham (6a63fef → c55743f): ota-commit yangilandi, lekin testning o'zi bir xil. Aziz uni qayta o'qimaydi.
--creation-factor=100 siz biz boshqa chiqish oldik: birinchi commit < (o'chdi) va > (yangi) deb ikki qatorda ko'rindi — commit kichik, o'zgarish esa uning katta qismi edi. Bayroq Git'ga "ularni baribir juftla" deydi.
12. Real ishda
- Qayerda uchraydi: deyarli har jamoada PR'siz
mainga kod tushmaydi. Ko'p kompaniyada kamida bitta tasdiq va CODEOWNERS majburiy; sezgir joylarga (to'lov, auth) — ikki tasdiq. - Bilim tarqatish: review — yangi xodimning loyihani o'rganish yo'li ham. Junior'larga katta dasturchilarning PR'larini review qilishni berishadi — ular savol beradi va o'rganadi.
- Avtomatlashtirish: linter, testlar va xavfsizlik skanerlari CI'da review'dan oldin yuradi. AI review yordamchilari ham bor — ular birinchi qarashni tezlashtiradi, lekin tasdiq baribir odamniki.
- Intervyu savollari: "Code review'da nimaga qaraysiz?", "Rozi bo'lmagan izohga qanday javob berasiz?", "Katta PR kelsa nima qilasiz?", "Review'ni qanday tezlashtirish mumkin?"
Xulosa
- Review tartibi: to'g'rilik → xavfsizlik va ma'lumot → testlar → dizayn → o'qilishi; uslub — linterniki.
- Har izohga belgi:
muammo:,taklif:,savol:,nit:,maqtov:— muallif nima majburiy ekanini darhol biladi. - Savol shaklida va sababi bilan yozing; maqtovni ham unutmang.
- Muallif har izohga javob beradi; katta taklif — alohida issue; muhokamani izoh egasi yopadi.
- Ikkinchi review —
git range-diff:=o'qilmaydi,!o'qiladi. - Tasdiq mezoni: to'g'ri, testli, xavfsiz, tushunarli — mukammal emas, yaxshiroq.
Keyingi dars: Texnik yozish: README va loyiha hujjatlari — README'ni yangi odam 5 daqiqada loyihani ishga tushiradigan qilib qayta tuzamiz, SECURITY.md qo'shamiz va ikki PR bilan yuboramiz.
Manbalar
- Conventional Comments: https://conventionalcomments.org/ (2026-11-04 da ochib o'qildi)
- Google Engineering Practices — The Standard of Code Review: https://google.github.io/eng-practices/review/reviewer/standard.html (2026-11-04 da ochib o'qildi)
- Google Engineering Practices — What to look for in a code review: https://google.github.io/eng-practices/review/reviewer/looking-for.html (2026-11-04 da ochib o'qildi)
- Git hujjati — git-range-diff: https://git-scm.com/docs/git-range-diff (
--creation-factorsukuti — Git 2.54.0 bilan kelgan hujjatdan, 2026-11-04) - GitHub Docs — About pull request reviews: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews (2026-11-04 da ochib o'qildi)
- GitHub Docs — Commenting on a pull request ("Resolve conversation"): https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/commenting-on-a-pull-request (2026-11-04 da ochib o'qildi)
- GitHub Changelog — Force push timeline event: https://github.blog/changelog/2018-11-15-force-push-timeline-event/ (2018-11-15)
- GitHub Changelog — Warning about bidirectional Unicode text: https://github.blog/changelog/2021-10-31-warning-about-bidirectional-unicode-text/ (2021-10-31)
- Trojan Source (CVE-2021-42574, CVE-2021-42694): https://trojansource.codes/ (2026-11-04 da ochib o'qildi)
- Kanon tajribasi (IlmHamroh, 2026-11-04): gh 2.92.0, sinov reposidagi PR #9 va #15 izohlari, rad etish chiqishlari.
range-diffchiqishlari va mashq yechimlari — biz ishga tushirdik (Git 2.54.0, Node 24.21.0, 2026-11-04).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!