3. témakör · Ágak és összefésülés · 14. fejezet
Két hasznos eszköz a mindennapi munkához. A stash egy „fiók”: félreteszed a félkész munkát, amikor sürgősen máshol kell dolgoznod, és később visszaveszed. A rebase a merge alternatívája: a saját commitjaidat egy új alapra „ülteti át”, így a történet egyenes marad. Megtanulod azt is, mikor ne használd a rebase-t.
git stash, list, pop, apply, drop.git rebase, és miben különbözik a merge-től.--continue, --skip, --abort).A feature/pontszam ágon dolgozol, félkész a kód. Ekkor szólnak, hogy a main-en azonnal javítani kell egy hibát. Commitolni még
nem akarsz (nem működik), ágat váltani viszont nem tudsz: a Git nem engedi, mert felülírná a módosításaidat. A megoldás:
PS> git stash -m "pontszám félkész" # félreteszed: a munkakönyvtár tiszta lesz Saved working directory and index state On feature/pontszam: pontszám félkész PS> git switch main # most már szabadon válthatsz … # … javítás, commit … PS> git switch feature/pontszam PS> git stash pop # visszaveszed, és folytatod
-u kapcsolóval teszi félre (git stash -u).stash@{0}, az előtte lévő a stash@{1} és így tovább.git push nem tölti fel.| Parancs | Mit csinál? |
|---|---|
git stash · git stash push -m "üzenet" | félreteszi a módosításokat (üzenettel könnyebb később megtalálni) |
git stash -u | a követetlen (új) fájlokat is félreteszi |
git stash list | kilistázza a félretett bejegyzéseket (stash@{0}: On main: …) |
git stash show -p stash@{1} | megmutatja, mi van egy bejegyzésben (-p: teljes diff) |
git stash pop | visszaállítja a legutóbbit, és törli a listából |
git stash apply | visszaállítja, de a listában megtartja (pl. több ágra is kell) |
git stash drop stash@{1} · git stash clear | egy bejegyzés · az összes törlése |
Ha közben ugyanazt a részt más is módosította, a pop ütközést jelez (CONFLICT … Stashed changes). Ilyenkor a bejegyzés
megmarad a listában (The stash entry is kept in case you need it again). Oldd fel a 13. fejezet szerint, majd git stash drop.
A stash rövid félretételre való. Ha napokig kellene tárolni a munkát, készíts inkább egy ágat, és commitold ott. A régi, elfelejtett stash-bejegyzésekről hetek múlva senki nem tudja, mik voltak.
Amíg a feature ágon dolgoztál, a main is haladt. A merge ezt egy merge committal egyesítené. A rebase mást csinál:
a feature saját commitjait (a közös ős utániakat) egyenként újrajátssza a main legfrissebb commitjára, mintha onnan kezdtél volna dolgozni.
PS> git switch feature PS> git rebase main Successfully rebased and updated refs/heads/feature.
Előtte
A git rebase main után
| merge | rebase | |
|---|---|---|
| Történet | megőrzi, ahogy valójában történt (elágazás + merge commit) | egyenes, „tisztított” történet |
| Meglévő commitok | változatlanok | újak jönnek létre (új hash); a régiek elhagyva |
| Ütközésfeloldás | egyszer, a merge-ben | commitonként, akár többször |
| Megosztott ágon | biztonságos | tilos (lásd az aranyszabályt) |
| Tipikus használat | kész feature beolvasztása a main-be; közös ágak frissítése | a saját, még fel nem töltött ág frissítése; commitok rendbetétele feltöltés előtt |
Egyik sem „jobb”: csapatszabály kérdése. Kezdőként a merge a biztonságosabb. A rebase-t a saját, helyi munkád rendbetételére használd.
Melyik eszköz illik a helyzethez?
PS> git rebase main CONFLICT (content): Merge conflict in jatek.js error: could not apply 9b2e4f1... feat: pontszámítás hint: Resolve all conflicts manually, mark them as resolved with hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
| Parancs | Mikor? |
|---|---|
git add fájl + git rebase --continue | feloldottad az ütközést; a rebase a következő committal folytatódik |
git rebase --skip | ezt az egy commitot kihagyod (pl. mert a main már tartalmazza a változást) |
git rebase --abort | kiszállsz: minden visszaáll a rebase előtti állapotra |
Rebase közben a HEAD le van választva (a git status: rebase in progress), és a jelölőkben a HEAD a
main-re már átültetett állapotot, a másik oldal a te éppen újrajátszott commitodat jelenti. Ezért fordított rebase-nél az ours és a theirs jelentése (13. fejezet).
Ha a commitjaid már fent vannak a GitHubon, és mások is letöltötték vagy ráépítettek, ne rebase-eld őket. A rebase új hash-ű commitokkal
cseréli le a régieket: a te gépeden más történet lesz, mint a társaidén. A feltöltéshez kényszerítés kellene (git push --force,
19. fejezet), ami a társaid munkáját összekuszálja vagy felülírja.
main és minden közös ág rebase-elése; olyan ág átírása, amelyen más is dolgozik.A git rebase -i HEAD~4 egy szerkesztőben megnyitja az utolsó négy commit „tennivaló-listáját” (a legrégebbi felül). Minden sor elején
megmondhatod, mi történjen a committal, és a sorokat át is rendezheted:
| Parancs | Jelentése |
|---|---|
pick | marad, ahogy van |
reword | marad, de új üzenetet adsz neki |
squash | beleolvad az előtte lévőbe, az üzenetek egyesülnek |
fixup | beleolvad az előtte lévőbe, a saját üzenete elvész (javító commitokhoz) |
drop | kimarad a történetből |
Feladat: a „wip” és az „elírás javítása” commit olvadjon bele az előtte lévőbe, a „fix” nevű commit kapjon beszédes üzenetet, a „teszt kiírás” pedig maradjon ki. A ▲▼ gombokkal a sorrendet is módosíthatod.
Ha csak a legutolsó commitot kell javítani, arra a git commit --amend (10. fejezet) egyszerűbb. Az interaktív rebase több, régebbi commitra való.
Mindkettő átírja a történetet, így ugyanaz az aranyszabály vonatkozik rájuk.
A kvizjatek repóban a feature/pontszam ágon állsz, félkész munkával. Sürgősen javítani kell egy hibát a main-en:
tedd félre a munkát, javíts, vedd vissza, commitold, végül ültesd át az ágadat a frissített main-re.
⭐ alap · ⭐⭐ haladó · ⭐⭐⭐ kihívás
Módosíts két fájlt, és hozz létre egy újat. Futtasd a git stash-t, majd a git status-t: mi maradt? Próbáld újra
-u-val. Nézd meg a git stash list-et, és vedd vissza mindkettőt.
A GitHub Desktopban tedd félre a módosításaidat (Stash all changes), válts ágat, térj vissza, és állítsd vissza őket (Restore).
Oldd meg az Interaktív rebase-labor feladatát, majd próbáld ki: mi történik, ha a legelső sort squash-ra állítod? Miért?
Hozz létre egy ágat két committal, közben a main-en is készíts egyet. Egyszer merge-dzsel, egyszer (egy másolaton) rebase-zel egyesítsd, és hasonlítsd össze a
git log --oneline --graph --all kimenetét és a commitok hash-ét.
Idézz elő ütközést rebase közben! Oldd fel, és folytasd --continue-val. Egy második próbánál szállj ki --abort-tal, és
ellenőrizd, hogy minden visszaállt.
Készíts három „wip” commitot, majd egy git rebase -i HEAD~3 paranccsal vond össze őket egyetlen, jó üzenetű committá (az első
pick, a többi squash). A szerkesztő a core.editor beállítás szerint nyílik meg (2. fejezet).
Írj rövid csapatszabályt arról, mikor használtok merge-et és mikor rebase-t a közös projektben! Térj ki az aranyszabályra és a GitHub pull request összefésülési módjaira is.
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 |
|---|---|
| stash | félretett, nem commitolt módosítások helyi verme |
stash@{n} | egy félretett bejegyzés; a stash@{0} a legutóbbi |
pop · apply | visszaállítás és törlés a listából · visszaállítás, a bejegyzés marad |
| rebase | a saját commitok újrajátszása egy új alapra (új hash-ekkel), egyenes történetet ad |
| interaktív rebase | git rebase -i: commitok összevonása, átnevezése, törlése, átrendezése |
pick · reword · squash · fixup · drop | marad · új üzenet · összevonás üzenettel · összevonás üzenet nélkül · kihagyás |
--continue · --skip · --abort | folytatás a feloldás után · a commit kihagyása · kiszállás |
| aranyszabály | megosztott (feltöltött, mások által használt) commitot nem rebase-elünk |
| történet átírása | meglévő commitok lecserélése újakra (rebase, amend, reset); feltöltés után force push kellene |
git stash (-m, -u) félreteszi a félkész munkát; list, show,
pop (visszaállít és töröl), apply (megtartja), drop.git rebase main a saját commitjaidat újrajátssza a main végére: egyenes történet, új hash-ek.git add, git rebase --continue; vagy --skip / --abort.-i): pick, reword, squash, fixup, drop; a Desktopban húzással és a Squash menüponttal.A következő fejezetben a történet fontos pontjait jelöljük meg: címkék és verziószámok.