A Git worktree parancs: dolgozz több branchen egyszerre egyetlen mappából

Képzeld el a helyzetet: éppen elmerülve fejlesztesz egy új funkciót a feature/amazing-new-thing branchen. Már vannak nem véglegesített változtatásaid, talán még néhány stage-elt fájlod is. Ekkor jön a kritikus hívás: egy sürgős hotfix kell a productionre, azonnal! Mi a teendő? Hagyományosan az ember stashel, commitol egy ideiglenes commitot, átvált main-re, megcsinálja a javítást, visszavált, unstashel, és reménykedik, hogy nem felejtett el semmit. Ismerős? Ez a gyakori kontextusváltás nemcsak időrabló, de rendkívül frusztráló is lehet, ráadásul könnyen vezethet hibákhoz vagy elfelejtett módosításokhoz.

De mi van, ha azt mondanám, van egy elegánsabb, hatékonyabb módja ennek? Egy olyan Git parancs, ami lehetővé teszi, hogy egyszerre több branchen dolgozz egyetlen Git repository-ból, anélkül, hogy stashelned kellene, vagy feladnád a jelenlegi munkád kontextusát. Üdvözlünk a git worktree világában!

Miért Van Szükségünk a Git Worktree-re? (A Probléma)

A modern szoftverfejlesztés ritkán lineáris. Egy átlagos fejlesztő gyakran szembesül azzal, hogy több feladaton kellene párhuzamosan dolgoznia:

  • Egy új funkció fejlesztése.
  • Egy sürgős hibajavítás elvégzése.
  • Egy kolléga kódjának review-zása.
  • Egy régebbi verzióban felmerülő hiba reprodukálása.
  • Különböző build konfigurációk vagy kísérletezések tesztelése.

A hagyományos Git munkafolyamatban, ha egyetlen klónt használsz, minden ilyen kontextusváltás kompromisszumokkal jár. Ha van befejezetlen munkád (módosított, nem commitolt fájlok), akkor a branch váltás előtt valahogy rendezned kell azt. Erre a leggyakoribb megoldások:

  1. git stash: Elmenti a nem commitolt változtatásaidat, majd „elrejti” őket. Később visszaállíthatod, de könnyen elfelejtheted, vagy a stash lista kaotikussá válhat. Ráadásul a stash-ek gyakran konfliktusba kerülhetnek a későbbi módosításokkal.
  2. Ideiglenes commit: Létrehozol egy „WIP” (Work In Progress) vagy „temp” commitot, amit később visszavonsz vagy összevonsz. Ez szennyezi a commit előzményeket, és szintén könnyen felejtésbe merülhet.
  3. Új klón: Egyszerűen klónozod a repository-t egy másik mappába, és ott dolgozol a másik branchen. Ez azonnal megoldja a problémát, de rendkívül pazarló lemezterület szempontjából, és az objektumok (a repository története) duplikálódnak, ami lassú és ineffektív.

Ezek a módszerek mind hátrányokkal járnak, és megakasztják a fejlesztői munkafolyamat áramlását. Pontosan ezen a ponton lép be a képbe a git worktree.

Mi is Az a Git Worktree? (A Megoldás)

A git worktree parancs egy elegáns megoldást kínál ezekre a kihívásokra. Ahelyett, hogy a teljes repository-t újra klónoznád, a worktree lehetővé teszi, hogy több, egymástól független munkakönyvtárat (working copy) hozz létre ugyanabból a Git repository-ból. Ezek a munkakönyvtárak mind egyazon alapvető Git repository-t osztják meg (azaz a `.git/objects` mappát), de mindegyiknek megvan a saját független HEAD-je, index-e és fájlrendszerbeli másolata a repository tartalmáról.

Gondolj rá úgy, mintha egy fő repository-hoz (ezt nevezhetjük „fő munkakönyvtárnak” vagy „main worktree”-nek) „mellék ágakat” (additional worktrees) csatolnál. Minden ilyen mellék ág egy külön mappában helyezkedik el, és benne egy adott branch van kivéve. A lényeg, hogy nem egy teljesen új Git repository-t hozol létre, hanem egy már meglévőnek egy új nézetét, ahol más branchen dolgozhatsz, anélkül, hogy ez befolyásolná a többi worktree állapotát.

Ez azt jelenti, hogy:

  • Nem kell stashelned vagy ideiglenes commitokat létrehoznod.
  • Nem kell többször klónoznod a repository-t, ezzel spórolva a lemezterületet és az időt.
  • Könnyedén válthatsz a különböző feladatok között egyszerűen a megfelelő mappába navigálva.
  • Minden worktree teljesen független a többiektől a munkafolyamat szempontjából.

A Git Worktree Használata Lépésről Lépésre

Nézzük meg, hogyan tudod a gyakorlatban használni a git worktree parancsot!

1. Új Worktree Létrehozása: git worktree add

Ez a parancs az alapja mindennek. Létrehoz egy új munkakönyvtárat, és kiköti benne a megadott branchen lévő kódot. A parancsot mindig a fő repository-d gyökérkönyvtárából add ki!

Szintaxis: git worktree add <útvonal> [<branch-név>]

Példák:

  1. Új branch és worktree létrehozása egy lépésben:
    Tegyük fel, hogy a fő fejlesztési branchen vagy (pl. develop), és el kell kezdened egy sürgős hotfixet a main-ről.

    # A fő repository gyökérkönyvtárában vagyunk (pl. my-project/)
    cd my-project/
    git worktree add ../my-project-hotfix hotfix/critical-bug
            

    Ez a parancs a my-project mappa mellé (tehát a szülőkönyvtárba) létrehozza a my-project-hotfix mappát. Ebben a mappában automatikusan létrejön a hotfix/critical-bug nevű új branch (a jelenlegi branchről indulva, ami ebben az esetben a main lehet, ha arra váltottunk, mielőtt kiadtuk a parancsot, vagy explicit módon megadhatjuk). A my-project-hotfix mappába belépve már ezen a branchen dolgozhatunk.

    Fontos megjegyezni, hogy ha a branch név nincs megadva, a Git megpróbál egy új branch-et létrehozni, ami megegyezik az útvonal utolsó elemével (pl. ../hotfix esetén hotfix nevű branch-et).

  2. Már létező branch kivétele egy új worktree-be:
    Szeretnéd review-zni egy kollégád feature/user-profile branch-ét, de nem akarod elhagyni a saját munkádat.

    # A fő repository gyökérkönyvtárában vagyunk
    git worktree add ../review-user-profile feature/user-profile
            

    Ezzel a ../review-user-profile mappában a feature/user-profile branch lesz kikötve. Most már be tudsz lépni oda, elvégezheted a review-t, futtathatod a teszteket, és ha szükséges, akár commitolhatsz is a review branch-re, mindezt anélkül, hogy a fő munkakönyvtáradban lévő aktuális munkádat megzavarnád.

  3. Worktree a fő repository alkönyvtáraként:
    Bár gyakori, hogy a worktree-k a fő repository mellé kerülnek, létrehozhatók alkönyvtáraként is.

    # A fő repository gyökérkönyvtárában vagyunk
    mkdir worktrees
    git worktree add worktrees/exp-branch experimental/feature
            

    Ez létrehozza a worktrees/exp-branch mappát a fő repository-n belül.

2. Aktív Worktree-k Listázása: git worktree list

Ez a parancs megmutatja az összes aktív worktree-t, beleértve a fő repository-t is. Ezt bármelyik worktree-ből kiadhatod.

cd my-project/ # Vagy bármelyik worktree-be
git worktree list

Példa kimenet:

/Users/user/dev/my-project          a0b1c2d3 [main]
/Users/user/dev/my-project-hotfix   e4f5g6h7 [hotfix/critical-bug]
/Users/user/dev/review-user-profile i8j9k0l1 [feature/user-profile]

A kimenet minden sorában láthatod a worktree útvonalát, az aktuális HEAD commit hash-ét és az aktuálisan kivett branch nevét (vagy detached HEAD állapotot, ha nincs branchhez kötve).

3. Worktree Eltávolítása: git worktree remove

Amikor végeztél egy feladattal egy adott worktree-ben (pl. a hotfix kész van és merge-elted), eltávolíthatod azt. Fontos, hogy a worktree-nek tisztának kell lennie (nincs nem commitolt változtatás) az eltávolítás előtt, különben a Git hibát dob.

# A fő repository gyökérkönyvtárában vagyunk, vagy bármelyik worktree-ben
git worktree remove /Users/user/dev/my-project-hotfix

Vagy ha a worktree könyvtárában vagy:

cd ../my-project-hotfix
git worktree remove . # Eltávolítja az aktuális worktree-t

Ha vannak nem commitolt változtatások, és biztosan el akarod távolítani, használd a -f (force) opciót:

git worktree remove -f /Users/user/dev/my-project-hotfix

Ez a parancs törli a worktree könyvtárát a fájlrendszerből, és eltávolítja a Git belső nyilvántartásából is.

4. Elárvult Worktree-k Törlése: git worktree prune

Előfordulhat, hogy manuálisan törölsz egy worktree mappát, anélkül, hogy a git worktree remove parancsot használtad volna. Ilyenkor a Git belsőleg még számon tartja az „elárvult” worktree-t. A git worktree prune parancs segít megtisztítani ezeket a bejegyzéseket:

git worktree prune

Ezt a parancsot a fő repository-ból érdemes futtatni.

Gyakori Használati Esetek (Amikor a Worktree Tényleg Ragyog)

Most, hogy tudjuk, hogyan kell használni, nézzük meg azokat a forgatókönyveket, ahol a git worktree valóban felgyorsítja a munkádat:

1. Sürgős Hotfixek

Ez a legklasszikusabb eset. Éppen dolgozol egy funkción, amikor egy kritikus hibát jelentenek a productionön. Ahelyett, hogy stashelnéd a munkádat a fő branch-en, egyszerűen létrehozol egy új worktree-t a main branch-ről, ott elvégzed a javítást, commitolod, deployolod, és merge-eled vissza a main-be. Ezután törlöd a hotfix worktree-t, és minden gond nélkül folytathatod a megszakított munkádat a korábbi worktree-ben.

2. Kód Review és Tesztelés

Egy kolléga beküldött egy pull requestet, és szeretnéd helyileg review-zni, esetleg futtatni a teszteket. Létrehozol egy worktree-t a pull requesthez tartozó branch-ről, review-zod, kommentelsz, majd törlöd a worktree-t. A saját munkád ehhez képest teljesen érintetlen marad.

3. Párhuzamos Funkciófejlesztés

Néha két különböző funkción kell dolgoznod, amelyek nem feltétlenül függenek egymástól, de szeretnéd, ha mindkettő előrehaladna. Hozol létre egy worktree-t az egyik funkciónak, egy másikat a másiknak. Egyszerűen átlépsz a megfelelő mappába, amikor az adott feladaton szeretnél dolgozni. Nincs többé „context-switching overload”.

4. Kísérletezés és Prototípus Készítés

Van egy vad ötleted, amit gyorsan ki szeretnél próbálni anélkül, hogy ez befolyásolná a fő fejlesztési ágat vagy a staging area-dat. Készítesz egy „sandbox” worktree-t, kísérletezel, és ha az ötlet nem működik, egyszerűen törlöd a worktree-t minden nyom nélkül. Ha működik, akkor azt a kódot bemerge-elheted a fő fejlesztésbe.

5. Különböző Build Konfigurációk Tesztelése

Egyes projektek esetében szükség lehet különböző build konfigurációk vagy célkörnyezetek tesztelésére (pl. egy projekt buildelése Windows, Linux, macOS platformra, vagy különböző függőségi verziókkal). Létrehozhatsz worktree-ket minden konfigurációhoz, és mindegyikben futtathatod a saját build folyamatát.

A Motorháztető Alatt: Hogyan Működik?

Ahhoz, hogy jobban megértsük a git worktree működését, érdemes bepillantani a kulisszák mögé. Amikor létrehozol egy worktree-t, a Git nem másolja le a teljes .git mappát. Ehelyett a következő történik:

  • A fő repository-ban, a .git/worktrees mappában létrejön egy alkönyvtár az új worktree nevével. Ez az alkönyvtár tartalmazza az adott worktree-hez specifikus Git fájlokat (pl. HEAD, index, logs/refs, config).
  • Maga az új worktree könyvtára (ahová a kódot kivetted) tartalmazni fog egy speciális .git fájlt (nem mappát!). Ez a fájl egy egyszerű szöveges fájl, ami egyetlen sort tartalmaz: gitdir: /path/to/main/.git/worktrees/<worktree-name>. Ez a bejegyzés mondja meg a Gitnek, hogy hol találja az aktuális worktree-hez tartozó metaadatokat.
  • A megosztott Git objektumok (a repository története, commitok, blobok, tree-k) továbbra is a fő repository .git/objects mappájában tárolódnak. Ezért spórol a worktree lemezterületet a teljes klónozással szemben.

Ez a felépítés biztosítja, hogy minden worktree saját HEAD-del és index-szel rendelkezzen, lehetővé téve a független commitokat és staging area-kat, miközben minden worktree ugyanazokat a commit objektumokat éri el.

Bevált Gyakorlatok és Tippek

  • Tiszta elnevezés: Adj értelmes neveket a worktree mappáknak, amelyek utalnak a benne végzett munkára (pl. my-project-hotfix, my-project-review-pr-123).
  • Rendszeres takarítás: Amikor végeztél egy worktree-ben, távolítsd el a git worktree remove paranccsal, hogy ne maradjanak felesleges mappák és Git bejegyzések. Rendszeresen futtasd a git worktree prune parancsot.
  • Aliasok használata: Ha gyakran használsz worktree-ket, érdemes aliasokat definiálni a Git konfigurációdban a gyakori parancsokhoz. Például:

    git config --global alias.wta 'worktree add'
    git config --global alias.wtl 'worktree list'
    git config --global alias.wtr 'worktree remove'
            
  • A fő repository helye: A fő repository-t érdemes egy „stabil” helyen tartani, ahonnan az összes worktree-t vezérled.

Potenciális Csapdák és Korlátok

Bár a git worktree rendkívül hasznos, van néhány korlátja és buktatója, amiről érdemes tudni:

  • Ugyanaz a branch nem lehet két worktree-ben checkoutolva egyszerre: Ez az egyik legfontosabb szabály. Ha például a main branch már ki van véve a fő munkakönyvtáradban, nem veheted ki egy másik worktree-ben. Ha megpróbálod, a Git hibát dob. Ennek az az oka, hogy a Gitnek egyértelműen tudnia kell, melyik munkafolyamat módosíthatja az adott branch-et.
  • Lemezterület: Bár az objektumok megosztottak, minden worktree tartalmazza a repository fájljainak teljes másolatát, ami persze elfoglal némi helyet a lemezen. Nagy repository-k esetén ez nem elhanyagolható.
  • IDE / Editor támogatás: A legtöbb modern IDE és text editor jól kezeli a worktree-ket, mivel azok egyszerű mappák. Azonban légy óvatos, ha ugyanazt a projektet több worktree-ből nyitod meg egyszerre ugyanabban az IDE-ben, ez néha zavart okozhat a belső indexelésben.
  • Hook-ok: A Git hook-ok (pl. pre-commit, post-merge) általában a fő .git/hooks mappában vannak definiálva, és a worktree-k is használják őket. Ha speciális hook-okra van szükséged egy adott worktree-hez, az egy kicsit bonyolultabbá teheti a kezelést, de megoldható.

Összegzés és Következtetés

A git worktree egy elengedhetetlen eszköz minden tapasztalt fejlesztő számára, aki hatékonyabban szeretne dolgozni a Git-tel. Megszünteti a kontextusváltás fájdalmát, lehetővé teszi a párhuzamos munkavégzést, és segít rendezetten tartani a fejlesztési környezetet. Nincs többé szükség stash-elésre, ideiglenes commitokra vagy felesleges klónokra. Egyszerűen és gyorsan válthatsz a különböző feladatok között, minimalizálva a mentális terhelést és növelve a produktivitást.

Ha még nem használtad, itt az ideje, hogy beépítsd a git worktree-t a napi munkafolyamatodba. Fedezd fel, hogyan teheti hatékonyabbá és élvezetesebbé a fejlesztést, és mondj búcsút a Git-ben rejlő frusztrációknak!

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük