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~10A 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 badHa nincs meg:
git bisect goodA 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-banMegvan! 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.