Git Workflow

Egy normál fejlesztési flow az alábbi módon néz ki:
- A fejlesztő elkezd dolgozni egy ticketen.
- A fejlesztő nyit egy
featurebranchet a tickethez adevelopbranchből ágazva. - A fejlesztő rendszeresen commitolja és pusholja a módosításokat a
featurebranchre. - A fejlesztő nyit egy merge requestet a
featurebranch-hez targetként adevelopbranchet megadva éswating for reviewstátuszba teszi a JIRA ticketet. - A reviewer átnézi a merge requesthez tartozó kódot, és megjegyzéseket ír a kódhoz a merge requesten belül.
- A fejlesztő javítja a kódot a megjegyzések alapján és 1 db commit formájában pusholja a javításokat a
featurebranchre. - A reviewer átnézi merge requesthez tartozó review fix commitot és ha mindent rendben talál mergeli a
featurebranchet adevelopbranchbe.
1. Branchelés
Ahhoz, hogy egy ticketen el tudjunk kezdeni dolgozni nyitnunk kell egy branchet. A tickethez tartozó kódmodosítások ezen a branchen kell, hogy elkészüljenek, majd merge request formájában jutnak el a kívánt cél branch-re.
1.1 Branch nyitása
1.1.1 Honnan kell leágaznia az új branchnek?
Attól függően, hogy a fejlesztésünket melyik verzióba szánjunk, az alapján kell eldöntenünk hogy melyik branchből kell leágaznia a branchünknek.
Például:
- Amennyiben a fejlesztésünket az éppen aktívan fejlesztés alatt álló verzióba szánjuk, akkor a
developbranchről kell ágaznunk. - Amennyiben a fejlesztésünket egy adott hotfix verzióba szánjuk akkor a megfelelő
hotfixbranchről kell ágaznunk. Pl. ha az 1.0.1-es hotfix verzióba kell javítást csinálnunk, akkor ahotfix/1.0.1branchről kell ágaznunk. - Amennyiben a fejlesztésünket egy adott release verzióba szánjuk akkor a megfelelő
releasebranchről kell ágaznunk. Pl. ha az 2.0.0-es hotfix verzióba kell javítást csinálnunk, akkor arelease/2.0.0branchről kell ágaznunk.
A hotfix és release branchek létrehozása
A projekten használt branchekről és azok szerepéről itt olvashatsz részletesebben.
Mindazonáltal a hotfix és normál release-ek brancheléséhez és a verziók tageléséhez a GitFlow-t vesszük alapul, amiről részletesebb itt olvashattok.
1.1.2 Új branch létrehozása GitLab-on
- A projekt GitLab repositoryjában bal oldalt válasszuk ki a Repository -> Branches menüpontot.
- Nyomjuk meg a jobb fölső sarokban található New branch gombot.
- A
Branch namemezőbe adjuk meg a branch nevét. A branchek nevénél is kövessük azt a konvenciót hogy a JIRA ticket id-t tartalmaznia kell a névnek. A pontos konvenciót lásd itt. - A
Create frommezőnél válasszuk ki a forrás branchet ahonnan a saját branchünket szeretnénk ágaztatni. - Nyomjuk meg a Create branch gombot.
1.2 Branch törlése
Előfordulhat, hogy egy fejlesztésre nincs szükség vagy kiderül, hogy egy másik ticket keretein belül már javítva lett. Ilyenkor szükség lehet arra, hogy töröljük a már létrehozott branchünket.
- A projekt GitLab repositoryjában bal oldalt válasszuk ki a Repository -> Branches menüpontot.
- Keressük meg a törölni kívánt branchet a listában.
- Kattintsunk a „kuka“ ikonra. A felugró ablakban ellenőrizzük, hogy valóban azt a branchet fogjuk-e törölni amit szeretnénk.
- Ha meggyőződtünk róla, hogy jó branchet fogunk törölni nyomjunk a Yes, delete branch gombra.
2. Commitok
Fontos
Alapelv, hogy commitoljunk és pusholjunk gyakran, de minden esetben commitoljunk legalább a nap végén és azt pusholjuk is fel a remote branch-re.
A commitokra vonatkozó részletes konvenciók megtalálhatóak itt.
3. Merge request
A merge request létrehozásának időpontja az adott fejlesztő egyéni preferenciájától függ. A lényeg, hogy egy fejlesztés
csak akkor kerülhet waiting for review státuszba, ha létezik hozzá merge request amin a CI pipeline sikeresen lefutott.
A merge request létrehozásának, review folyamatának és mergelésének lépései illetve konvenciói megtalálhatóak itt.
4. Continous Integration
A projekten futó CI pipeline automatikusan elindul, ha a védett branchekre vagy egy merge requestbe új commit kerül.
A CI feladata, hogy automatikus (ellenőrző) műveleteket végezzen a projekten. Ezek a műveletek a következők:
- A projekt buildelése.
- Checkstyle validációk futtatása.
- Automata tesztek futtatása.
Ha a fentiek közül bármelyik eredménye sikertelen, akkor a CI pipeline elbukik.
Fontos
Csak akkor kerülhet egy merge request wating for review státuszba, ha a CI pipeline az utolsó commitra sikeresen lefutott.
5. Review
A sikeres CI lefutás mellett a második fontos ellenőrző lépés a kód review. A reviewt a projekten dolgozó tapasztaltabb kollégák végzik.
Példa review folyamat
- A fejlesztő
waiting for review-ra teszi a ticketet. - A reviewer megjegyzéseket ír és
selected for developmentstátuszba teszi a ticketet. - A fejlesztő javítja a megjegyzésekben kapott problémákat és újra
waiting for review-ra teszi a ticketet. - A reviewer ha mindent rendben talál, akkor a következő státuszba billenti a ticketet.
Mire figyel a reviewer?
Az általános kódellenőrzésen kívül a reviewerek minden esetben ellenőrzik az alábbiakat:
- Konvencióknak megfelelően van-e elnevezve a merge request.
- Konvencióknak megfelelően vannak-e elnevezve a commit messagek.
- Megfelelőek-e a fejlesztéskor írt SQL scriptek. (Le tudnak-e futni, van-e migráció stb.)
- Az új adatbázis objektumokhoz lettek-e definiálva adatbázis kommentek.
- Az elkészült frontend fejlesztésekhez lett-e a tickethez feltöltve a fejlesztést bemutató screenshot és/vagy videó.
- Elkészültek-e az automata tesztek.
Hasznos, ha a fenti listán a fejlesztő már a fejlesztés végeztével, a review folyamat előtt végigmegy, így a saját és a reviewer munkáját is megkönnyíti.
Interaktív review folyamat
A review nem csak arról szól, hogy a reviewer formailag, illetve üzletileg ellenőrizze a fejlesztést. Az is célja, hogy a reviewt végző kollégák átfogóbb képet kapjanak arról, hogy milyen fejlesztések készültek el.
Ebből következően sok esetben a review megjegyzés lehet egy kérdés is a reviewertől, ami nem feltétlen kódmódosítást, pusztán magyarázatot igényel a fejlesztőtől.
Épp ezért fontos, hogy a review folyamat során kommunikáljunk a reviewerrel. Ez a kommunikáció történhet review kommenteken keresztül vagy szóban, azonban mindenképp írjuk oda a merge requesthez is, hogy mi lett a konklúzió.
Fontos, hogy még a legtriviálisabb review kommentek esetén is jelezzük, hogy elvégeztük a szükséges kódjavítást.
Például a review kommenthez válaszul írjuk oda, hogy fixed. Így a reviewer számára is egyértelmű lesz, hogy a fejlesztő észlelte és foglalkozott a megjegyzéssel.
Fontos, hogy a review kommentek resolválása a code reviewer feladata, nem pedig a fejlesztőé.
6. Rebase
Amikor szeretnénk a legfrissebb kódot áthozni a célbranchről a fejlesztés alatt álló branchünkre akkor előfordulhat, hogy conflictok keletkeznek amiket fel kell oldanunk.
A conflictok feloldására rebase-t használunk.
A rebase lépései
Mivel a fejlesztés alatt álló branchünkön több commit is lehet ezért ahhoz, hogy ne kelljen commitonként feloldani a conflictokat ajánlott squasholni. Az alább bemutatott folyamat a squasholást is tartalmazza.
Squash folyamat
Az alábbi parancsokat parancssorból kell kiadni.
- Squasholjuk a commitokat a branchünkön az alábbi paranccsal:
git rebase -i HEAD~{commitokSzáma}. A{commitokSzáma}helyére azt a számot írjuk amennyi commitunk van a branchen, ez látszik az MR-ből is. Pl.:git rebase -i HEAD~8. - Vim-ben megjelenik egy lista a commitjainkkal. Itt kell megadni mely commitokat akarjuk squasholni.
- Az
ibetű megnyomásával váltsunk INSERT módba. - Az első commitot hagyjuk
pick-en a többihezsbetüt írjunk apickhelyett (azsasquashrövidítése). - Az
ESCgomb megnyomásával lépjünk ki az INSERT módból majd írjuk be a:wq(mentés és kilépés) utasítást.
- Az
- Ezután egy új Vim képernyőn kell megadni a squasholt commit message-et.
- Az
ibetű megnyomásával váltsunk INSERT módba. - Adjuk meg a commit messaget.
- Az
ESCgomb megnyomásával lépjünk ki az INSERT módból majd írjuk be a:wq(mentés és kilépés) utasítást.
- Az
- A squash sikeresen megtörtént. A
git log -3paranccsal tudjuk ellenőrizni, hogy valóban az elvárt 1 db commit szerepel-e már a logban.
Rebase folyamat
Az alábbi parancsokat parancssorból kell kiadni.
- A remote repositoryk frissítéséhez adjuk ki a
git fetchparancsot. - A
git statusparanccsal ellenőrizzük, hogy a saját branchunkön állunk-e. - Majd adjuk ki a
git rebase origin/{targetBranchName}parancsot. Pl.: Ha a célbranchünk adevelopakkor ez lesz a parancs:git rebase origin/develop. - Amennyiben conflictot jelez a Git nyissuk meg a mergetool-unkat:
- Lehet ez az IntelliJ beépített merge toolja.
- Lehet ez a
.gitconfig-ban konfigurált tool is (ebben az esetben parancssorban ki kell adnigit mergetoolparancsot).
- Oldjuk fel az összes conflictot majd adjuk ki a
git rebase --continueparancsot. - Pusholjuk változtatásokat a remote branchre a
git push --force-with-leaseparanccsal.
Fontos
Figyeljük meg, hogy force-with-lease-t használunk force push helyett. Ennek oka, hogy a force push felülirja
a lokál állapottal bármi is van a remote-on. Ez gondot okozhat ha többen dolgozunk egy branchen és időközben valaki
pusholt a remote branchre, ugyanis a force push miatt az ő módosításai elveszének.
Ezt oldja meg a with-lease ugyanis a Git ilyenkor ellenőrzi, hogy ne legyen eltérés a remote branchhez képest,
ezáltal ha valaki pusholt időközben ahhoz az állapothoz képest amihez rebaseltünk, akkor nem fogja engedni pusholni
a változtatásainkat addig, amíg újra nem rebaselünk.