2. gyakorlat: Git¶
Szerkesztés alatt!
Az oldal további része szerkesztés alatt áll, a tartalma minden további értesítés nélkül többször, gyakran, jelentősen megváltozhat!
Verziókövetés¶
A verziókövetés lényegében valamilyen információ - például a forráskód, fájlok, mappák - több változatának menedzselése.
Ez megtehető "manuálisan" is, fájlok, mappák átnevezésével, verziószámozásával, de ilyet manapság nem csinálunk!
Helyette verziókövető rendszereket használunk, amik:
- Nyomon követik, hogy mikor és hogyan változtak a fájljaink, mappáink és ki végezte el a változtatást.
- A mappák, fájlok bármelyik korábbi (rögzített) állapota visszaállítható, illetve lekérhető a legfrissebb verzió.
- Szinkronizálni tudják a mi változatainkat egy másik gépen levő hasonló mappával (átvezetve a változásokat).
- Jelzik, ha ezt nem tudják automatikusan elvégezni.
- Minden verziót egy egyedi azonosítóval (számmal vagy hash-sel) azonosítanak.
- Nyilvántartják a verziók közötti összefüggéseket (amik a legegyszerűbben egy gráffal vizualizálhatók).
Azaz innentől kezdve nincs szükség arra, hogy a fájlok elnevezésével jelöljük meg a különböző verziókat, hiszen szoftveres módon fogjuk tudni kezelni a problémát.
Sokféle verziókövető rendszer létezik, ezek között kisebb-nagyobb különbségek vannak:
- CVS
- SVN
- Git
- Mercurial
- GNU Bazaar
- IBM ClearCase
- Visual SourceSafe
- ...
Mi a talán legismertebbel, és manapság legnépszerűbbel, a Git-tel fogunk megismerkedni.
Verziókövetés fogalmak¶
A félév során Git verziókövető rendszert fogunk használni, így az alábbi fogalmak is elsősorban erre a verziókezelő szoftverre vonatkoznak.
- repository: a forráskódok, history (korábbi események) tárhelye (repó néven is hivatkozunk majd rá)
- remote repository: egy távoli gépen (általában szerveren) tárolt repository, általában staging area és working copy nélkül
- local repository: a saját gépen tárolt repository, amiben dolgozunk, amihez staging area és working copy is tartozik
- clone: remote repository lemásolása a saját gépre (első alkalommal)
- working copy (working directory): aktuális munkakönyvtár egy adott repository-hoz
- staging area: átmeneti terület a local repository és a working directory között, a következő commit-ra jelölt fájlokat tartalmazza
- commit: a fájlok, változások eltárolása a local repository-ban
- push: a local repository változásainak (commit-jainak) feltöltése a remote repository-ra
- fetch: a remote repository változásainak (commit-jainak) letöltése a local repository-ba
- pull: egy fetch, merge és checkout; a remote repository változásainak letöltése a local repository-ba, ha kell (és lehet) akkor az eltérések automatikus feloldása, és a working copy updatelése az aktuális branch-en
- branch: különböző elágazások a fejlesztésben, amelyek később visszatér(het)nek a main-be
- main: a fő fejlesztési irányvonal, egy kitüntetett és általában jobban védett branch
- checkout: a working copy elemeit módosítja a staging area és/vagy local repository-ből, például branch-ek váltása esetén
- HEAD: a working copy alapjául szolgáló verzióra való hivatkozás
- merge: branch-ek egyesítése
- conflict: ha ugyanaz a dokumentum mindkét merge-elendő branch-ben megváltozott (a két branch közös őse óta), és a változtatások nem egyesíthetők automatikusan
Git specifikus fogalmak
Bár minden verziókezelő célja alapvetően ugyanaz, és nagyjából ugyanazokból az elemekből építkeznek, mégis, néhány fenti fogalom más verziókezelő - például SVN - esetén nem értelmezhető vagy mást jelent. Ezért, más verziókezelők használata esetén oda kell figyelni az abban használt fogalmak jelentésére.
Mit verziókövessünk Git-ben?¶
A Git verziókezelő rendszer alapvetően a szöveges állományok, így tipikusan a forráskód fájlok, plain text dokumentációk változáskezelésében hatékony. Ez azt is jelenti, hogy bizonyos fájlokat nem érdemes Git-tel verziókövetni (bizonyos nézőpontból pedig nem csak nem érdemes, de elvi hiba is, hiszen a Git nem tárhelyszolgáltatásként működik). Valamint, a szöveges állományok közül szintén nem érdemes azokat tárolni, amelyek a többi segítségével automatikusan és egyértelműen generálhatók (bár ezen ökölszabály alól is lehetnek kivételek). Így tehát Git-ben NE tároljunk:
- futtatható állományokat (pl. linux programok,
*.exe
) - tömörített mappákat (pl.
*.jar
,*.rar
,*.zip
) - bináris fájlokat és csak ilyeneket tartalmazó mappákat (pl.
bin/
,*.class
,*.png
,*.jpg
) - generált fájlokat és mappákat (pl.
build/
,tmp/
,*.class
,*.tmp
,*.log
)
Repository létrehozása¶
Git repository és GitLab projekt
Ami a Git-ben egy repository, az a GitLab-on egy projekt alapja, egy GitLab projekt egy konkrét Git repository-hoz nyújt kiegészítő támogatást.
Az előző órán szó volt a GitLab-ról, mint a Git "fölé" épülő, annak funkcióit kényelmesebben kezelhetővé tevő és kibővítő szoftverről. Amikor a GitLab-on létrehozunk egy projektet, akkor létrejön egy hozzá tartozó Git repository is. Ez azt jelenti, hogy mindenki legalább két Git repository-hoz hozzáfér a Hallgatói Demonstrációs GitLab Szerveren:
- a saját csoportjának közös
folyamatok
nevű projektjének repójához, és - a saját maga által az adott csoportban
SDP25-hxxxxxx
néven létrehozott projektjének repójához.
Ezen repository-k URL-je https://git-okt.sed.inf.szte.hu/sdp25-szoftverfejlesztesifolymatok/SDP25-IBNa1017L-%/folyamatok.git
, illetve https://git-okt.sed.inf.szte.hu/sdp25-szoftverfejlesztesifolymatok/SDP25-IBNa1017L-%/{'name': 'SDP25-hxxxxxx', 'slug': 'SPD25-hxxxxxx', 'temp': 'hxxxxxx'}.git
, ahol a %
helyére a csoport sorszámát, a hxxxxxx
helyére pedig a saját h
-s azonosítót kell behelyettesíteni.
A továbbiakban ezeket mint remote repository-kat fogjuk használni.
Remote repository és central repository
Vannak központosított és elosztott verziókezelők.
A központosított verziókezelők (mint például az SVN) jellemzője, hogy van egy központi szerver, és az felel a verziók nyilvántartásáért; a klienseken általában csak a working copy és staging area (illetve az adott verziókezelő ezeknek megfelelő elemei) találhatóak meg. Vagyis a teljes repository csak egyetlen helyen van nyilvántartva.
Az elosztott verziókezelők esetében (mint például a Git) a teljes repository minden kliensnél megtalálható. Így tulajdonképpen nem is lenne szükség szerverre, a Git köszöni szépen, local repository-ként a helyi könyvtárban is nagyon jól megvan. Ha viszont többen dolgoznak egyszerre a projekten, mindenki saját gépen, akkor az azt jelentené, hogy több repository van, mindenkinek van egy saját local repository-ja. Az ugyan igaz, hogy remote repository-ként bárki bármelyik másik fejlesztő repóját el tudná érni, de a teljes szinkronizálás (hogy mindenkinél ugyanaz a repository legyen meg) ilyen esetben rémálom lenne. Ezért az elosztott verziókezelők esetén is ki szokás jelölni egy kitüntetett, központi repository-t, amit minden fejlesztő beállít magának remote repository-ként, és mindenki ezzel szinkronizál. Ez a központi repó (általában) egy úgynevezett bare repository, és nem tartozik hozzá staging area és working copy.
A fent említet, GitLab szerveren található repók ilyen, csak remote repository-ként használható bare repository-k.
És hogyan lesz ezekből local repository-nk? Klónozással!
git
kliensek
Sokféle Git kliens létezik (bár a "kliens" elnevezés a Git filozófiája miatt nem biztos, hogy megállja a helyét).
Mi alapvetően a parancssori git
-tel fogunk megismerkedni.
Linux alatt ez a git
csomag telepítése után terminálból használható, Windows alatt pedig például a git bash
-ben lehet a git parancsokat használni.
Repository klónozása¶
Gyakorlatvezetői feladat: README.md
Mielőtt a hallgatók klónozzák a sdp25-szoftverfejlesztesifolymatok/SDP25-IBNa1017L-%/folyamatok.git
repository-t, a README.md
fájlban hozzunk létre egy Csoporttagok:
nevű részt (a felesleges dolgokat pedig törölhetjük).
A hallgatók majd ide fogják listaelemként beírni a saját nevüket.
Ha már létezik egy repository, amit mi remote repository-ként használnánk, és szeretnénk belőle egy vele ekvivalens local repository-t, akkor ezt a repository-t klónozhatjuk a git clone
paranccsal.
Ennek egy vagy két további paramétere van:
- A remote repository elérhetősége (kötelező), ami általában egy URL (
https://user@gitlab.server.url/path/to/project.git
) vagy egy SSH könyvtár URI (user@gitlab.server.url:path/to/project.git
), de lehet lokális könyvtár is. - A könyvtár neve (opcionális), amibe a repository kerül. Ha ezt nem adjuk meg, akkor az URL
project
név része lesz használva.
1 2 |
|
Feladat: klónozd le a gyakorlati csoportod közös és saját repository-ját
Klónozd le a Hallgatói Demonstrációs GitLab Szerverről a SDP25-SzoftverfejlesztesiFolymatok
csoport saját gyakoraltodhoz tartozó SDP25-IBNa1017L-%
alcsoportjából a közös folyamatok
és saját SDP25-hxxxxxx
nevű projekteket.
Projekt és repository nevek
Figyelj arra, hogy a GitLab-on látható csoport és projektnevek (SDP25-SzoftverfejlesztesiFolymatok
, SDP25-IBNa1017L-%
, folyamatok
, SDP25-hxxxxxx
) nem feltétlenül egyeznek meg a projekt elérhetőségében található nevekkel (sdp25-szoftverfejlesztesifolymatok
, SDP25-IBNa1017L-%
, folyamatok.git
, SPD25-hxxxxxx.git
)!
A géptermekben figyelj arra, hogy hol, melyik könyvtárban dolgozol!
A számítógépes géptermekben a gépek helyi meghajtói minden újraindításkor törlődnek. Ha ide dolgozol, akkor a local repository-d abban a pillanatban elveszik, amikor kilépsz a gépről. Ezért érdemes felmountolni a saját home könyvtáradat, és abban dolgozni; legalább addig, amíg nem tudod szinkronizálni a local repository-t a remote repository-val. Ha ezt már meg tudod tenni, és a géptől való távozás előtt meg is teszed, akkor egy újabb klónozással már meglesznek a legutóbbi verzióid; ilyenkor legfeljebb a személyazonosság beállításával kell majd minden klónozás után bajlódnod.
Local repository beállításai¶
A git repository-nkat, illetve az adott gépen lévő összes local repository default beállításait a git config
parancs segítségével tudjuk konfigurálni.
A legfontosabb dolog a személyazonosság beállítása.
Ezt saját tulajdonú gépen alapvetően érdemes globálisan beállítani.
(A géptermekben pedig minden, a home könyvtáradba klónozott repository-hoz egyenként, azaz --global
kapcsoló nélkül.)
1 2 |
|
Egy adott local repository-n belül a --global
kapcsoló elhagyásával a fenti értékeket az adott repóra vonatkozóan felülírhatjuk.
Bármely, az adott gépen és repóban végzett Git tevékenységet a Git a beállított személyazonossághoz fog kapcsolni, függetlenül attól, hogy a GitLab szervert milyen identitással érjük el.
A beállítások listáját, illetve egy-egy settings.id
nevű beállítás konkrét értékét a git config --list
illetve git config settings.id
parancsokkal kérhetjük le (mindkettőnél használható a --global
kapcsoló).
Feladat: Személyazonosság beállítása
Állítsd be a nevedet és az e-mail címedet a Git-ben a git config
parancsok segítségével.
Munka a local repository-ban¶
Egy Git által verziókezelt könyvtárban háromféle "terület" van:
- working copy: Ez a könyvtár aktuális állapota. Az állapotot általában a staging area-hoz, vagy egy konkrét verzióhoz (a HEAD referenciával hivatkozott verzióhoz) képest értelmezzük.
- staging area: A working copy és a local repository közötti ideiglenes verzió. Ide kerülnek azok a (tartalmi és fájlrendszerbeli) változtatások a working copy-ból, amit majd a következő tárolt verzióba belerakunk. Ezt is a HEAD verzióhoz képest értelmezzük.
- local repository: A verziókezelt könyvtár összes tárolt verziója.
A branch kiválasztása¶
Egy projekt során általában több fejlesztés is fut egyszerre, ezek a repository-ban általában külön branch-ként jelennek meg. Minden branch-hez több commit, azaz verzió tartozhat. Ha a fejlesztésnek vége, akkor az adott branch-en elvégzett változtatásokat be lehet merge-elni a main-be (és az adott branch-et törölni lehet, de ezt fejlesztése válogatja).
Új branch a git branch
paranccsal készíthető.
1 |
|
Ilyenkor az aktuális verzióból (a HEAD-ből) kiágaztatunk egy új fejlesztési ágat.
Ez ilyenkor még nem lesz automatikusan a working copy alapja, ennek kiválasztására a git checkout
parancs szolgál.
1 |
|
A git checkout
parancs
A git checkout
jóval többet tud, mint egy branch kiválasztása.
Igazából bármilyen tárolt verziót (egyedi commit-ot) checkout-olhatunk, onnantól ez lesz a working copy "alapja".
Sőt, egyes fájlok állapotát külön-külön is vissza tudjuk vele állítani a tárolt verzióra.
A fenti két parancs, azaz egy új branch létrehozása és beállítása mint a working copy alapja egyben is megoldható.
1 |
|
Feladat: saját branch létrehozása
A folyamatok
repository-ban hozz létre egy saját branch-et, melynek neve a h
-s azonosítód, és állítsd be ezt a branch-et a working copy alapjának!
Következő verzió kialakítása¶
A working copy állapotának ellenőrzésére a
1 2 3 |
|
parancsok használhatók. A working copy változásait a
1 2 |
|
parancsokkal tudjuk a staging area-ba átrakni.
A git add
a megadott fájlok aktuális verzióit adja hozzá (akár verziókezelt volt előtte a fájl (változtatás), akár nem (hozzáadás)), míg a git rm
parancs törli az adott fájlokat az adott verzióból (egyelőre staging area-ból).
Fájlok hozzáadása és törlése
Az talán egyszerűen látható/elképzelhető, hogy ha a working copy-ban létrehozunk egy fájlt, az a megfelelő git add
parancs végrehajtásáig nem kerül bele a következő verzióba, a Git "nem fog emlékezni" rá.
Ha már létező (verziókezelt) fájlt módosítunk, de ezt nem jeleztük a Git felé a megfelelő git add
paranccsal, a Git akkor nem fogja figyelembe venni a változtatásunkat a következő verzióban.
Az már kevésbé nyilvánvaló, hogy ha törlünk egy fájlt a working copy-ból, az a git rm
parancs kiadásáig nem fog törlődni a következő verzióból.
Vagyis hiába törlünk "csak úgy" egy fájlt a Git értesítése nélkül, a Git az ilyen fájlokat (az előző verzióhoz képest) változatlannak fogja tekinteni.
Feladat: fájl módosítása
A csoport közös folyamatok
nevű repository-jában a README.md
fájl Csoporttagok:
pontja alá írd be a nevedet.
- Mit mutat a
git status
parancs?
git status
1 2 3 4 5 6 7 8 9 |
|
- Mit mutat a
git diff
parancs?
git diff
A parancs kimenete valami hasonló lesz, attól függően, hogy pontosan mi is volt a README.md
eredeti tartalma:
1 2 3 4 5 6 7 8 9 |
|
Feladat: változás hozzáadása
A README.md
fájlban történt változtatást add hozzá a staging area-hoz.
- Most mit mutat a
git status
parancs?
git status
1 2 3 4 5 6 |
|
- Mit mutat a
git diff
parancs?
git diff
A parancs kimenete üres lesz.
1 |
|
- Mit mutat a
git diff --staged
parancs?
git diff --staged
A parancs kimenete valami hasonló lesz, attól függően, hogy pontosan mi is volt a README.md
eredeti tartalma.
1 2 3 4 5 6 7 8 9 |
|
Új verzió készítése¶
A staging area-ban tárolt változtatásokból az aktuális branch egy új verzióját, azaz egy commit-ot, a git commit
parancs segítségével tudjuk létrehozni.
1 |
|
A commit message az aktuális verzióban található változtatások rövid leírása.
A parancs kiadása után a változások egy új commit formájában bekerülnek a local repository-ba.
A repository commit-jait a git log
parancs segítségével tudjuk megnézni.
Minden commit-hoz tartozik egy egyedi azonosító, egy úgynevezett commit hash.
Fel van továbbá tüntetve a szerző (ahogy a Git konfigurációjában szerepel, és nem a GitLab user), a dátum, valamint a fentebb említett commit message.
A git log
paraméterezhetősége
A git log
parancsa alapvetően az adott branch korábbi commit-jait mutatja, listában, részletesen.
Viszont sokféleképpen felparaméterezhető, ami egy bonyolultabb, több itt-ott összeérő branch-et tartalmazó fejlesztés esetén jól jöhet.
Pl:
1 |
|
Feladat: commit elkészítése
Készíts egy commit-ot, a commit message legyen a "Saját név hozzáadása a README.md listához.", vagy valami hasonló.
A git log
parancs segítségével nézd meg a repó commit-jait.
- Hány commit volt eddig?
- Kik és mikor készítették ezeket?
- Most mi a working copy státusza?
Van tehát egy új branch-ünk, abban egy új commit, és mindezt eltároltuk a local repository-ban. Már "csak" szinkronizálni kell a remote branch-csel. A következő két gyakorlat erről a "csak"-ról fog szólni.
Házi feladatok¶
Házi feladat: Saját projekt klónozása
Otthon klónozd le a https://hxxxxxx@git-okt.sed.inf.szte.hu/sdp25-szoftverfejlesztesifolymatok/SDP25-IBNa1017L-%/SPD25-hxxxxxx.git
URL-ről (a %
és hxxxxxx
részeket megfelelően kicserélve) a saját projekt repódat!
Konfiguráld fel a Git-et, állítsd be a személyazonosságodat!
(Legalább a saját repódban, de ha a saját gépen globálisan csinálod meg, talán az sem árt.
Illetve, ha mégis ártana valamit, akkor meg valószínűleg nem lesz probléma elvégezned a feladatot. ;) )
Házi feladat: 1. mérföldkő a saját projektben
A CooSpace-en kihirdetésre kerülnek/tek az 1. mérföldkő követelményei. Ezt nézd át, és ha valamit esetleg javítanod kell, azt még a 2025-03-02 határidő előtt tedd meg!
Hogyan javítsd az esetleges hibákat?
Az előző óra utolsó házi feladata talán nyújt egy kis segítséget a projekt nevezéktannal kapcsolatos hibáinak kezeléséhez.