4.6 Git history és hibakeresés

← 4. Git és verziókezelés a gyakorlatban

4.6 Git history és hibakeresés – git log, blame, bisect

Áttekintő

Gondolj a Git historyre mint egy időgépre: nemcsak azt mutatja meg, mi van a kódban most, hanem azt is, hogyan jutottunk ide – és miért. Ez a tudás az egyik legértékesebb eszközöd, amikor valami hirtelen elromlik, és fogalmad sincs, mióta és ki miatt.

Ez az alfejezet három olyan Git parancsra fókuszál, amelyeket a legtöbb junior sosem tanul meg igazán:

  • git log – a history olvasása, nem csak görgetése
  • git blame – ki, mikor és miért változtatott egy sort
  • git bisect – bináris kereséssel megtalálni, melyik commit rontotta el a dolgot

Mellette megnézzük, hogy a jól megírt commit history hogyan spórolja meg a jövőbeli hibakeresési órákat.


Részletes leírás

git log – nem csak görgetés

A git log alapból egy hosszú, nehezen olvasható listát ad. A legtöbb junior erre nyom egy Ctrl+C-t. De ez a parancs annál sokkal több.

Az olvasható forma:

git log --oneline

Kimenet:

a3f1c2e fix: null pointer hiba a user törlőnél
d82b0f1 feat: email küldés hozzáadva
c14a7d9 refactor: authentication modul szétválasztva

Ez már kezelhető. Egy sor = egy commit = könnyen áttekinthető.

A vizuális history – branching és merge-ek megértéséhez:

git log --oneline --graph --all

Kimenet (részlet):

*   b3c9d1f Merge pull request #42 from feature/payments
|\  
| * f8a2e10 feat: Stripe integráció
| * 1d4b7c3 fix: payment callback URL javítva
* | 9e2a3f1 fix: login redirect hiba
|/  
* 2c7d8b0 feat: user regisztráció

Ez megmutatja a branch-ek életútját. Mikor ágaztak el, mikor kerültek vissza mainre. Ha regressziót keresel, ez a nézet segít behatárolni, melyik ág hozta be a hibát.

Szűrés időre és szerzőre:

# Csak az utolsó 2 hét commitjai
git log --oneline --since="2 weeks ago"

# Egy adott szerző munkái
git log --oneline --author="Kovács Anna"

# Egy adott fájl history-ja
git log --oneline -- src/auth/login.py

Ez utóbbi különösen hasznos: ha egy fájl „megváltozott és nem tudom mióta rosszul működik", a fájl szintű log megmutatja az összes vonatkozó commitot.

Diff a commitban:

git log -p --follow -- src/auth/login.py

A -p flag hozzáadja az egyes commitokhoz a tényleges változtatást. A --follow átkövet fájl-átnevezésen is.


git blame – ki írta ezt a sort?

A neve sötéten hangzik, de a git blame nem bűnbakkeresési eszköz – hanem kontextus-keresési eszköz. Az a célja, hogy megértsd: miért van itt ez a sor, mikor kerülhetett be, és van-e mellette valami releváns commit üzenet.

git blame src/auth/login.py

Kimenet (részlet):

^a3f1c2e (Kovács Anna  2024-03-12 14:23:11 +0100 42) def validate_token(token):
^a3f1c2e (Kovács Anna  2024-03-12 14:23:11 +0100 43)     if token is None:
d82b0f1a (Nagy Péter   2024-04-02 09:11:05 +0100 44)         raise ValueError("Token nem lehet üres")
^a3f1c2e (Kovács Anna  2024-03-12 14:23:11 +0100 45)     return decode_jwt(token)

Minden sorhoz látod: commit hash, szerző neve, dátum, sor száma, sor tartalma.

Mit csinálj ezzel:

  1. Megtalálod, melyik commit változtatta meg az adott sort
  2. Megnézed azt a commitot részletesen: git show d82b0f1a
  3. Olvasod a commit üzenetet – és lehetséges, hogy a MIÉRT ott van leírva

Mikor NEM a git blame a helyes eszköz:

  • Ha bűnbakot keresel. („Ő írta, ő a hibás.") A blame a kontextusért van, nem az ujjmutatásért.
  • Ha az egész fájl át lett formatálva (whitespace-only commit): az összes sor ugyanazt a commitot mutatja, ami nem informativ.
  • Ha a fájlt átmozgatták anélkül, hogy a -C opciót használták volna a commit-ban: a history megszakad.

git bisect – bináris keresés a hibás commitban

Képzeld el: valaki jelzi, hogy „a fizetési folyamat valahol elromlott az utóbbi 3 hétben". Megnézed a logot: 60 commit van az utóbbi 3 hétből. Melyik törte el?

Kézzel végignézni 60 commitot: szenvedés. A git bisect ezt bináris kereséssel csinálja meg.

Hogyan működik:

A bináris keresés elve: mindig felezd a keresési teret. 60 commitból 6 lépés alatt megtalálod a hibásat (log₂(60) ≈ 6).

Használat lépései:

# 1. Indítsd el a bisect folyamatot
git bisect start

# 2. Jelöld meg, hogy a jelenlegi állapot rossz
git bisect bad

# 3. Jelöld meg az utolsó ismert jó állapotot (pl. 3 hetes commit)
git bisect good a1b2c3d

# → Git automatikusan checkout-ol egy közbülső commitot
# Teszteld: működik-e a fizetési folyamat?

# Ha működik:
git bisect good

# Ha nem működik:
git bisect bad

# → Git újra felezi, checkout-ol, teszteled...
# Néhány lépés után:
# "b7f3a1c is the first bad commit"

# 4. Miután megvan a hibás commit:
git bisect reset  # visszaállít az eredeti állapotba

Automatizált bisect:

Ha van teszted, amit lefuttathatsz:

git bisect start
git bisect bad HEAD
git bisect good v1.2.0
git bisect run python -m pytest tests/test_payment.py

A Git automatikusan végigfut a commitokon, lefuttatja a tesztet, és megtalálja a hibás commitot – beavatkozás nélkül.

Mikor éri meg a bisect?

  • Sok commit között kell keresni (10+)
  • A hiba reprodukálható (le tudod ellenőrizni: jó-e vagy rossz)
  • Nem tudod a hibát a logból beazonosítani

Hogyan írj historyt, ami segíti a jövőbeli hibakeresést?

A git log, git blame és git bisect csak annyit ér, amennyit a commit üzenetek. Egy „fix" nevű commit hihetetlen frusztrációt okoz 3 hónap múlva.

A jó commit üzenet a jövőbeli detective munkáját segíti:

Rossz:

fix: javítás

Jó:

fix: token validáció hibás null check javítva

A validate_token() None értékre RuntimeError-t dobott
ValueError helyett, ami elnyelte a logging rendszer.
Fixes #234

A blame+log-barát commit azt mondja el:

  • Mit változtattál (és ez legyen a subject-ből érthető)
  • Miért változtattál (és ez a body-ba kerül)
  • Kapcsolódó ticket vagy issue referencia (ha van)

Ennyi befektetés az íráskor órákat spórol debuggoláskor.


Életszerű példák

1. eset: „Mióta lassabb a betöltés?"

Anna senior fejlesztő jelzi, hogy a dashboard lassabb lett az utóbbi hetek óta. Nincs hibaüzenet, csak lassabb.

Gábor junior nekiáll:

# Melyik commitok érintették a dashboard fájlokat az utóbbi 3 hétben?
git log --oneline --since="3 weeks ago" -- src/dashboard/

# Kimenet:
# f3a1b2c feat: dashboard új szűrők hozzáadva
# 9e2c4d1 refactor: dashboard API hívások átírva
# 2b7a3f0 fix: dashboard betöltési spinner javítva

A refactor: dashboard API hívások átírva gyanús. Megnézi:

git show 9e2c4d1

Látja: az átírásban minden szűrőértékhez külön API hívás lett, míg előtte egy batch hívás volt. N+1 query probléma – commit üzenet nem mondta el a „miért"-et, de a diff egyértelmű.


2. eset: „Ki rakta bele ezt a hardcoded URL-t?"

Kódátvizsgálásnál Béla talál egy sorban hardcoded staging URL-t:

API_BASE = "https://staging.example.com/api"
git blame src/config.py

Kimenet megmutatja: 6 héttel ezelőtt, egy sürgős hotfix commitban került be. A commit üzenet: „hotfix: API hiba ideiglenesen javítva". Az „ideiglenesen" maradt.

Béla megtalálja a commitot, megérti a kontextust, és most már nem kérdőjelezi meg a szerzőt – hanem megírja a proper fix-et és egy TODO ticketet.


3. eset: „Valahol elromlott a belépés, de nem tudjuk mikor"

Péter junior megkapja: „A 2FA belépés valahol elromlott az utóbbi 2 hétben."

git bisect start
git bisect bad HEAD
git bisect good $(git log --oneline --since="2 weeks ago" | tail -1 | cut -d' ' -f1)

# Git checkout-ol egy közbülső commitot
# Péter manuálisan leteszteli a 2FA belépést: hibás → bad
git bisect bad

# Git checkout-ol ismét
# Leteszt: hibás → bad
git bisect bad

# Git checkout-ol ismét
# Leteszt: működik → good
git bisect good

# Git megtalálja:
# "e3f1a2b is the first bad commit"
git show e3f1a2b

Commit üzenet: „feat: session timeout rövidítése". A diff mutatja: a timeout értéket ms-ból s-ba változtatták, de elfelejtették a 2FA token validáció timeoutját is frissíteni. Megvan a hiba.


Tesztfeladatok

1. feladat – Parancs párosítás

Párosítsd a Git parancsot a leírással:

ParancsLeírás
git log --onelineA) Megmutatja, ki módosított egy adott sort, mikor és melyik commitban
git log --graph --allB) Tömörített egysoronkénti history
git blameC) Megmutatja a branch-ek elágazását és összeolvadását vizuálisan
git bisectD) Bináris kereséssel megtalálja, melyik commit vezette be a hibát
git log -p -- fájlE) Egy adott fájl commitjait mutatja a tényleges változtatásokkal

2. feladat – git log kimenet értelmezése

Az alábbi git log --oneline --graph kimenet alapján válaszolj a kérdésekre:

*   c4f2a1b Merge pull request #88 from feature/notifications
|\  
| * 9d1e3b2 feat: email értesítések hozzáadva
| * 7a4c0f1 fix: SMTP konfiguráció javítva
* | 3b8f2e1 fix: user profile kép feltöltési hiba
|/  
* 1e9a7d3 feat: user profil beállítások
* 0f4b6c8 Initial commit

Kérdések:

  1. Hány branch-en folyt párhuzamosan a fejlesztés?
  2. Melyik commit javított egy hibát a main branchen a feature branch fejlesztése közben?
  3. Melyik commit az SMTP-vel kapcsolatos?
  4. Mi volt a merge előtti utolsó közös pont (melyik commit volt mindkét branch alapja)?

3. feladat – git blame olvasás

Az alábbi git blame részlet alapján:

^3a1b2c9 (Tóth Bence   2024-01-15 10:22:31 +0100 78) def calculate_discount(price, user):
^3a1b2c9 (Tóth Bence   2024-01-15 10:22:31 +0100 79)     if user.is_premium:
f9e2d1a0 (Kiss Réka    2024-03-28 16:45:02 +0100 80)         return price * 0.8
^3a1b2c9 (Tóth Bence   2024-01-15 10:22:31 +0100 81)     return price

Kérdések:

  1. Ki és mikor adta hozzá a 80. sort?
  2. Mi volt az eredeti kedvezmény logika Bence verziójában (ha a 80. sor nem volt ott)?
  3. Hogyan derítsd ki, mi volt a változtatás oka? Melyik git parancsot futtatnád?
  4. Ha a 80. sor hibás (pl. rossz diszkont arány), kit kell megkérdezni a kontextusért?

4. feladat – git bisect logika

Egy csapatban 50 commit keletkezett az elmúlt 2 hétben. Valahol egy regresszió csúszott be: a PDF export funkció 404-et ad. A 2 héttel ezelőtti verzió még működött.

Minimum hány bisect lépéssel (good/bad döntéssel) lehet megtalálni a hibás commitot?

A) 5 lépés
B) 6 lépés
C) 7 lépés
D) 25 lépés

Indokold a válaszod!


5. feladat – Commit üzenet értékelés

Értékeld az alábbi commit üzeneteket abból a szempontból: mennyire segítik a jövőbeli hibakeresést git blame és git log során?

A commit:

update stuff

B commit:

fix: session kezelés javítva

C commit:

fix: session lejárat 30 percre állítva (volt: undefined)

A bejelentkezés után a session soha nem járt le, mert a
SESSION_LIFETIME változó nem volt beállítva és az alapértelmezett
érték undefined volt. Ez biztonsági kockázat volt.
Refs: #412

Kérdések:

  1. Melyik commit üzenet a legkevésbé hasznos git blame esetén? Miért?
  2. Melyik commit üzenet a leghasznosabb git bisect után (amikor megtaláltad a hibás commitot)? Miért?
  3. A „B" commit elégséges-e, ha a git show-ban látható a diff is?

6. feladat – Szituációs döntés

Melyik git parancsot használnád az alábbi szituációkban? (Egy-egy sorban indokold is.)

  1. Szituáció: Egy tesztfájl egy sora furcsa – nem illeszkedik a körülötte lévő logikához. Meg szeretnéd tudni, mikor és miért kerülhetett be.
  1. Szituáció: Az alkalmazás prod-on eldobott egy exception-t, ami valahol a login folyamatban van. Tudod, hogy 3 héttel ezelőtt még nem volt. Az utóbbi 3 hétben 40 commit keletkezett, és a hiba reprodukálható.
  1. Szituáció: Egy új csapattag megkérdezi: „Mikor vezettük be a dark mode funkciót és kik dolgoztak rajta?" A feature branch már be van mergelve.
  1. Szituáció: Egy fájl törölve lett, de nem tudod, mikor és ki törölte.

7. feladat – History alapú nyomozás

Az alábbi git log --oneline kimenet egy kis projekt utolsó 10 commitját mutatja (legújabbtól régibbig):

f1a2b3c fix: törlés után helyes redirect
e4d5c6b feat: komment szerkesztés hozzáadva
d7e8f9a fix: XSS javítás a komment mezőben
c1b2a3d feat: komment törlés hozzáadva
b4c5d6e feat: komment lista megjelenítés
a7b8c9d feat: komment hozzáadás
9f1e2d3 refactor: user controller szétválasztva
8a2b3c4 fix: user regisztráció email validáció
7d1e2f3 feat: user profil szerkesztés
6c4b5a6 Initial commit: user login és regisztráció

Kérdések:

  1. Melyik commit vezette be legvalószínűbben a komment törlés regresszióját, ha a redirect hiba a törlés funkció bevezetése óta volt?
  2. Mit csinálnál, ha a d7e8f9a commitot meg akarod érteni pontosan (melyik mezőben volt XSS és hogyan lett javítva)?
  3. Ha be akarnád határolni, hogy az XSS hiba mikor és melyik commitban jelent meg, melyik eszközt használnád és miért?

8. feladat – igaz/hamis

Jelöld meg, hogy az állítás igaz vagy hamis, és ha hamis, írj helyes változatot.

  1. A git blame elsősorban arra való, hogy megtaláljuk, ki a hibás a bugért.
  2. A git bisect bináris keresést alkalmaz: 64 commit között 6 lépésben megtalálja a hibásat.
  3. A git log --oneline -- fájlnév megmutatja az összes commitot, ami az adott fájlt érintette.
  4. A git bisect run <parancs> automatikusan végigfuttatja a teszteket és megkeresi a hibás commitot.
  5. A jó commit üzenet csak a „mit" mondja el, a „miért" felesleges és zajt okoz.
  6. A git log --graph --all csak a saját branch-ünk history-ját mutatja.
Scroll to Top