git bisect — xatoni qaysi commitda paydo bo'lganini topish

~15 daq · Git · Git Tarixini Boshqarish

Muammodan boshlaylik

Bir oy oldin chiqarilgan v1.4.0 da savat to'g'ri ishlardi. Bugungi main da — savatga qo'shilgan mahsulot narxi noto'g'ri hisoblanadi. Shu orada — 300 ta commit, 6 ta dasturchidan.

Qaysi commit buzdi? Har birini birma-bir tekshirish — 300 marta. Kodni o'qib topish — xato aniq ko'rinmaydi.

git bisect — ikkiga bo'lib qidirish bilan buzilgan commitni topadi. 300 ta commit uchun — taxminan 9 qadam.


Ikkiga bo'lib qidirish

O'yin: "1 dan 1000 gacha son o'yladim. Katta yoki kichik deb javob beraman." Eng tez strategiya — har safar o'rtasini aytish: 500? → kichik. 250? → katta. 375? ... Ko'pi bilan 10 qadamda topiladi.

Bisect aynan shunday ishlaydi:

 v1.4.0 (yaxshi)                                         main (yomon)
  ●────●────●────●────●────●────●────●────●────●────●────●
  ✓                        ?                             ✗
                    1-qadam: o'rtasini tekshir

  ✓                        ✓────●────●────?────●────●────✗
                                    2-qadam: qolgan yarmining o'rtasi
  ...
                                         ✗ ← birinchi yomon commit topildi
Commitlar soni Kerakli qadamlar
10 ~4
100 ~7
1 000 ~10
10 000 ~14

Qo'lda bisect

git bisect start
git bisect bad                 # joriy holat (main) — yomon
git bisect good v1.4.0         # bu versiya — yaxshi
Bisecting: 149 revisions left to test after this (roughly 7 steps)
[c3d4e5f...] Mahsulot kartasi: chegirma belgisi

Git o'rtadagi commit ga o'tdi (detached HEAD, 14-dars). Endi siz tekshirasiz: ilovani ishga tushiring, savatni sinab ko'ring.

npm run dev
# ... brauzerda tekshirish ...
git bisect good                # bu commit da hammasi to'g'ri
Bisecting: 74 revisions left to test after this (roughly 6 steps)
[e5f6a7b...] Narx: yaxlitlash funksiyasi qayta yozildi
# tekshirish... xato bor
git bisect bad

... 7–8 marta takrorlang. Oxirida:

e5f6a7b8c9d0... is the first bad commit
commit e5f6a7b8c9d0...
Author: Malika Karimova <malika@example.com>
Date:   Mon Oct 20 15:42:11 2026 +0500

    Narx: yaxlitlash funksiyasi qayta yozildi

 src/narx.js | 12 ++++++------

Topildi. Endi xato aniq 12 qatorlik o'zgarishda — git show e5f6a7b.

git bisect reset               # bisect ni tugatish, asl branch ga qaytish

[!INFO] Ba'zi commit ni tekshirib bo'lmasa (masalan, u kompilyatsiya bo'lmaydi) — git bisect skip. Git qo'shni commitni tanlaydi.


Avtomatik bisect — eng kuchli shakl

Har bir qadamni qo'lda tekshirish o'rniga — test skripti. Skript chiqish kodi bilan javob beradi: 0 — yaxshi, 1 — yomon (Linux kursi, 38-dars).

git bisect start main v1.4.0
git bisect run npm test -- savat.test.js

Git o'zi barcha qadamlarni bajaradi va bir necha daqiqada natijani beradi — siz qahva ichib turasiz.

Maxsus test bo'lmasa — kichik skript:

#!/bin/bash
# xato-tekshir.sh
npm install --silent || exit 125       # 125 — "skip": bu commit ni tekshirib bo'lmaydi
node -e "
  const { narxHisobla } = require('./src/narx.js');
  process.exit(narxHisobla(19990, 3) === 59970 ? 0 : 1);
"
chmod +x xato-tekshir.sh
git bisect start main v1.4.0
git bisect run ./xato-tekshir.sh
git bisect reset

[!TIP] Skriptni repozitoriydan tashqarida saqlang (masalan, /tmp/) — aks holda bisect eski commitlarga o'tganda u yo'qolib qolishi mumkin (u commit larda hali bo'lmagan).

Chiqish kodi Bisect uchun ma'nosi
0 good
1–124, 126, 127 bad
125 skip

Bisect jurnali

git bisect log                 # qilingan qadamlar
git bisect visualize           # qolgan nomzodlar (gitk yoki log)

Xato qadam bosdingizmi (good o'rniga bad)?

git bisect log > bisect.log
# bisect.log da xato qatorni o'chirish
git bisect reset
git bisect replay bisect.log

Bisect qachon yaxshi ishlaydi

Bisect samarali bo'lishi uchun — yaxshi tarix kerak:

  • Har bir commit ishlaydi (kompilyatsiya bo'ladi, ishga tushadi) — 8-darsdagi qoida. Ko'p buzilgan oraliq commitlar — ko'p skip va noaniq natija
  • Kichik commitlar — topilgan commit 12 qatorli bo'lsa, xato bir qarashda ko'rinadi; 2000 qatorli "turli o'zgarishlar" commit i bo'lsa — bisect deyarli yordam bermaydi
  • Testlar — avtomatik bisect run uchun

Bu — "nima uchun kichik, ishlaydigan commitlar" savoliga yana bir amaliy javob.


Nima uchun shunday?

Nima uchun bisect kod tahlili emas, "qora quti" sinov orqali ishlaydi?

Chunki "qachon buzildi" savoli ko'pincha "nima uchun buzildi" dan ancha oson. Xato sababi murakkab bo'lishi mumkin: ikki mustaqil o'zgarishning kutilmagan o'zaro ta'siri, bog'liqlik versiyasi, chekka holat. Kodni o'qib uni topish — soatlar yoki kunlar. Bisect esa kodni tushunishni talab qilmaydi: u faqat "ishlaydimi — yo'qmi?" savoliga javob kutadi va logarifmik tezlikda qidiruv maydonini toraytiradi. Natijada siz butun tarix o'rniga bitta kichik diff bilan qolasiz — va sabab odatda darhol ko'rinadi.


Xulosa

Eslab qoling:

  • Bisect — ikkiga bo'lib qidirish: 1000 commit → ~10 qadam
  • git bisect start → bad (hozirgi) → good <eski-yaxshi>
  • Har qadamda tekshirish → git bisect good yoki bad; tekshirib bo'lmasa — skip
  • Topilgach — git show; tugatish — git bisect reset
  • Avtomatik: git bisect run <skript> — 0 good, 1 bad, 125 skip
  • Skript — repozitoriydan tashqarida
  • Samaradorlik — kichik, ishlaydigan commitlarga bog'liq

Keyingi dars

31-dars: git reflog — yo'qolgan commitlarni tiklash