3. témakör · Ágak és összefésülés · 13. fejezet
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.
git status kimenetéből.<<<<<<<, =======, >>>>>>>), és tudod, melyik rész honnan jön.git add, majd git commit. Szükség esetén kiszállsz: git merge --abort.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ó:
| Fajta | Mi történt? | A Git üzenete |
|---|---|---|
| tartalmi | ugyanazt a sort (részt) mindketten másképp módosítottátok | CONFLICT (content) |
| módosítás/törlés | az egyik fél módosította a fájlt, a másik törölte | CONFLICT (modify/delete) |
| mindkettő hozzáadta | ugyanazon a néven mindketten új, eltérő fájlt hoztatok létre | CONFLICT (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.
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.
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
git status -s ezeket UU jellel mutatja.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.
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 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.
git status.<<<<<<< jelölőket.git add kapcsolat.txt. (Ez a Gitnek azt jelenti: „ez a végleges változat”.)git commit (a merge üzenete kész; --no-edit nélkül a szerkesztő nyílik meg), vagy git merge --continue.Kattints a lépésekre abban a sorrendben, ahogy egy konfliktus feloldásakor elvégzed őket!
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ó!
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 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:
git add fájl,git rm fájl.git add-ot.--ours / --theirs).git merge main vagy pull, 18. fejezet): a kis ütközéseket könnyebb azonnal feloldani..editorconfig).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.
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
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.
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.
Oldd meg a Konfliktus-feloldó mind a négy feladatát úgy, hogy mindegyik elsőre sikerüljön!
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.
Á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?
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).
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.)
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.
| Fogalom | Jelenté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 · incoming | a VS Code-ban: a jelenlegi ág (ours) · a beolvasztott ág (theirs) változata |
| feloldás | a végleges tartalom megírása a jelölők nélkül, majd git add |
git merge --abort | kiszállás: minden visszaáll az összefésülés előtti állapotra |
git merge --continue | a feloldás után a merge commit elkészítése (≈ git commit) |
--ours · --theirs | egy ü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 editor | a VS Code háromablakos ütközésfeloldó nézete (Incoming, Current, Result) |
git status → Unmerged paths / UU.git add, majd git commit. Kiszállás: git merge --abort.
Egész fájl: --ours / --theirs.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).