11. Ágak (branch) és a HEAD · Ágak és összefésülés
3. témakör · Ágak és összefésülés · 11. fejezet
Ágak (branch) és a HEAD
Eddig minden commit egyetlen egyenes vonalra került. A valódi projektekben viszont egyszerre több dolgon dolgozunk: egy új funkción,
egy sürgős hibajavításon, egy kísérleten. Erre valók az ágak. Megtanulod, mi az ág valójában (meglepően egyszerű!),
mit jelent a HEAD, hogyan hozol létre ágat, és hogyan váltasz közöttük parancssorból és a GitHub Desktopban.
Érted, miért dolgozunk ágakon, és hogy az ág valójában csak egy mozgatható címke egy commiton.
Tudod, mit jelöl a HEAD, és mi a leválasztott HEAD (detached HEAD).
Ismered a main és a master nevű ág történetét.
Ágat hozol létre, váltasz, átnevezel és törölsz: git branch, git switch, git checkout.
Tudod, mi történik váltáskor a munkakönyvtárral, és ugyanezt elvégzed a GitHub Desktopban.
1Miért kellenek ágak?
Képzeld el: a csapat weboldalán egy új galéria oldalon dolgozol, félkész állapotban. Ekkor kiderül, hogy a kezdőlapon
hibás a telefonszám, és azonnal javítani kell. Ha minden egyetlen vonalon történik, a javítással együtt a félkész galéria is
„élesbe” kerülne. Ágakkal viszont:
🌿 maina mindig működő, „kiadható” változat
🧪 galeriaaz új funkció, amíg el nem készül; senkit nem zavar
🩹 fix/telefonszama gyors javítás, amely a galériától függetlenül mehet élesbe
Párhuzamos munka: mindenki a saját ágán dolgozik, nem írják felül egymást.
Biztonságos kísérletezés: ha egy ötlet zsákutcának bizonyul, az ágat egyszerűen eldobod.
Rendezett történet: egy funkció commitjai együtt vannak, és egyben kerülnek vissza a fő ágba (összefésülés: 12. fejezet).
Csapatmunka a GitHubon: a pull request (20. fejezet) mindig két ág között jön létre.
2Mi az ág valójában?
Sokan azt hiszik, hogy egy ág létrehozásakor a Git lemásolja a projekt fájljait. Nem így van. Az ág csupán egy
név, amely egy commitra mutat, egy mozgatható címke. A .git/refs/heads/ mappában minden ágnak
egy kis szövegfájl felel meg, benne egyetlen commit hash-ével:
Ágat létrehozni ezért villámgyors és ingyenes: a Git csak ír egy 41 bájtos fájlt.
Amikor egy ágon commitolsz, az új commit szülője a mostani commit lesz, és az ág címkéje továbblép az új commitra.
Két ág mutathat ugyanarra a commitra. Az ág a történet egy vonalát jelöli: a címkétől visszafelé, a szülőkön át elérhető commitokat.
ℹ️ A COMMITOK NEM „TARTOZNAK” EGY ÁGHOZ
A commit nem tárolja, melyik ágon készült. Csak a szülőjét ismeri. Ezért lehet, hogy egy commit egyszerre több ág történetének is része:
például a legelső commit minden ághoz hozzátartozik.
3A HEAD: itt állsz most
A HEAD jelöli, hogy most hol állsz: melyik ágon dolgozol, és melyik commit tartalma van a munkakönyvtárban.
Általában nem közvetlenül egy commitra, hanem egy ágra mutat. Ezt a .git/HEAD fájl tárolja:
PS>cat .git\HEAD
ref: refs/heads/main
Commitkor az az ág lép tovább, amelyre a HEAD mutat. A git log ezt így jelzi: (HEAD -> main).
Ágváltáskor (git switch galeria) a HEAD átáll a másik ágra, a munkakönyvtár pedig annak a commitnak a tartalmát kapja.
A HEAD~1, HEAD~2 hivatkozások (8. fejezet) mindig innen, a HEAD-től számolnak visszafelé.
4Ág-játszótér
Próbáld ki gombokkal! Commitolj, hozz létre ágat, válts! Figyeld, melyik címke lép tovább commitkor, hová mutat a HEAD, és mi van a
.git mappában. Ha egy commitra rákattintasz, a HEAD leválik róla (8. szakasz).
Címkék és a HEAD
Commitgráfkattints egy commitra a leválasztott HEAD-hez
Kiadott parancsok
A .git mappában
5main vagy master?
Az első ágnak nincs különleges szerepe, a neve is csak megállapodás. A Git hosszú ideig master néven hozta létre,
2020 óta a GitHub az új repóknál a main nevet használja, és ma a legtöbb eszköz is ezt javasolja.
Régebbi projektekben és leírásokban ezért még gyakran találkozol a master-rel. A kettő ugyanazt a szerepet tölti be.
# az alapértelmezett név beállítása (2. fejezet)PS>git config --global init.defaultBranch main# egy meglévő repó master ágának átnevezésePS>git branch -m master main
💡 NÉZD MEG, MI A FŐ ÁG NEVE
Mielőtt egy idegen repóban parancsokat gépelsz, a git branch megmutatja, hogy main vagy master
a fő ág. Sok hibaüzenet (pathspec 'main' did not match…) abból adódik, hogy a repóban a másik név van használatban.
6Ágak parancssorból
Parancs
Mit csinál?
git branch
kilistázza a helyi ágakat; a * jelöli, hol állsz (-v: az utolsó commit is)
git branch galeria
új ágat hoz létre a mostani commitnál, de nem vált rá
git switch galeria
átvált egy meglévő ágra
git switch -c galeria
létrehozza az ágat, és rögtön át is vált rá (-c = create)
git checkout galeria git checkout -b galeria
ugyanez a régebbi paranccsal (váltás / létrehozás + váltás)
git switch -
vissza az előző ágra
git branch -m régi új
átnevez egy ágat (egy névvel: a mostanit)
git branch -d galeria
törli az ágat, ha már be van olvasztva; különben figyelmeztet
git branch -D galeria
kényszerített törlés: a be nem olvasztott commitok is elhagyhatók (a reflogból még visszahozhatók)
git log --oneline --graph --all
az összes ág története rajzzal
PS>git switch -c galeria
Switched to a new branch 'galeria'
PS>git branch* galeria
main
PS>git log --oneline --graph --all*9b2e4f1(HEAD -> galeria) feat: galéria oldal
| *5c7d013(main) fix: telefonszám javítása
|/*2f6a9c3 Kezdőlap első változata
A rajzon látszik: a két ág a 2f6a9c3 commitnál elágazott, és azóta mindkettőn készült egy-egy commit.
Ezek összefésülése lesz a 12. fejezet témája.
Melyik parancs kell?
Válaszd ki, melyik parancs végzi el a feladatot!
1 / 8Pontszám: 0
…
7Váltás és a munkakönyvtár
Ágváltáskor a Git a munkakönyvtárat a másik ág legutolsó commitjának állapotára hozza: a fájlok tartalma megváltozik, egyes fájlok
megjelennek vagy eltűnnek. Ez nem baj: semmi nem veszett el, a fájlok a másik ág commitjaiban vannak. Visszaváltáskor visszakerülnek.
A nem commitolt módosítások „utaznak”: ha egy fájlt módosítottál, de nem commitoltad, és a két ágon ez a fájl azonos,
a módosítás átjön a másik ágra is. A Git ezt ki is írja: M index.html.
Ha ütközne, a Git nem vált: ha a módosított fájl a két ágon eltér, a váltás felülírná a munkádat. Ilyenkor megáll:
error: Your local changes to the following files would be overwritten by checkout:
index.html
Please commit your changes or stash them before you switch branches.
Aborting
A megoldás: commitold a munkát a mostani ágon, dobd el (git restore), vagy tedd
félre (git stash, 14. fejezet). A GitHub Desktop ilyenkor megkérdezi, vigye-e magával a módosításokat
(Bring my changes) vagy hagyja a régi ágon (Leave my changes, ez a háttérben stash).
💡 VÁLTÁS ELŐTT: GIT STATUS
Jó szokás ágváltás előtt a git status-szal ellenőrizni, hogy tiszta-e a munkakönyvtár
(nothing to commit, working tree clean). Így biztosan nem viszel át véletlenül félkész módosítást a másik ágra.
8A leválasztott HEAD
Ha nem ágra, hanem közvetlenül egy commitra váltasz (pl. hogy megnézd, hogyan nézett ki régen a projekt), a HEAD
leválik (angolul detached HEAD): nem ágra mutat, hanem egy commitra.
PS>git switch --detach 2f6a9c3# vagy: git checkout 2f6a9c3
HEAD is now at 2f6a9c3 Kezdőlap első változata
PS>git statusHEAD detached at 2f6a9c3
Nézelődni, fordítani, tesztelni nyugodtan lehet. Commitolni is lehet, de ezek a commitok egyik ághoz sem tartoznak.
Ha elváltasz, a Git figyelmeztet: you are leaving 1 commit behind. A commitok ekkor csak a reflogból (10. fejezet) hozhatók vissza.
Ha meg akarod tartani a munkát, készíts belőle ágat, amíg ott állsz: git switch -c kiserlet.
Vissza a normál állapotba: git switch main (vagy git switch -).
⚠️ NEM HIBA, CSAK FIGYELMEZTETÉS
A detached HEAD kifejezés ijesztően hangzik, de nem jelent bajt. Csak annyit jelent, hogy most nem ágon dolgozol. Ha véletlenül kerültél bele,
egy git switch main visszavisz.
9switch vagy checkout?
A git checkout régen nagyon sokféle dolgot csinált: ágat váltott, ágat hozott létre, commitra ugrott, és egy fájl módosításait is
visszaállította. Ez sok félreértést okozott, ezért a Git 2.23-as változata (2019) két új, egyértelmű paranccsal osztotta szét a feladatait:
Feladat
Régi alak
Új, ajánlott alak
ágváltás
git checkout galeria
git switch galeria
új ág + váltás
git checkout -b galeria
git switch -c galeria
commitra ugrás
git checkout 2f6a9c3
git switch --detach 2f6a9c3
fájl visszaállítása
git checkout -- index.html
git restore index.html (10. fejezet)
Mindkettő működik, és a régi alakot rengeteg leírásban, tesztben és kollégánál látni fogod, ezért érdemes ismerni. Saját munkához a
switch és a restore ajánlott.
10Jó ágnevek
Beszédes és rövid:galeria, kosar-kerekites. Ne uj, proba2 vagy anna.
Előtag a fajtára (csapatszabály szerint): feature/galeria, fix/telefonszam, docs/readme.
A Desktop és a GitHub a /-t mappaként csoportosítva mutatja.
Kisbetű, kötőjel, ékezet nélkül. Szóköz, ~ ^ : ? * [ és .. nem lehet benne; a Git elutasítja:
fatal: 'uj funkcio' is not a valid branch name. A GitHub Desktop a szóközt magától kötőjelre cseréli.
Ha van hozzá GitHub-feladat (issue, 23. fejezet), a szám is kerülhet bele: feature/12-galeria.
11Ágak a Desktopban és a VS Code-ban
Desktop GitHub Desktop
Felül a Current branch gomb mutatja, hol állsz; rákattintva listázza az ágakat, és egy kattintással válthatsz.
New branch (vagy Branch → New branch…, Ctrl+Shift+N): megadod a nevet és azt, melyik ágból induljon.
Ha nem commitolt módosításod van, váltáskor rákérdez: Leave my changes on … (félreteszi, stash) vagy Bring my changes to … (viszi).
Branch → Rename… és Branch → Delete…: átnevezés és törlés. A History fül az aktuális ág commitjait mutatja.
IDE VS Code
A bal alsó sarokban (állapotsor) látszik az ág neve. Rákattintva: váltás, Create new branch…, Create new branch from….
A Source Control panel … menüjében: Branch → Create / Rename / Delete Branch…
A Git Graph bővítmény (25. fejezet) a git log --graph --all-hoz hasonló, kattintható rajzot készít.
Web GitHub.com
A repó oldalán a bal felső ágválasztóval nézheted meg bármelyik ág fájljait és commitjait.
Ugyanitt új ágat is létrehozhatsz: beírod a nevet → Create branch … from main.
A Branches oldalon (…/branches) látszik minden ág, mennyivel jár előrébb vagy hátrébb a fő ághoz képest, és törölhető is.
12Gyakorlás a szimulátorban
A portfolio repóban Anna weboldala van. Készíts egy új ágon galéria oldalt, közben javíts egy sürgős hibát a fő ágon,
és nézz vissza a múltba leválasztott HEAD-del! A terminál alatt élőben látszik a commitgráf.
PowerShell + Git
Windows PowerShell— ▢ ✕
Küldetések 0 / 9
A portfolio repó commitgráfja
13Feladatok
Gyakorló feladatok
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
11.1⭐CLI
A saját repódban hozz létre egy kiserlet ágat, válts rá, és készíts rajta két commitot! Válts vissza a fő ágra: mi
történt a fájlokkal? Nézd meg a git log --oneline --graph --all kimenetét.
11.2⭐CLI
Írasd ki a .git\HEAD és a .git\refs\heads\kiserlet fájl tartalmát! Commitolj egyet, és nézd meg újra.
Mi változott, és mi nem?
11.3⭐
Az Ág-játszótéren készíts olyan állapotot, amelyben három ág van, és kettő ugyanarra a commitra mutat! Utána válaszd le a HEAD-et egy régi commitra,
commitolj, és válts vissza egy ágra. Mit jelez a játszótér?
11.4⭐⭐CLI
Módosíts egy fájlt úgy, hogy a két ágon eltérő legyen, és ne commitold! Próbálj ágat váltani. Olvasd el a hibaüzenetet, és oldd meg kétféleképpen
(commit, illetve git restore).
11.5⭐⭐Desktop
A GitHub Desktopban hozz létre egy feature/rolunk ágat, commitolj rajta, és válts vissza a fő ágra nem commitolt módosítással.
Próbáld ki a Leave my changes és a Bring my changes lehetőséget is. Mit tapasztalsz?
11.6⭐⭐CLI
Egy régi, master ágú repóban (vagy egy újonnan, git init -b master-rel létrehozottban) nevezd át az ágat
main-re, és ellenőrizd a git branch és a .git\HEAD tartalmával.
11.7⭐⭐⭐CLI
„Veszíts el” egy commitot leválasztott HEAD-en (commitolj, majd válts el), és mentsd meg: keresd meg a hash-ét a figyelmeztetésben vagy a
git reflog-ban, és hozz létre rá ágat: git branch mentes <hash>.
14Ö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.
15Fogalomtár
Fogalom
Jelentés
ág (branch)
egy commitra mutató, mozgatható név; commitkor továbblép az új commitra
main / master
a fő ág szokásos neve (a GitHubon 2020 óta main)
HEAD
ahol most állsz: általában egy ágra mutat (ref: refs/heads/main)
leválasztott HEAD (detached HEAD)
a HEAD közvetlenül egy commitra mutat, nem ágra
elágazás
két ág történetének szétválása egy közös commit után