Vezérlőpult
13. Konfliktusok feloldása · Ágak és összefésülés

3. témakör · Ágak és összefésülés · 13. fejezet

Konfliktusok feloldása

Előbb-utóbb mindenki találkozik vele: a Git megáll, és ezt írja: CONFLICT … Automatic merge failed. Ez nem hiba, és semmi nem veszett el. Csak ketten ugyanazt a részt változtattátok meg eltérően, és a Git nem akar helyetted dönteni. Megtanulod felismerni, elolvasni és feloldani a konfliktust parancssorból, a VS Code-ban és a GitHub Desktopban.

CLI + Desktop + VS CodeKonfliktus-feloldóSorrend-kirakóSzimulátor15 kvízkérdés

Tanulási célok

1Mikor keletkezik konfliktus?

A 12. fejezetben láttad: a Git a közös ősből kiindulva dönt, és ha csak az egyik fél változtatott valamit, azt automatikusan átveszi. Konfliktus (ütközés) csak akkor van, ha a Git nem tudja eldönteni, melyik változat a jó:

FajtaMi történt?A Git üzenete
tartalmiugyanazt a sort (részt) mindketten másképp módosítottátokCONFLICT (content)
módosítás/törlésaz egyik fél módosította a fájlt, a másik törölteCONFLICT (modify/delete)
mindkettő hozzáadtaugyanazon a néven mindketten új, eltérő fájlt hoztatok létreCONFLICT (add/add)

Konfliktus nemcsak git merge-nél lehet, hanem minden olyan parancsnál, amely két változatot egyesít: git pull (18. fejezet), git rebase és git stash pop (14.), git revert (10.), git cherry-pick (28.). A feloldás mindegyiknél ugyanígy megy.

💡 NE ESS PÁNIKBA

A konfliktus nem hiba és nem baleset. A Git megállt, hogy te dönts, és minden változat megvan. Ha elbizonytalanodsz, a git merge --abort mindent visszaállít az összefésülés előtti állapotra.

2A konfliktus felismerése

PS> git merge feature/kapcsolat
Auto-merging kapcsolat.txt
CONFLICT (content): Merge conflict in kapcsolat.txt
Automatic merge failed; fix conflicts and then commit the result.
PS> git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   kapcsolat.txt

3A konfliktusjelölők

Az ütköző helyre a Git mindkét változatot beírja a fájlba, jelölőkkel elválasztva. A fájl többi része érintetlen.

Kapcsolatváltozatlan rész
<<<<<<< HEADitt kezdődik a mi változatunk (ahol a HEAD áll: a main)
Telefon: +36 30 222 2222current (a jelenlegi ág, ours)
=======elválasztó
Telefon: +36 30 999 9999incoming (a beolvasztott ág, theirs)
>>>>>>> feature/kapcsolatvége; mögötte a beolvasztott ág neve
E-mail: info@klub.huváltozatlan rész

A feloldás azt jelenti, hogy ezt a blokkot kicseréled a végleges szövegre: megtarthatod az egyiket, a másikat, mindkettőt, vagy írhatsz egy új változatot. A lényeg, hogy a végén egyetlen jelölő se maradjon a fájlban.

ℹ️ A KÖZÖS ŐS IS MEGJELENÍTHETŐ

A git config --global merge.conflictStyle zdiff3 beállítás után a Git a két változat közé a közös ős változatát is beírja (||||||| merged common ancestor után). Így jobban látszik, ki mit változtatott az eredetihez képest.

4A feloldás lépései

  1. Nézd meg, mi ütközik: git status.
  2. Nyisd meg az ütköző fájlt (VS Code, Desktop → Open in Visual Studio Code), és keresd meg a <<<<<<< jelölőket.
  3. Dönts minden blokknál: a mi változatunk, az övék, mindkettő, vagy egy új. Ha nem tudod, kérdezd meg a társadat, aki a másik oldalt írta!
  4. Töröld a jelölőket, és mentsd a fájlt. Ha kód, ellenőrizd, hogy működik.
  5. Jelöld feloldottnak: git add kapcsolat.txt. (Ez a Gitnek azt jelenti: „ez a végleges változat”.)
  6. Zárd le az összefésülést: git commit (a merge üzenete kész; --no-edit nélkül a szerkesztő nyílik meg), vagy git merge --continue.

Sorrend-kirakó: mi a helyes sorrend?

Kattints a lépésekre abban a sorrendben, ahogy egy konfliktus feloldásakor elvégzed őket!

    5Konfliktus-feloldó

    A VS Code-hoz hasonló felületen oldj fel négy konfliktust! Minden blokk fölött választhatsz: a jelenlegi (Current, a mi oldalunk), a bejövő (Incoming, az övék), mindkettő, vagy kézi szerkesztés. Figyeld a feladatot: nem mindig az egyik oldal a jó!

    Oldd fel, amit a csapat kért!

    6Egész fájl egyik oldalról, törlés-ütközés

    Ha egy fájlnál biztosan az egyik oldal teljes változata kell (pl. egy generált fájlnál), nem kell blokkonként dönteni:

    PS> git checkout --theirs stilus.css    # a beolvasztott ág változata (vagy: git restore --theirs)
    PS> git checkout --ours stilus.css      # a mi változatunk
    PS> git add stilus.css
    ⚠️ REBASE-NÉL FORDÍTVA

    Rebase közben (14. fejezet) az ours a célág (amire ráépítesz), a theirs pedig a saját, éppen újrajátszott commitod. Ez sokakat megtéveszt, ezért rebase-nél mindig ellenőrizd a fájl tartalmát.

    Módosítás/törlés ütközésnél (deleted by us / deleted by them) két döntés közül választhatsz:

    7A VS Code merge editora

    Accept Current Change | Accept Incoming Change | Accept Both Changes | Compare Changes
    <<<<<<< HEAD (Current Change)
    Telefon: +36 30 222 2222
    =======
    Telefon: +36 30 999 9999
    >>>>>>> feature/kapcsolat (Incoming Change)

    8A GitHub Desktopban és a GitHubon

    Desktop GitHub Desktop
    • Ütközéskor a Resolve conflicts before merging ablak listázza az ütköző fájlokat (1 conflicted file).
    • Minden fájlnál: Open in Visual Studio Code (vagy a beállított szerkesztő), illetve a legördülő menüből Use the modified file from main / from feature/… (ez a --ours / --theirs).
    • Ha minden fájl mellett zöld pipa van (No conflicts remaining), a Continue merge elkészíti a merge commitot. Az Abort merge kiszáll.
    Web GitHub.com (pull request)
    • Ha egy pull request ütközik, a PR alján ez áll: This branch has conflicts that must be resolved.
    • Egyszerű (szöveges) ütközésnél a Resolve conflicts gomb webes szerkesztőt nyit: töröld a jelölőket, majd Mark as resolved → Commit merge.
    • Bonyolultabb esetben a gomb nem használható; ilyenkor helyben oldd fel (fésüld be a main-t a feature ágba), és töltsd fel.

    9Hogyan előzd meg?

    10Gyakorlás a szimulátorban

    A klubnap repóban három ág vár a main-re. Mindegyik ütközni fog: egyiket kézzel oldod fel, egyikből kiszállsz, egyiknél az egész fájlt a bejövő oldalról veszed. Az ütköző fájlok egysorosak, így a "…" | Set-Content fájl paranccsal egyszerűen felülírhatod őket.

    PowerShell + Git

    Windows PowerShell
    Küldetések 0 / 8
      A klubnap repó commitgráfja

      11Feladatok

      Gyakorló feladatok

      ⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás

      13.1⭐CLI

      Idézz elő szándékosan egy konfliktust: két ágon módosítsd ugyanannak a fájlnak ugyanazt a sorát, majd fésüld össze őket. Olvasd el a git status kimenetét és a fájl tartalmát, majd szállj ki a git merge --abort paranccsal.

      13.2⭐IDE

      Idézd elő újra, és oldd fel a VS Code-ban az Accept Both Changes gombbal! Utána a Source Control panelen készítsd elő és commitold.

      13.3⭐

      Oldd meg a Konfliktus-feloldó mind a négy feladatát úgy, hogy mindegyik elsőre sikerüljön!

      13.4⭐⭐Desktop

      A GitHub Desktopban fésülj össze két ütköző ágat! Az egyik fájlt a Use the modified file from … menüponttal, a másikat a szerkesztőben oldd fel, majd Continue merge.

      13.5⭐⭐CLI

      Állítsd be a git config --global merge.conflictStyle zdiff3-at, és idézz elő egy konfliktust. Mit mutat most a fájl a ||||||| jelölő után? Miben segít ez a döntésben?

      13.6⭐⭐CLI

      Hozz létre módosítás/törlés ütközést: az egyik ágon töröld a fájlt, a másikon módosítsd. Nézd meg a git status üzenetét, és oldd meg egyszer git add-dal (marad), egyszer git rm-mel (törlődik).

      13.7⭐⭐⭐Web

      Párban: mindketten ugyanabban a GitHub-repóban, két ágon módosítsátok a README ugyanazt a sorát, és nyissatok pull requestet mindkettőből. Az elsőt fésüljétek be, a második ütközik: oldjátok fel a GitHub webes Resolve conflicts szerkesztőjével. (Előzetes a 20. fejezethez.)

      12Önellenőrző kvíz

      Ellenőrizd magad!

      Az egyválasztós kérdéseknél kattints a válaszra. A többválasztósaknál jelöld be az összes helyeset, majd nyomd meg az Ellenőrzés gombot.

      13Fogalomtár

      FogalomJelentés
      konfliktus (merge conflict)ütközés: a Git nem tudja eldönteni, melyik változat a jó, ezért megáll
      unmerged pathütköző, még fel nem oldott fájl (git status -s: UU)
      konfliktusjelölők<<<<<<< HEAD · ======= · >>>>>>> ág: a két változat határai
      current · incominga VS Code-ban: a jelenlegi ág (ours) · a beolvasztott ág (theirs) változata
      feloldása végleges tartalom megírása a jelölők nélkül, majd git add
      git merge --abortkiszállás: minden visszaáll az összefésülés előtti állapotra
      git merge --continuea feloldás után a merge commit elkészítése (≈ git commit)
      --ours · --theirsegy ütköző fájl teljes egészében a mi / az ő változatunkból (git checkout / git restore)
      modify/deleteütközés: az egyik fél módosította, a másik törölte a fájlt; megoldás: git add vagy git rm
      merge editora VS Code háromablakos ütközésfeloldó nézete (Incoming, Current, Result)

      14Összegzés

      1. Konfliktus akkor van, ha ugyanazt a részt ketten eltérően változtattátok meg, vagy az egyik fél módosított, a másik törölt. Nem hiba: a Git a te döntésedre vár.
      2. Felismerés: CONFLICT üzenet, git status → Unmerged paths / UU.
      3. A jelölők között felül a mi (HEAD, current), alul az ő (incoming) változatuk van.
      4. Feloldás: dönts, töröld a jelölőket, git add, majd git commit. Kiszállás: git merge --abort. Egész fájl: --ours / --theirs.
      5. Megelőzés: kis commitok, rövid életű ágak, gyakori frissítés a main-ből, egyeztetés, közös formázás.

      A következő fejezetben két új eszköz jön: a munka félretétele (stash) és a történet újraalapozása (rebase).