Vezérlőpult
12. Összefésülés (merge) · Ágak és összefésülés

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

Összefésülés (merge)

Az ágakon elkészült munkának egyszer vissza kell kerülnie a fő ágba. Ezt az összefésülés (merge) végzi. Megnézzük a két alapesetet: a fast-forwardot, amikor elég előretolni a címkét, és a háromutas összefésülést, amely egy merge commitot hoz létre. Megtanulod azt is, hogyan dönt a Git fájlonként, és mire jók a --no-ff, --ff-only és --squash kapcsolók.

CLI + DesktopMerge-laborHáromutas döntőSzimulátor15 kvízkérdés

Tanulási célok

1Mi az összefésülés?

Az összefésülés (merge) egy másik ág változásait beépíti abba az ágba, amelyen éppen állsz. A két lépés sorrendje fontos:

PS> git switch main              # 1. állj a CÉL ágra (ahová a munka kerüljön)
PS> git merge feature/galeria    # 2. fésüld bele a FORRÁS ágat
feature/galeriaforrás: innen jön a munka
➜ git merge ➜
maincél: itt állsz (HEAD)

2Fast-forward: csak előre kell tolni

Ha a cél ágon az elágazás óta nem készült új commit, akkor a forrás ág története egyszerűen „folytatja” a célét. A Gitnek nem kell semmit összefésülnie: csak előretolja a main címkét a forrás ág végére. Új commit nem keletkezik.

Előtte

A git merge feature után

PS> git merge feature/galeria
Updating 2f6a9c3..9b2e4f1
Fast-forward
 galeria.html | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 galeria.html

3Háromutas összefésülés és a merge commit

Ha az elágazás óta mindkét ágon készült commit, a történet szétvált, előretolással nem lehet egyesíteni. Ilyenkor a Git három állapotot vet össze:

Ahol csak az egyik oldal változtatott, azt átveszi; az eredményből pedig egy új merge commitot készít, amelynek két szülője van.

Előtte: szétvált ágak

A git merge feature után

PS> git merge feature/galeria
Auto-merging index.html
Merge made by the 'ort' strategy.
 galeria.html | 12 ++++++++++++
 index.html   |  1 +
 2 files changed, 13 insertions(+)
PS> git log --oneline --graph
*   c4e18a0 (HEAD -> main) Merge branch 'feature/galeria'
|\
| * 9b2e4f1 (feature/galeria) feat: galéria oldal
* | 5c7d013 fix: telefonszám javítása
|/
* 2f6a9c3 Kezdőlap első változata

4Merge-labor

Válassz egy kiinduló helyzetet és egy összefésülési módot, és nézd meg, milyen lesz a történet!

Mi lesz a git merge feature után?

Helyzet
Parancs

Előtte

Utána


    

5Hogyan dönt a Git?

A háromutas összefésülés szabálya egyszerű: a Git minden fájlt (és azon belül minden sort) a közös őshöz hasonlít.

Közös ősMi (main)Ők (feature)Eredmény
AAAA: senki nem változtatott
AABB: csak ők változtattak, átvesszük
ABAB: csak mi változtattunk, megmarad
ABBB: ugyanazt változtattuk
ABC⚡ ütközés: mindketten mást, ugyanott

Ez soronként is működik: ha ugyanabban a fájlban mi az elejét, ők a végét módosították, a Git mindkét változást automatikusan beépíti (Auto-merging index.html). Ütközés csak akkor van, ha ugyanazt a részt változtattátok meg eltérően, vagy az egyik fél törölt egy fájlt, amelyet a másik módosított. Ennek feloldása a 13. fejezet témája.

Háromutas döntő: mi lesz az eredmény?

A közös őshöz képest ki mit változtatott? Döntsd el, mit tesz a Git!

1 / 8Pontszám: 0
…

6--no-ff, --ff-only, --squash

ParancsMit csinál?Mikor jó?
git merge featureha lehet, fast-forward; ha nem, merge commitaz alapeset
git merge --no-ff featureakkor is merge commitot készít, ha fast-forward lehetneha a történetben látszódjon, hogy ezek a commitok egy funkcióhoz tartoztak
git merge --ff-only featurecsak fast-forwardot enged; ha az nem lehetséges, megállha biztosan nem akarsz merge commitot (pl. egy frissítésnél)
git merge --squash featurea feature összes változását előkészíti, de nem commitol; utána egyetlen commitot készíteszha sok apró „wip” commitot egyetlen tiszta commitként akarsz a main-be tenni
ℹ️ A GITHUBON IS EZEK A LEHETŐSÉGEK

Egy pull request (20. fejezet) lezárásakor a GitHub ugyanezt a hármat kínálja: Create a merge commit (≈ --no-ff), Squash and merge (≈ --squash) és Rebase and merge (14. fejezet).

⚠️ SQUASH UTÁN A FEATURE ÁG „NEM BEOLVASZTOTT”

A --squash új commitot készít, a feature ág commitjai nem kerülnek a main történetébe. A git branch -d feature ezért figyelmeztet (not fully merged), noha a tartalom már bent van. Ilyenkor a -D a helyes választás.

7Takarítás: a beolvasztott ágak

A beolvasztott ág feladata véget ért, a címkéje törölhető. A commitok megmaradnak, hiszen a main története már tartalmazza őket.

PS> git branch --merged          # azok az ágak, amelyek már benne vannak a mostaniban
  feature/galeria
  fix/telefon
* main
PS> git branch -d feature/galeria fix/telefon
Deleted branch feature/galeria (was 9b2e4f1).
Deleted branch fix/telefon (was 5c7d013).
PS> git branch --no-merged       # amelyek még NINCSENEK beolvasztva (ezeket ne töröld!)

8Ha rosszul sikerült

HelyzetMegoldás
az összefésülés ütközéssel megállt, és inkább kiszállnálgit merge --abort: minden visszaáll a merge előtti állapotra (13. fejezet)
a merge elkészült, de még nem töltötted felgit reset --hard ORIG_HEAD: az ORIG_HEAD a merge előtti helyzetet jegyzi meg (10. fejezet: reset)
a merge commit már fent van a GitHubongit revert -m 1 <merge-hash>: új commit visszafordítja; a -m 1 mondja meg, hogy az első szülő (a main) a „fő” ág

9Összefésülés a Desktopban és a VS Code-ban

Desktop GitHub Desktop
  • Válts a cél ágra (Current branch), majd Branch → Merge into current branch… (Ctrl+Shift+M).
  • Válaszd ki a forrás ágat. A Desktop előre jelzi, hány commit jön át, és lesz-e ütközés (This will merge 2 commits… / There will be 1 conflicted file).
  • A gomb legördülő részéből a mód is választható: Create a merge commit, Squash and merge, Rebase.
  • Ne felejtsd el utána a Push origin gombot (18. fejezet), ha a GitHubra is fel kell kerülnie.
IDE VS Code
  • Ctrl+Shift+P → Git: Merge… (régebben Git: Merge Branch…), majd válaszd ki a forrás ágat.
  • Ütközés esetén a fájl a Merge Changes csoportba kerül, és megnyitható a merge editor (13. fejezet).
  • A Git Graph bővítményben jobb klikk egy ágon → Merge into current branch…, a no fast-forward és a squash is bejelölhető.
Web GitHub.com
  • A GitHubon az ágakat pull requesttel fésüljük össze (20. fejezet): a kódot a csapat előbb átnézi, és a gomb csak utána zöld.
  • Ha egy PR-ban a fő ág közben előrébb jutott, az Update branch gomb a main-t fésüli bele a feature ágba.

10Gyakorlás a szimulátorban

Az iskolaujsag repóban két ág vár összefésülésre: egy új hírek rovat és egy lábléc-javítás. Fésüld be őket a main-be, készíts egy --no-ff összefésülést is, végül takarítsd el a beolvasztott ágakat. A gráf élőben mutatja a változást.

PowerShell + Git

Windows PowerShell
Küldetések 0 / 8
    Az iskolaujsag repó commitgráfja

    11Feladatok

    Gyakorló feladatok

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

    12.1⭐CLI

    Hozz létre egy ágat, commitolj rajta kétszer, és fésüld vissza a main-be! Fast-forward vagy merge commit lett? Miért? Ellenőrizd a git log --oneline --graph --all paranccsal.

    12.2⭐CLI

    Hozz létre két ágat ugyanabból a commitból, mindkettőn módosíts egy-egy különböző fájlt, majd fésüld mindkettőt a main-be. Nézd meg a merge commitot a git show-val: hol látszik a két szülő?

    12.3⭐

    A Merge-laborban próbáld ki mind a nyolc kombinációt (2 helyzet × 4 parancs), és írd le egy mondatban mindegyik eredményét!

    12.4⭐⭐CLI

    Ugyanabban a fájlban az egyik ágon a fájl elejét, a másikon a végét módosítsd, és fésüld össze őket. Lett ütközés? Mi az Auto-merging sor jelentése?

    12.5⭐⭐Desktop

    A GitHub Desktopban fésülj be egy ágat a Merge into current branch… ablakkal, egyszer Create a merge commit, egyszer Squash and merge móddal. Hasonlítsd össze a History fülön az eredményt!

    12.6⭐⭐CLI

    Készíts egy összefésülést, majd vond vissza a git reset --hard ORIG_HEAD paranccsal! Ellenőrizd a git reflog-ban, mi történt.

    12.7⭐⭐⭐CLI

    Egy repóban ne legyen közös ős: hozz létre egy „árva” ágat (git switch --orphan uj), commitolj rajta, és próbáld a main-be fésülni. Olvasd el a hibaüzenetet (refusing to merge unrelated histories), és nézz utána, mikor lehet szükség az --allow-unrelated-histories kapcsolóra (19. fejezet).

    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
    összefésülés (merge)egy másik ág változásainak beépítése az aktuális ágba
    cél ág · forrás ágahol állsz (ide kerül a munka) · amelyet beolvasztasz
    fast-forwarda cél ág címkéje egyszerűen előrelép, mert közben nem készült rajta új commit; nincs merge commit
    háromutas összefésülésa közös ős, a mi és az ő változatunk összevetése szétvált ágaknál
    közös ős (merge base)az utolsó commit, amely mindkét ág történetében szerepel
    merge commitkét szülővel rendelkező commit, amely két ág történetét egyesíti
    ours · theirsösszefésüléskor: a mi (cél, HEAD) oldalunk · a beolvasztott ág oldala
    --no-ff · --ff-only · --squashmindig merge commit · csak fast-forward · az összes változás egy új commitba
    ORIG_HEADa HEAD helye egy merge vagy reset előtt; git reset --hard ORIG_HEAD visszaállít
    git branch --mergedazok az ágak, amelyek már be vannak olvasztva (biztonságosan törölhetők)

    14Összegzés

    1. Összefésüléskor a cél ágon állsz: git switch main, majd git merge feature. Csak a cél ág változik.
    2. Fast-forward: ha a cél ágon nem készült új commit, a címke csak előrelép, és nem jön létre új commit.
    3. Háromutas: szétvált ágaknál a közös ős, a mi és az ő változatunk alapján merge commit készül, két szülővel.
    4. Ahol csak az egyik fél változtatott, a Git automatikusan dönt; ütközés csak az ugyanott eltérő változtatásnál van.
    5. --no-ff · --ff-only · --squash; takarítás: git branch --merged + -d; visszavonás: --abort, reset --hard ORIG_HEAD, revert -m 1.

    A következő fejezetben megnézzük, mi a teendő, ha a Git nem tud dönteni: konfliktusok feloldása.