Git bisect hibakeresés gyakorlati példával.

A git bisect: Mikor és hogyan keressük vissza azt a rossz commitot?

Előfordul mindannyiunkkal: tegnap még működött a kód, ma reggelre valami eltört. A CI piros, a tesztesetek sikertelenek, a funkció nem úgy reagál, ahogy kellene. Nézed a commit historyt – az utóbbi két hétben tucatnyi változtatás történt, több fejlesztő is beletett dolgokat. Hol kezded a hibakeresést? Egyesével visszatesztelni minden commitot órákba telhet. Itt jön a képbe a git bisect, a fejlesztői arzenál egyik legerősebb, de gyakran alulhasznált eszköze a hibás módosítás pontos forrásának felkutatására.

Mi is az a git bisect?

A git bisect lényegében egy bináris keresést hajt végre a commit historydon. A koncepció egyszerű: megmondod neki egy ismert „jó” pontot (egy commit, ahol minden még működött) és egy „rossz” pontot (ahol a hiba már megvan). Ezután a git félidőben választ egy commitot a kettő között, és oda „checkoutol”. Te elvégzed a teszteket, és megmondod neki, hogy az az állapot „jó” volt-e vagy „rossz”. A folyamat ismétlődik, amíg a git pontosan be nem tudja határolni azt az egyetlen commitot, amely bevezette a hibát.

Nem kell félni tőle – bár parancssori eszköz, nem igényel varázslatos ismereteket. Leginkább úgy képzeld el, mint egy robotizált kollégát, aki szorgalmasan lapozgat a változásnaplóban, miközben te a lényegre koncentrálhatsz: a tesztelésre.

Egy tipikus forgatókönyv: A törött formátum

Képzeld el, hogy van egy PHP backend API végpontod, ami JSON-t szolgál fel, és egy jQuery/Bootstrap alapú admin felület, ami ezt jeleníti meg. A múlt héten minden szépen működött. Ma viszont a felhasználói lista oldalon egy adott mező (lastLogin) üresen jelenik meg, holott a tesztadatbázisban van érték.

Először is, ellenőrizd, hogy a hiba valóban a kódban van-e, és nem valami lokális konfigurációban. Ha biztos vagy, kezdődhet a bisect.

# Elindítjuk a bisect sessiont
git bisect start

# Megjelöljük az aktuális (törött) állapotot ROSSZnak
git bisect bad HEAD

# Megkeressük és megjelöljük egy régebbi, biztosan jó commitot (pl. 10 committal ezelőttit)
git bisect good HEAD~10

A git most kiválaszt egy commitot a kettő közé. A munka a te részed: le kell futtatnod egy tesztet, ami kimutatja, hogy a hiba jelen van-e ebben az állapotban. Ez lehet egy egyszerű szkript, egy manuális lépés vagy egy automata teszteset. A mi példánkban egy gyors PHP szkriptet futtathatsz, ami ellenőrzi a problémás API választ.

// quick_test.php - Egy gyors ellenőrző szkript a bisect-hez
query("SELECT id, lastLogin FROM users LIMIT 1");
$user = $stmt->fetch(PDO::FETCH_ASSOC);

// A hiba: a lastLogin formázása utáni dátum üres
$formattedDate = formatLastLogin($user['lastLogin']); // Ezt a függvényt változtatták meg?

if (empty($formattedDate) && !empty($user['lastLogin'])) {
    echo "BAD: A formázás eltört.\n";
    exit(1); // Nem nulla kilépési kód -> ROSSZ
} else {
    echo "GOOD: Minden rendben.\n";
    exit(0); // 0 kilépési kód -> JO
}

function formatLastLogin($datetime) {
    // Tegyük fel, hogy itt történt a kritikus változás
    return date('Y-m-d H:i', strtotime($datetime));
}

Futtasd le a szkriptet. Ha a hiba már megvan ebben a commit-ban, akkor:

git bisect bad

Ha nincs meg:

git bisect good

A git új commitra ugrik, és ismételheted a folyamatot. Általában néhány lépés alatt (log2(N)) meg is találja a bűnöst.

git bisect start
git bisect bad HEAD
git bisect good HEAD~10
# ... néhány good/bad jelölés után ...
abcdef123456 is the first bad commit
commit abcdef123456
Author: Kolléga János 
Date:   Wed May 15 11:23:45 2024 +0200

    refactor: Átírtam a dátumformázó függvényt az API-ban

Megvan! A formatLastLogin függvény átírása okozta a problémát. Most már tudod, hogy pontosan melyik változtatást kell megvizsgálni és javítani.

Gyakori buktatók és tippek

1. A „jó” pont fontossága: Ha rosszul jelölsz meg egy „jó” commitot (ami már tartalmazza a hibát), a bisect eredménye értelmetlen lesz. Amikor csak lehet, használj címkéket (v1.2) vagy tag-eket, amikről biztosan tudod, hogy jók voltak. 2. Automatizálás: Ha van megbízható teszteseted (pl. PHPUnit), a folyamat teljesen automatizálható a git bisect run paranccsal. Ez egy álom!

    git bisect run phpunit tests/ApiResponseTest.php
    

3. A frontend hibák: Ha a hiba egy jQuery eseménykezelőben vagy CSS/SCSS stílusban van, a teszted manuális is lehet. Nyisd meg a böngészőt, ellenőrizd, és add meg a választ. Lehet, hogy lassabb, de ugyanúgy működik.

    // Gyors frontend ellenőrző - futtasd a konzolban az adott commit checkout-ján
    if ($('#userTable .lastLogin-cell:first').text().trim() === '') {
        console.log("BAD - üres mező"); // És ird be: git bisect bad
    } else {
        console.log("GOOD"); // És ird be: git bisect good
    }
    

4. Megszakítás és reset: Elakadtál? Bármikor kiléphetsz a git bisect reset paranccsal, ami visszavisz a kiinduló ágra. 5. Nem-kód változások: A bisect nem csak kódhibákra jó. Ha egy build script, egy .env fájl vagy egy CSS fájl módosítása tör el valamit, az is nyomon követhető.

Összegzés

A git bisect nem egy mindennapi eszköz, de amikor szükség van rá, mentőövként szolgál. Megszünteti a találgatást és a „ki volt az?” vitákat, helyette adatokat és pontos commitokat kínál. Tárd fel a fejlesztői eszköztárad egy zugát, és legközelebb, amikor egy rejtélyes hiba bukkan fel a múlt homályából, ne kezdj el kétségbeesetten visszalapozgatni – indíts egy bisect sessiont, és hagyd, hogy a git végre a nehéz munkát.

Emlékezz: a legjobb hibák azok, amelyeket soha nem követsz le, de a második legjobbak azok, amelyeket egy git bisect segítségével gyorsan és fájdalommentesen meg tudsz javítani.

A weboldalon megjelenő szöveges és vizuális tartalmak előállításához mesterséges intelligenciát (AI) használunk.