Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. Git hook'lar: Husky'siz
- 2.1 .git/hooks
- 2.2 Birinchi hook qo'lda
- 2.3 Muammo: .git repoga kirmaydi
- 3. Husky
- 3.1 O'rnatish
- 3.2 prepare — jamoa uchun kalit
- 3.3 .husky/_ ichida nima
- 3.4 Bizning ikki hook
- 4. lint-staged
- 4.1 Nega butun loyiha emas
- 4.2 lint-staged qanday ishlaydi
- 4.3 Birinchi commit
- 5. Hook'lar ishda: to'rt holat
- 5.1 Xabar standartga mos emas
- 5.2 Kodda lint xatosi
- 5.3 Faqat format buzilgan
- 5.4 To'g'ri commit — formatlangan holda
- 5.5 Faqat staged fayllar
- 6. Chetlab o'tish: --no-verify va HUSKY=0
- 6.1 --no-verify
- 6.2 HUSKY=0
- 7. pre-push: testlar push'dan oldin
- 8. Muqobillar: lefthook va simple-git-hooks
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): qo'lda hook
- 2-mashq (o'rta): lefthook
- 3-mashq (o'rta): pre-push
- 4-mashq (qiyin): Vazifalar qadami
- 11. Real ishda
- Xulosa
- Manbalar
Git hooklar: Husky va lint-staged bilan commitdan oldin tekshirish
Qisqacha: Git hook — Git ma'lum paytda (commitdan oldin, push'dan oldin) o'zi ishga tushiradigan skript. Husky bu skriptlarni repoga qo'yib, jamoadagi hammaga ulaydi. lint-staged esa commitga tushayotgan fayllarnigina ESLint va Prettier'dan o'tkazadi — butun loyihani emas. Natija: xatoli yoki formatlanmagan kod va noto'g'ri commit xabari tarixga tushmaydi.
Bu darsda
- Git hook nima ekanini va
.git/hookspapkasida qanday ishlashini ko'rasiz. - Husky 9 ni o'rnatasiz:
husky init,pre-commit,commit-msg,pre-push. - lint-staged bilan faqat staged fayllarni tekshirasiz va avtomatik tuzatasiz.
--no-verifyvaHUSKY=0nima qilishini va nega CI baribir kerakligini tushuntirasiz.- lefthook muqobilini taniysiz.
Oldin bilishingiz kerak: Conventional Commits va commitlint, Birinchi repo: init, status, add, commit, scripts chuqur.
1. Nega bu kerak?
O'tgan darsda commitlint'ni o'rnatdik. Lekin u faqat siz echo "…" | npx commitlint deb so'raganingizda ishlaydi. Sardor esa shoshilib commit qiladi va tekshirishni unutadi. ESLint va Prettier bilan ham shunday: npm run check bor, lekin uni ishga tushirish odamga bog'liq.
Unutishdan himoya — avtomatika. Git har commitdan oldin o'zi skript ishga tushira oladi. Bu imkoniyatni Birinchi repo darsida .git/hooks papkasida ko'rgansiz — "keyin kerak bo'ladi" degan edik. Bugun o'sha "keyin".
O'xshatish: «Bahor» oshxonasida taom zaldan chiqishdan oldin oshpaz uni tatib ko'radi. Har taom, har safar — eslatmasiz. Mijozga sovuq osh bormaydi. Hook — kod uchun shunday "tatib ko'rish".
2. Git hook'lar: Husky'siz
2.1 .git/hooks
Git hook — .git/hooks papkasidagi ma'lum nomli skript. Git uni o'z vaqtida ishga tushiradi. Skript 0 dan boshqa kod bilan tugasa, Git amalni to'xtatadi.
| Hook | Qachon | Odatiy ishi |
|---|---|---|
pre-commit |
commit yaratilishidan oldin | lint, format |
commit-msg |
xabar yozilgach | commitlint |
pre-push |
push'dan oldin | testlar |
post-merge |
merge (pull) dan keyin |
npm ci eslatmasi |
Har yangi repoda Git namunalar qo'yadi: pre-commit.sample, pre-push.sample va boshqalar. .sample kengaytmasi bor fayl ishlamaydi — u faqat namuna.
2.2 Birinchi hook qo'lda
Mashq repoda .git/hooks/pre-commit faylini yaratdik:
#!/bin/sh
# Staged fayllarda "console.log" qolmasin
if git diff --cached | grep -q "^+.*console\.log"; then
echo "pre-commit: console.log qolib ketgan — olib tashlang"
exit 1
figit diff --cached — staged o'zgarishlar (git diff darsidan), grep -q — "qatorni topdingmi?" deb jim so'raydi. Topsa — xabar va exit 1. Endi console.log li faylni commit qilamiz:
git commit -m "feat: menyu"pre-commit: console.log qolib ketgan — olib tashlangCommit yaratilmadi, chiqish kodi 1. console.log ni olib tashlagach — [main (root-commit) 5e82a81] feat: menyu. Hook ishlaydi!
Linux va macOS'da hook faylini bajariladigan qilish kerak: chmod +x .git/hooks/pre-commit. Windows'dagi Git buni talab qilmadi.
2.3 Muammo: .git repoga kirmaydi
Bu hook faqat sizning kompyuteringizda. .git papkasining ichi git push bilan ketmaydi. Malika reponi klon qilsa, uning .git/hooks ida faqat .sample lar bo'ladi. Har dasturchi hook'ni qo'lda nusxalashi kerak — va kimdir albatta unutadi.
Yechim: hook skriptlarini oddiy papkada (repoda) saqlash va Git'ga "hook'larni shu yerdan ol" deyish. Buning uchun Git'da sozlama bor — core.hooksPath. Husky aynan shuni qiladi.
Tekshirib ko'ring: Sardor
.git/hooks/pre-commityozdi va push qildi. Malikagit pullqildi. Malikada hook ishlaydimi?
Javob
Yo'q. .git papkasining ichki fayllari (hook'lar, sozlamalar) push va pull bilan uzatilmaydi — faqat commitlar. Hook jamoaga yetib borishi uchun u repodagi oddiy faylda bo'lishi va har kompyuterda ulanishi kerak.
3. Husky
3.1 O'rnatish
Husky — Git hook'larini repodagi .husky/ papkasida saqlaydigan va ularni npm install paytida avtomatik ulaydigan kichik paket. Branch: chore/husky.
npm i -D husky@9.1.7 lint-staged@17.6.0
added 4 packages, and audited 204 packages in 4s
72 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesIkkalasi ham yengil: 4 ta paket. Versiyalar — 2026-10 holatiga eng yangisi (.npmrc dagi save-exact tufayli ^ siz yoziladi). lint-staged'ni keyingi bo'limda ishlatamiz.
npx husky initBuyruq jim tugaydi (chiqish yo'q) — bu muvaffaqiyat belgisi. Lekin u uch ish qildi:
package.jsonga skript qo'shdi:"prepare": "husky"..husky/pre-commitfaylini yaratdi, ichida bitta qator:npm test.- Git'ni sozladi:
git config core.hooksPathendi.husky/_ni ko'rsatadi.
3.2 prepare — jamoa uchun kalit
prepare — npm'ning maxsus skripti: npm install va npm ci oxirida o'zi ishga tushadi (scripts chuqur darsidagi hayot sikli skriptlari). Malika reponi klon qilib npm ci qilsa, husky buyrug'i uning kompyuterida ham core.hooksPath ni sozlaydi. Hech kim hech narsani unutmaydi.
flowchart LR
A["git clone"] --> B["npm ci"]
B --> C["prepare: husky"]
C --> D["core.hooksPath<br/>= .husky/_"]
D --> E["git commit"]
E --> F[".husky/pre-commit"]
E --> G[".husky/commit-msg"]3.3 .husky/_ ichida nima
.husky/_/ papkasida Husky har hook nomi uchun kichik fayl yaratadi (pre-commit, pre-push, commit-msg…). Ularning hammasi bitta umumiy skriptni chaqiradi — .husky/_/h. Undagi muhim qatorlar:
[ "${HUSKY-}" = "0" ] && exit 0
export PATH="node_modules/.bin:$PATH"
sh -e "$s" "$@"
c=$?
[ $c != 0 ] && echo "husky - $n script failed (code $c)"HUSKY=0bo'lsa — hook'lar o'chiq, darhol chiqadi.PATHganode_modules/.binqo'shiladi — hook ichidaeslint,lint-stagedkabi buyruqlar topiladi.- Sizning
.husky/pre-commitfaylingizsh -ebilan bajariladi: birinchi xatoda to'xtaydi. - Xato bo'lsa —
husky - pre-commit script failed (code 1). Bu qatorni tez-tez ko'rasiz.
.husky/_/ ning o'zi .gitignore bilan repodan chiqarilgan: uni har kompyuterda husky buyrug'i qayta yaratadi. Repoga faqat siz yozgan .husky/pre-commit, .husky/commit-msg kiradi.
3.4 Bizning ikki hook
husky init yozgan npm test ni almashtiramiz. .husky/pre-commit:
npx lint-staged.husky/commit-msg:
npx --no -- commitlint --edit "$1"$1— Git bergan vaqtinchalik fayl yo'li (.git/COMMIT_EDITMSG), ichida siz yozgan xabar.--edit— commitlint'ga "xabarni shu fayldan o'qi".npx --no— "paket o'rnatilmagan bo'lsa, internetdan yuklama, xato ber". Hook har commitda ishlaydi — u jimgina biror narsa yuklab o'tirmasin.--— npx bayroqlari tugadi, keyingisi buyruq.
Tekshirib ko'ring: Nega
vazifalardagi pre-commit'danpm testvanpm run tipyo'q?
Javob
Ular sekin va butun loyihani tekshiradi: 146 ta test va tsc -b har commitda — bir necha soniya qo'shimcha kutish. Commit tez bo'lishi kerak, aks holda dasturchilar hook'ni chetlab o'ta boshlaydi. Shuning uchun: commitda — faqat o'zgargan fayllar (lint-staged), to'liq tekshiruv — npm run check va CI'da. Xohlasangiz, testlarni pre-push ga qo'yish mumkin (mashqda).
4. lint-staged
4.1 Nega butun loyiha emas
pre-commit ga npm run lint qo'ysak bo'lardi. Lekin u 50 ta faylni tekshiradi, siz esa bitta faylni o'zgartirdingiz. Bundan yomoni: boshqa (hali commit qilinmagan) faylingizdagi xato ham commitni to'xtatadi.
lint-staged — faqat staged fayllar (git add qilinganlar) ustida buyruq bajaradigan vosita. Sozlamasi — .lintstagedrc.json:
{
"*.{js,ts}": ["eslint --fix", "prettier --write"],
"*.{json,yml}": "prettier --write"
}| Kalit | Qiymat | Ma'nosi |
|---|---|---|
"*.{js,ts}" |
glob naqsh | staged .js va .ts fayllar |
["eslint --fix", "prettier --write"] |
buyruqlar ro'yxati | ketma-ket, har biriga fayl nomlari qo'shiladi |
"*.{json,yml}" |
— | JSON va YAML — faqat format |
eslint --fix — tuzatsa bo'ladiganini tuzatadi, qolganini xato deydi. prettier --write — formatlaydi. Tuzatilgan fayllarni lint-staged o'zi yana git add qiladi — commitga tuzatilgan variant tushadi.
4.2 lint-staged qanday ishlaydi
flowchart TB
A["git commit"] --> B["zaxira<br/>(git stash)"]
B --> C["staged fayllar<br/>ro'yxati"]
C --> D["eslint --fix,<br/>prettier --write"]
D -->|"xato"| E["asl holatga<br/>qaytarish"]
D -->|"toza"| F["o'zgarishlarni<br/>qayta stage"]
E --> G["commit yo'q"]
F --> H["commit"]Zaxira muhim: commit qilinmagan, stage qilinmagan o'zgarishlaringiz lint-staged ishlayotganda yo'qolmaydi. Xato bo'lsa, hammasi avvalgi holatiga qaytadi.
4.3 Birinchi commit
Hamma fayllar tayyor — commit qilamiz (hook'lar endi ishlaydi):
git add -A
git commit -m "chore: husky va lint-staged — pre-commit va commit-msg hook'lari"lint-staged har bosqichni alohida qatorda yozadi. Belgilarga qarang: ⋯ — boshlandi, ✔ — muvaffaqiyatli, ✖ — yiqildi, ↓ — o'tkazib yuborildi.
⋯ Backing up original state…
✔ Done backing up original state (efcfedf)!
⋯ Running tasks for staged files…
*.{json,yml} — 4 files
⋯ prettier --write
✔ prettier --write
✔ Done running tasks for staged files!
⋯ Staging changes from tasks…
✔ Done staging changes from tasks!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!
[chore/husky cc520f5] chore: husky va lint-staged — pre-commit va commit-msg hook'lari
6 files changed, 84 insertions(+), 1 deletion(-)
create mode 100644 .husky/commit-msg
create mode 100644 .husky/pre-commit
create mode 100644 .lintstagedrc.jsonBosqichlar ro'yxatini o'qing: zaxira, vazifalar (*.{json,yml} — 4 files: package.json, lock, .lintstagedrc.json, pages.yml), qayta stage, tozalash. .husky/* fayllari hech bir naqshga mos emas — ular tekshirilmadi. Keyin commit-msg hook'i xabarni tekshirdi — u jim o'tdi. Terminalda chiqish rangli bo'ladi. pages.yml ga qo'shilgan HUSKY: 0 haqida — «Chetlab o'tish» bo'limida.
Maslahat: Hash'lar (
efcfedf,cc520f5) va vaqtlar sizda boshqacha. Bizning kompyuterda bu commit 26 s davom etdi: birinchi ishga tushishdanpxva ESLint sekin yuklanadi, kompyuterda boshqa ishlar ham bor edi. Keyingi commitlar 5–9 s.
5. Hook'lar ishda: to'rt holat
5.1 Xabar standartga mos emas
git commit -m "Taymer izohi"…
✔ Done running tasks for staged files!
…
⧗ --- input ---
Taymer izohi
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky - commit-msg script failed (code 1)Avval pre-commit o'tdi (fayl toza), keyin commit-msg yiqildi. Xabar — o'tgan darsdagi commitlint xatosi. Oxirgi qator — Husky'niki: qaysi hook va qanday kod bilan. Commit yaratilmadi, fayllaringiz esa staged holida qoldi — xabarni tuzatib, qayta urinasiz.
5.2 Kodda lint xatosi
fayl.ts oxiriga atayin xavfli funksiya qo'shib, stage qildik:
export function bosh(x: any) {
eval(x);
}⋯ Backing up original state…
✔ Done backing up original state (707c241)!
⋯ Running tasks for staged files…
*.{js,ts} — 1 file
⋯ eslint --fix
⋯ prettier --write
✖ eslint --fix
↓ prettier --write
✖ Failed to run tasks for staged files!
↓ Skipped staging changes from tasks…
⋯ Reverting to original state because of errors…
✔ Done reverting to original state!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!
✖ eslint --fix:
D:\kurs\vazifalar\src\fayl.ts
50:25 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
51:3 error `eval` can be harmful no-eval
51:8 error Unsafe argument of type `any` assigned to a parameter of type `string` @typescript-eslint/no-unsafe-argument
✖ 3 problems (3 errors, 0 warnings)
husky - pre-commit script failed (code 1)✖ eslint --fix — ESLint yiqildi, ↓ prettier --write — keyingi buyruq o'tkazib yuborildi (↓ — "o'tkazildi"). Reverting to original state — fayl asl holiga qaytdi. Pastda — ESLint'ning to'liq hisoboti: uchta xato, ulardan biri — 13-qismdagi eval taqiqi. Bu holat 6.5 s davom etdi.
5.3 Faqat format buzilgan
Endi kod to'g'ri, faqat bo'sh joylar ortiqcha:
export const MAKS_FAYL_HAJMI = 1_000_000 ;…
✔ eslint --fix
✔ prettier --write
✔ Done running tasks for staged files!
⋯ Staging changes from tasks…
✖ Prevented an empty git commit!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!
⚠ lint-staged prevented an empty git commit.
Use the --allow-empty option to continue, or check your task configuration
husky - pre-commit script failed (code 1)Kutilmagan natija! Prettier qatorni formatladi va u asl holatga — main dagidek — qaytdi. Farq qolmadi, demak, commit bo'sh bo'lardi. lint-staged bo'sh commitni to'xtatdi: "bo'sh commit oldi olindi". Bu yaxshi: tarixda "hech narsa o'zgarmagan" commit bo'lmaydi.
5.4 To'g'ri commit — formatlangan holda
Qatorga izoh qo'shib, yana noto'g'ri formatda stage qildik:
export const MAKS_FAYL_HAJMI = 1_000_000; // 1 MBgit commit -m "docs: fayl.ts — 1 MB izohi"…
✔ eslint --fix
✔ prettier --write
✔ Done running tasks for staged files!
⋯ Staging changes from tasks…
✔ Done staging changes from tasks!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!
[chore/husky 193d136] docs: fayl.ts — 1 MB izohi
1 file changed, 1 insertion(+), 1 deletion(-)Commitning o'zida (git show HEAD) nima bor:
-export const MAKS_FAYL_HAJMI = 1_000_000;
+export const MAKS_FAYL_HAJMI = 1_000_000; // 1 MBOrtiqcha bo'sh joylar yo'q — commitga Prettier formatlagan variant tushdi. Biz formatlashni o'ylamadik ham. 8.9 s.
5.5 Faqat staged fayllar
Yana bir tajriba: taymer.ts ga any li qator yozdik, lekin stage qilmadik. Boshqa faylni (fayl.ts, toza o'zgarish) commit qildik — commit o'tdi. taymer.ts esa M (o'zgargan) holida qoldi: lint-staged unga qaramadi. Bu lint-staged'ning maqsadi: sizning hali tugallanmagan ishingiz commitga xalaqit bermaydi.
Tekshirib ko'ring: «Faqat format buzilgan» holatida Sardor baribir commit qilmoqchi. Nima qiladi?
Javob
Hech narsa — commit kerak emas. Uning o'zgarishi faqat formatda edi, Prettier uni qaytardi va fayl main dagi bilan bir xil bo'ldi. Bo'sh commit ma'nosiz. Agar haqiqatan bo'sh commit kerak bo'lsa (masalan, CI'ni qayta ishga tushirish), git commit --allow-empty bor — lint-staged xabarining o'zi ham shuni aytadi.
6. Chetlab o'tish: --no-verify va HUSKY=0
6.1 --no-verify
git commit --no-verify -m "Tez commit"[chore/husky f9b9f21] Tez commit
1 file changed, 1 insertion(+)0.9 soniyada o'tdi — pre-commit ham, commit-msg ham ishlamadi. Faylda any (lint xatosi) va xabar standartga zid. --no-verify (qisqasi -n) — Git'ning o'z bayrog'i: "hook'larni ishga tushirma".
Bu tuzoq emas, imkoniyat: favqulodda holatda (sayt yiqildi, tuzatish 1 daqiqada kerak) foydali. Lekin u hook'lar himoya emas, qulaylik ekanini ko'rsatadi. Har kim o'chira oladi. Shuning uchun vazifalar da asosiy himoya — CI: pages.yml dagi npm run check ni chetlab o'tib bo'lmaydi.
6.2 HUSKY=0
.husky/_/h dagi birinchi tekshiruvni eslang: HUSKY=0 bo'lsa — darhol chiqish. Bu CI uchun: GitHub Actions'da npm ci → prepare → husky ishga tushadi, lekin u yerda commit qilinmaydi. pages.yml:
# CI'da git hook'lar kerak emas: npm ci dagi "prepare": "husky" jim
# o'tadi (16/#41)
env:
HUSKY: 0Lokalda ham ishlaydi: HUSKY=0 git commit -m "…" — hook'larsiz commit (bash'da O'ZGARUVCHI=qiymat buyruq — faqat shu buyruq uchun).
7. pre-push: testlar push'dan oldin
Testlar commitga og'ir, lekin push'dan oldin — o'rinli. Sinov repoda .husky/pre-push faylini yaratdik (ichida npm test) va lokal "masofaviy" repoga push qildik. Atayin xato testni qo'shib:
ℹ tests 147
ℹ pass 146
ℹ fail 1
husky - pre-push script failed (code 1)
error: failed to push some refs to 'D:/kurs/masofa.git'Push to'xtadi — xato test serverga bormadi. Testlar o'tganda push 4.5 s davom etdi. vazifalar kanonida pre-push yo'q: testlar npm run check da va CI'da. Jamoa qaroriga ko'ra qo'shish mumkin.
8. Muqobillar: lefthook va simple-git-hooks
lefthook (2.2.1) — Go'da yozilgan hook menejeri. Husky + lint-staged ishini bitta YAML faylda qiladi:
# lefthook.yml — Husky + lint-staged o'rniga bitta fayl
pre-commit:
commands:
prettier:
glob: "*.{js,json}"
run: npx prettier --check {staged_files}{staged_files} — lint-staged'dagidek staged fayllar ro'yxati. npx lefthook install → sync hooks: ✔️(pre-commit). Formatlanmagan fayl bilan commit:
[warn] menyu.js
[warn] Code style issues found in the above file. Run Prettier with --write to fix.
…
summary: (done in 2.16 seconds)
✗ prettier (2.16 seconds)Bir qiziq detal: lefthook o'rnatilganda postinstall skriptini ishga tushiradi va npm 11.19.0 shunday ogohlantiradi:
npm warn install-scripts 1 package has install scripts not yet covered by allowScripts:
npm warn install-scripts lefthook@2.2.1 (postinstall: node postinstall.js)O'rnatishda kod bajaradigan paketlar — Ta'minot zanjiri darsining mavzusi. Husky va lint-staged'da bunday skript yo'q.
| Vosita | Sozlama | Qachon tanlanadi |
|---|---|---|
| Husky + lint-staged | .husky/* + .lintstagedrc.json |
npm loyihalarida eng keng tarqalgan |
| lefthook | lefthook.yml |
ko'p tilli repolar, parallel buyruqlar |
| simple-git-hooks | package.json dagi kalit |
minimal, bitta-ikkita hook |
9. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| hook umuman ishlamaydi | npm ci qilinmagan → prepare ishlamagan |
npm ci yoki npx husky |
husky - command not found in PATH |
paket o'rnatilmagan | npm ci |
husky - pre-commit script failed (code 1) |
ichidagi buyruq xato berdi | yuqoridagi chiqishni o'qing |
Prevented an empty git commit! |
format o'zgarish qaytdi, farq yo'q | hech narsa yoki --allow-empty |
Yana ikki holat. .git siz papkada npx husky .git can't be found deydi va jim tugaydi — npm ci ni repo ildizida qiling. VS Code'ning Source Control paneli orqali commit qilganda ham hook'lar ishlaydi — ular Git'ning o'ziga ulangan, terminalga emas.
10. Mashqlar
Hook'larni o'rganish uchun alohida repo kerak: kurs/mashqlar/16/41-git-hook/ da git init. vazifalar da emas — u yerda tajriba tarixni buzishi mumkin.
1-mashq (oson): qo'lda hook
«Birinchi hook qo'lda» bo'limidagi pre-commit ni yarating. console.log("sinov"); li menyu.js ni commit qilib ko'ring, keyin export const osh = 35000; bilan.
- Birinchi commit chiqish kodi:
- Ikkinchi commit chiqish kodi:
Yechim
Hook fayli — darsdagidek. Birinchi urinishda: pre-commit: console.log qolib ketgan — olib tashlang, commit yo'q. Ikkinchisida: [main (root-commit) …] feat: menyu. Mashqdan keyin .git/hooks/pre-commit ni o'chiring — keyingi mashqqa xalaqit bermasin.
2-mashq (o'rta): lefthook
npm init -y, npm pkg set type=module, .gitignore (node_modules/), npm i -D -E lefthook@2.2.1 prettier@3.9.9. «Muqobillar» bo'limidagi lefthook.yml ni yozing, npx lefthook install. export const osh=35000 ni commit qiling. Natija? Faylni npx prettier --write menyu.js bilan tuzatib, qayta urining.
Yechim
Birinchi urinish: [warn] menyu.js va ✗ prettier — commit yo'q, chiqish kodi 1. --check faqat tekshiradi, tuzatmaydi. Formatlangandan keyin commit o'tadi (chiqish kodi 0). Avtomatik tuzatish kerak bo'lsa: run: npx prettier --write {staged_files} va stage_fixed: true — lefthook tuzatilgan faylni o'zi stage qiladi. Oxirida npx lefthook uninstall.
3-mashq (o'rta): pre-push
Shu repoda: npm i -D -E husky@9.1.7, npx husky init. .husky/pre-commit ni bo'shating, .husky/pre-push ga node --test yozing. narx.test.js:
import { test } from "node:test";
import assert from "node:assert/strict";
import { osh } from "./menyu.js";
test("osh narxi", () => {
assert.equal(osh + 5000, 45000);
});Lokal masofaviy repo: git init --bare ../masofa.git, git remote add origin ../masofa.git. Commit qilib, git push -u origin main. Nima bo'ldi? Testni tuzatib (osh 35 000 + ko'k choy 5 000 = ?), qayta push qiling.
Yechim
ℹ tests 1
ℹ pass 0
ℹ fail 1
husky - pre-push script failed (code 1)
error: failed to push some refs to '../masofa.git'35 000 + 5 000 = 40 000, test esa 45 000 kutyapti. 45000 → 40000 qilib commit qilgach: ℹ pass 1, push o'tdi. --bare — ishchi papkasiz repo, server'dagi repo aynan shunday (Remote darsi). E'tibor bering: husky init lefthook'ning .git/hooks dagi hook'larini emas, core.hooksPath ni ishlatadi — ikki menejer bir repoda bir-biriga xalaqit beradi, bittasini tanlang.
4-mashq (qiyin): Vazifalar qadami
kurs/vazifalar da, branch chore/husky:
npm i -D husky@9.1.7 lint-staged@17.6.0,npx husky init..husky/pre-commit→npx lint-staged;.husky/commit-msg→npx --no -- commitlint --edit "$1";.lintstagedrc.json— darsdagidek.pages.ymlgaenv: HUSKY: 0(izohi bilan).- Commit:
chore: husky va lint-staged — pre-commit va commit-msg hook'lari. Keyin «Hook'lar ishda» bo'limidagi to'rt tajribani takrorlang va har biridan keyingit statusqiling.
Yechim
Fayllar — darsdagidek. git config core.hooksPath → .husky/_. Tajribalar natijasi: noto'g'ri xabar — commit yo'q, fayl staged qoladi; lint xatosi — Reverting to original state, fayl staged va o'zgarishsiz qoladi (xatoni o'zingiz tuzatasiz); faqat format — Prevented an empty git commit!, staged hech narsa qolmaydi; to'g'ri commit — formatlangan holda. Tajribalardan keyin git reset --hard bilan branch'ni qadam commitiga qaytaring (git log --oneline da tekshiring). npm run check — toza. Diff: 6 fayl.
11. Real ishda
- Deyarli har frontend repoda
.husky/yokilefthook.ymlbor. Yangi loyihada birinchinpm cidan keyin hook'lar o'zi ulanadi — commit qilganda "nima bu?" deb hayron bo'lmang. - Hook — qulaylik, CI — qonun. Hook tez qayta aloqa beradi, CI esa chetlab o'tib bo'lmaydigan tekshiruv. Ikkalasi bir xil buyruqlarni ishlatsa yaxshi (
vazifalardanpm run check). - Sekin hook — o'lik hook. Commit 30 soniya kutsa, jamoa
--no-verifyga o'rganadi. Og'ir ishnipre-pushyoki CI'ga qo'ying. - Intervyu: "Husky qanday ishlaydi (
core.hooksPath,prepare)?", "lint-staged nima uchun kerak?", "--no-verifyga qarshi nima qilasiz?".
Xulosa
- Git hook —
.git/hooksdagi skript; nol bo'lmagan chiqish kodi amalni to'xtatadi..gitpush bilan ketmaydi. - Husky: hook'lar
.husky/da (repoda),prepare: husky→core.hooksPath = .husky/_— harnpm cida avtomatik. pre-commit→npx lint-staged(faqat staged:eslint --fix,prettier --write, tuzatilgani commitga);commit-msg→commitlint --edit "$1".- lint-staged zaxira oladi: xatoda asl holat, faqat format o'zgarsa — bo'sh commit to'xtatiladi.
--no-verifyvaHUSKY=0hook'larni o'chiradi — shuning uchun CI'danpm run check.- Muqobillar: lefthook (bitta YAML), simple-git-hooks.
Keyingi dars: tsconfig Vite + React loyihada: app/node bo'linishi va references — vazifalar da brauzer va Node kodi uchun ikki alohida tsconfig; birinchi tsc -b hech kim tekshirmagan kodda 26 ta xato topadi.
Manbalar
- Git: githooks, core.hooksPath
- Husky — Get started, How to
- lint-staged — README
- lefthook — Configuration
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!