Verziókezelő rendszerek Verziókezelés Verziókezelő rendszerek
Kulcsszavak Verziókezelés Verziókezelő rendszerek Revision Control, Version Control, Source Control, Source Code Management (SCM) Verziókezelő rendszerek Version Control System (VCS) Distributed Revision Control (DRCS)
Verziókezelés Verziókezelés alatt több verzióval rendelkező adatok kezelését értjük. Leggyakrabban a mérnöki tudományokban és a szoftverfejlesztésben használnak verziókezelő rendszereket fejlesztés alatt álló dokumentumok, tervek, forráskódok és egyéb olyan adatok verzióinak kezelésére, amelyeken több ember dolgozik egyidejűleg. Az egyes változtatásokat verziószámokkal vagy verzióbetűkkel követik nyomon.
Példa (Horde repository)
Példa (Horde README revision)
Példa (README Annotation)
Példa (Google Docs)
Felhasználási területek Elsősorban többszemélyes projektek esetében. A legtöbb verziókezelő rendszert szoftverfejlesztési projektekben használták először, de egyes szövegszerkesztők, táblázatkezelők és egyes tartalomkezelő szoftverek is támogatják. A beépített verziókezelés a wiki szoftvereknél is kulcsfontosságú. A wiki rendszerek integrált verziókezelői teszik lehetővé, hogy a felhasználók nyomon követhessék egymás szerkesztéseit, és visszaállíthassanak oldalakat azok korábbi verzióira, ezzel védekezve a vandalizmus és a spam ellen.
Alapjellemzők Definíció: a szoftver megépítéséhez szükséges források és más fájlok tárolása és megosztása Biztonságosan Ellenőrzött hozzáféréssel A fájlok legújabb illetve korábbi változatainak megőrzésével
Alapjellemzők: biztonság Megbízható hardver (pl. RAID) – diszkhibák ellen Rendszeres mentés, archiválás (Disaster recovery) A fejlesztés történetének teljes rögzítése Verziók azonosítása Fejlesztői/kooperációs hibák ellen Új verziók és javítások párhuzamos fejlesztéséhez
Alapjellemzők: ellenőrzött hozzáférés Felhasználó-azonosítás A változtatások névhez köthetők legyenek A vétett hibák névhez köthetők legyenek Jogosultságok bevezetése, védelem Konkurencia-kezelés Fájl szinten (párhuzamos módosítások) Alkalmazás logikai szintjén (konzisztens állapotok, mérföldkövek megkülönböztetése)
Kezelési modellek Központosított modell (hagyományos): minden verziókezelési művelet egy közösen használt szerveren történik Elosztott verziókezelő rendszerek: minden felhasználó gépe egy-egy külön tárolóként jelenik meg. Központosított modell: repositoryban (központi tárolóban) tároljuk az adatokat. Szemben a kliens-szerver modellel, az elosztott verziókezelők decentralizált rendszerek. Itt egy központi tároló helyett minden felhasználó gépe egy-egy külön tárolóként jelenik meg. A szinkronizáció az egyes gépek között küldött patch-ek (módosításcsomagok) által valósul meg.
Példa: Központi verziókezelő
Alapműveletek Lokális munkamásolat készítése (checkout) Lokális másolat frissítése (update) A lokális példány is már változhatott addigra! Változások megtekintése, elemzése (log, diff, status) Változások visszaírása a repositoryba (commit, checkin) Ez az egyetlen írási művelet a repository felé!
Központosított modellek Probléma: ha két, vagy több fejlesztő egyidejűleg próbálja módosítani ugyanazt a fájlt. Az ilyen (centralizált) rendszerek kétféleképpen oldják meg ezt a problémát (concurrency modell): lock-olással és merge-eléssel. Lock modell(zárolás): Előnyök, hátrányok Merge modell (összefésülés) Zárolás A konkurens hozzáférés kezelésének legegyszerűbb módja, ha megtiltjuk a konkurrens hozzáférést, azaz ha egy valaki már elkezd módosítani egy fájlt, akkor azt már más felhasználó nem nyithatja meg írásra. Ha egy felhasználó kivesz (kicsekkel) egy fájlt, akkor a többi felhasználó már csak olvasásra nyithatja meg azt egészen addig, amíg a kicsekkelő felhasználó visszateszi (becsekkeli) a módosított változatot (vagy elveti a módosítást). Ennek a módszernek előnyei és hátrányai is vannak. A nagyobb vagy sok fájlt érintő változtatásoknál célszerű ezt választani, mert bonyolult összefésülési műveleteket lehet megtakarítani vele. Ha azonban egy fájl túl sokáig zárolt állapotban marad, akkor a többi fejlesztő esetleg arra vetemedhet, hogy a verziókezelést megkerülve a fájl lokális másolatát módosítsák, ami nagyobb bonyodalmakhoz vezethet. Összefésülés A legtöbb verziókezelő, például a CVS is, lehetővé teszi, hogy több felhasználó dolgozzon egyidejűleg ugyanazon a fájlon. Ekkor a saját változtatását elsőként becsekkelő felhasználó mindenképpen sikerrel fog járni. A rendszer a többi felhasználónak összefésülési lehetőséget ad, mellyel a különböző módosítások összeolvaszthatóak, így a felhasználók nem írják felül egymás munkáját. Az összefésülés lehet automatikus vagy kézi. Általában az összefésülésre képes verziókezelők is adnak lehetőséget fájlok egyfelhasználós, kizárólagos szerkesztésére reserved edit néven.
Elosztott rendszerek Nincs nagy központi adatbázis, csak munkamásolatok (working copies). A gyakori műveletek gyorsak, mert nem kell központi szerverrel kommunikálni. Minden munkamásolat egy-egy távoli backup, ami természetes védelmet ad az adatvesztés ellen. Szemben a kliens-szerver modellel, az elosztott verziókezelők decentralizált rendszerek. Itt egy központi tároló (angolul repository) helyett minden felhasználó gépe egy-egy külön tárolóként jelenik meg. A szinkronizáció az egyes gépek között küldött patch-ek (módosításcsomagok) által valósul meg. Ez a megközelítés jelentős változásokat okoz: Nincs nagy központi adatbázis, csak munkamásolatok vannak. A gyakori műveletek, mint a becsekkelés, verziótörténet böngészés és a változtatások visszaállítása gyorsak, mert nem kell központi szerverrel kommunikálni. Minden munkamásolat egy-egy backup, ami természetes védelmet ad az adatvesztés ellen. Két fajta elosztott verziókezelő létezik, a nyitott és a zárt. A nyitott rendszereket inkább nyílt forráskódú termékeknél használják, a zártakat inkább a nem nyilvános forráskódú termékeknél.
Központi vs. elosztott Main trunk : közös változat R1, r2, stb. Revision-ök, változatok
Központi vs. Elosztott Mindenkinek van saját lokális repositoryja, amit megoszthat másokkal. Distributed: New Terminology push: send a change to another repository (may require permission) pull: grab a change from a repository There’s not really a “latest version”. If there’s no central location, you don’t immediately know whether to see Sue, Joe or Eve for the latest version. Again, a central location helps clarify what the latest “stable” release is. There aren’t really revision numbers.
Központi vs. Elosztott konklúzió A központi: egyszerű, kiváló backup, undo, szinkronizáló műveletekre. Elosztott: a valós élethez közelebb áll, összefésülés, elágazásra alkalmasabb, nem igényel folyamatos online jelenlétet, csak a változások megosztásánál. Sokkal gyorsabb nagy projekteknél, sok változtatás esetében, cserébe nehezebb menedzselni központilag.
Nyitott rendszer (open system) Minden munkamásolat gyakorlatilag egy ág. (branch) Minden ág egy-egy munkamásolatként implementálódik. Az ágak összefésülés patch-ek küldözgetésével történik. Lehet válogatni az egyes változtatások között, nem kell feltétlenül minden változtatást letölteni. Új tagok bármikor csatlakozhatnak a rendszerhez, nincs szükség szerveroldali regisztrációra. A nyitott, elosztott verziókezelők támogatják különböző ágak létezését, és erősen függenek a fent tárgyalt összefésülés (merge) művelettől.
Példa egy projektre Trunk: a fejlesztés fő vonala (baseline, mainline), jóváhagyott változata Branch: elágazás, párhuzamosan fejlesztett változat Tag: a fájlokhoz adott időpillanatban, adott ponton rendelt címke (label), ami a verziószámot jelöli (beszédesen, vagy számokkal).
Műveletek, fogalmak Import: lokálisan tárolt adathalmaz, amely még nem munkamásolat, felmásolása a tárolóra és verziókontroll alá helyezése. Export: hasonlít a checkout-hoz, de metaadatok nélküli tiszta publikálás. Change, change list: a verziókezelt dokumentum változtatásai Conflict: a változások összefésülésének problémája Import Az import művelettel lehet egy lokálisan tárolt adathalmazt, amely még nem munkamásolat, felmásolni a tárolóra és verziókontroll alá helyezni. Export Az export a checkout-hoz hasonlít azzal a különbséggel, hogy tiszta könyvtárat csinál a verziókezeléshez szükséges metaadatok nélkül. Ezt a műveletet általában közvetlenül a tartalom publikálása előtt szokták használni. Change Egy változtatás (change, diff vagy delta) mindig egy verziókezelt dokumentumon vagy fájlon tett változtatást jelenti. Rendszerfüggő, hogy milyen mértékű módosítások számítanak change-nek. Change list Egy change list vagy change set egy check-in művelet során bevitt változtatások listája, olyan rendszereken, melyek támogatják atomi műveletként több változás egyidejű becsekkelését. Conflict Konfliktusról akkor beszélünk, ha ketten akarnak megváltoztatni egy dokumentumot vagy fájlt és a rendszer nem képes összeépíteni a változásokat. A felhasználónak ekkor fel kell oldania a konfliktust, amit vagy úgy tehet meg, hogy a változtatásokat összekombinálja vagy úgy, hogy kiválasztja az egyik változtatást és csak azt juttatja érvényre.
Merge (összefésülés) szüksége Ha egy felhasználó módosítja a saját munkamásolatát, majd letölt a szerverről egy másik módosított változatot. Ekkor a szerveren lévő változásokat össze kell fésülni a lokális munkapéldány változásaival a kliensen. Ha a fejlesztésben elágazás történt, majd egy hibát kijavítottak valamely ágban, s a javítást alkalmazni kell a másik ágra is. Ha a fejlesztésben elágazás történt, majd az ágakat különböző irányba fejlesztettek tovább, s a különböző fejlesztéseket össze kell vonni egy közös változatba (trunk-ba).
Verziókezelő rendszerek csoportosítási szempontjai Repository modell szerint (központi, elosztott) Támogatott platformok (Linux, Windows,..) Költsége (ingyenes, fizetős, illetve licensze) History modell (changeset, patch, snapshot) Verzió-azonosító (Revision ID: namespace, sequence, pseudorandom) Hálózati protokoll (http, https, ftp,sftp,ssh) History modell: leírja annak a módját, hogy hogyan tárolódnak a változások a repositoryban. Például egy változás jóváhagyásakor a rendszer tárolhat egy-egy példányt a fáról a változás előtti, és utáni időpontban (snapshot), vagy esetleg van egy példány a változás előttről, és egy changeset a változásokról. Revision ID: a repositoryban tárolt fájlok egy-egy verziójának azonosításának módja. A rendszer használhat erre álvéletlen számokat, fájlokat növekvő verziószámokkal (namespace), stb.
Aktív verziókövető rendszerek Bazaar (ingyenes, elosztott) Bitkeeper (utóbb fizetős, elosztott) CVS (ingyenes, központi, egyik legrégebbi) Subversion (SVN) (ingyenes, központi) Visual SourceSafe (Microsoft, shared folder alapú, fizetős)
Subversion Általános, ingyenes CMS eszköz, changeset, snapshot alapú tárolás (csak a változást tárolja) Többféle hálózati konfiguráció Egygépes környezetben - file:// Kliens-szerver környezetben
Subversion Támogatja: Atomi commit Fájl átnevezés Szimbolikus linkek Események pre/post kapcsolása Unicode fájlok támogatása Idegen repositoryk beágyazása Részleges checkout/clone Atomi commit: garantálja, hogy minden változás össze lesz fésülve, vagy egyáltalán nincs változtatás. Átnevezés: megengedi, hogy a fájl neve megváltozzon a verzió megőrzése mellett. Szimbolikus linkek: a rendszer megengedi a linkek verziókontrollját a normál fájlokhoz hasonlóan. Egyesek szolgáltatásnak, mások a biztonság megsértésének tekintik (/etc/passwd linkje pl.) Támogatásuk csak a konkrét választott platformon lehetséges. Események pre/post kapcsolása: egy-egy művelet, mint pl. egy commit előtt, vagy után adott parancsok futtatásának képessége. Részleges checkout/clone: checkout, vagy klón csupán a repository egy kiválasztott könyvtárából.
Subversion telepítése Csomagból Linux (Debian, Ubuntu) : apt-get install subversion Windows CollabNet Tigris.org SlikSVN (32, 64 bit kliens) VisualSVN (szerver és kliens) Forrásból
A Subversion bemutatása egy példán keresztül Két projekt létrehozása: egy induló, üres projekt (MyProject1) és egy létező (MyProject2). Cél: a meglévő projektek verzió kontroll felügyelet alá helyezése, illetve új projektek készítése az eszköz használatával A példa szerint két projectet szeretnénk létrehozni: MyProject1 és MyProject2. A MyProject1 egy éppen most induló project lesz, amihez még nem tartozik egyetlen sor forráskód vagy egyéb fájl sem. A MyProject2 egy már létező projectnek fog készülni. Az eddig elkészült kódok eddig nem voltak verziókezelő rendszer által támogatva, ezt most szeretnénk beállítani.
A struktúrák kialakítása SVN repository kialakítása: cd /devdirs mkdir svnlayout mkdir svnlayout/{trunk,branches,tags} SVN adatbázis, projektkönyvtár létrehozása: mkdir {svnrepos,projects} Mivel szeretjük, ha a dolgaink egy helyen vannak, ezért az SVN repositorykat és minden hozzájuk tartozó fájlt egy helyre fogunk tenni. Tegyük fel, hogy ennek egy külön partíciót tartunk fent, amit a /devdirs könyvtárba csatoltunk fel. Lépjünk be a mappába a cd /devdirs; paranccsal. Készítsünk egy svnlayout nevű mappát, ebben létrehozzuk az SVN repositoryk sablon szerkezetét, ami az alap esetben ajánlott trunk, branches és egy tags mappából áll. A trunk mappa tartalmazza majd a fejlesztői ágat. A branches a dokumentumok, programok egyes ágainak van fenntartva, így pl. itt készíthetünk el egy olyan új funkciót a programunkhoz, ami később beolvasztásra kerülhet. A tags mappában egy-egy pillanatképet szokás tárolni, így ha van egy jól működő változatunk egy programról amit később módosítani szeretnénk, előtte készíthetünk róla egy taget, mintegy extra mentésként. Ezen kívül még két könyvtárra lesz szükségünk, egyik ahol az SVN adatbázisok lesznek tárolva ez lesz az svnrepos könyvtár valamint egy, ahol a projectjeink lesznek, itt fog zajlani a tényleges munkavégzés. A könyvtár neve projects lesz.
Tárolók létrehozása (svnadmin create) mkdir {svnrepos,projects}/{MyProject1,MyProject2} svnadmin create --fs-type fsfs svnrepos/MyProject1 svnadmin create --fs-type fsfs svnrepos/MyProject2; Eljött az idő, hogy elkészítsük projectjeink tárolóját. Ehhez először létrehozzuk a projectek könyvtárát az svnrepos könyvtárban majd az svnadmin paranccsal létrehozzuk magát a tárolót, ahol az adott projecthez tartozó összes információ tárolva lesz. Egyúttal hozzuk létre a projects könyvtárba is a megfelelő könyvtárakat.
Használható protokollok Elérési mód file:/// Elérés közvetlenül a helyi fájlrendszeren keresztül http:// Elérés WebDAV-on keresztül https:// Elérés SSL titkosítással ellátott WebDAV-on keresztül svn:// Elérés az SVN saját protokollján keresztül svn+ssh:// Elérés az SVN saját protokollján, SSH titkosított csatornán keresztül A Subversion több féle elérési módot támogat, így egy repositoryt el lehet érni például közvetlen a fájlrendszerről vagy az SVN saját protokolljával. A megfelelő protokoll kiválasztása helyzetfüggő. Ha csak egymagunk dolgozunk a projecten, akkor elegendő a helyi fájlrendszeren keresztüli elérést használni, ebben az esetben ugyanis nincs szükség további konfigurálásra, így ez a leggyorsabb. Amennyiben többen dolgozunk a fájlokon, szükségünk lesz egy olyan megoldásra, amin keresztül mások is elérhetik a repositoryt. Ekkor lehetőség szerint használjunk titkosított csatornát az adatok biztonsága érdekében.
Struktúra létrehozása cd svnlayout svn import . file:///devdirs/svnrepos/MyProject1 --message 'Struktura letrehozasa‘ svn import . file:///devdirs/svnrepos/MyProject2 --message 'Struktura letrehozasa' Hozzuk létre az svn sablon szerkezetét úgy, hogy az előzőleg az svnlayout könyvtárban elkészített szerkezetet beimportáljuk a frissen megcsinált repositoryba (figyeljünk a pontra, ami az aktuális könyvtárat jelöli)
Tárolók feltöltése és használatba vétele (svn import) cd /path/to/projectdir svn import . file:///devdirs/svnrepos/MyProject2/trunk --message 'Mar kesz fajlok beimportalasa‘ cd /devdirs/projects/MyProject1 svn checkout file:///devdirs/svnrepos/MyProject1 . cd /devdirs/projects/MyProject2 svn checkout file:///devdirs/svnrepos/MyProject2 .; Mivel a MyProject2 egy létező projectünk, ezért a trunk könyvtárába beimportáljuk a már létező fájlokat. $ cd /path/to/projectdir; $ svn import . file:///devdirs/svnrepos/MyProject2/trunk --message 'Mar kesz fajlok beimportalasa'; Visszamegyünk a projects könyvtárba majd az svn checkout paranccsal letöltjük a projectek adatbázisát, hogy utána megkezdhessük velük a munkát. $ cd /devdirs/projects/MyProject1; $ svn checkout file:///devdirs/svnrepos/MyProject1 .; $ cd /devdirs/projects/MyProject2; $ svn checkout file:///devdirs/svnrepos/MyProject2 .; Ezután a projectek trunk könyvtárában elkezdhetjük a munkát.
Revision Svn-ben a fájlok változatait úgy nevezett revision numberrel azonosíthatjuk. Minden revision egyértelműen meghatározza minden fájl állapotát, tartalmát. A revision number minden commit után eggyel növekszik. Ez a szám az egész repositoryra vonatkozik, ellenben a CVS-sel, ami minden fájlt külön-külön számoz. Ez megkönnyíti egy-egy régebbi verzió megtalálását.
Revision elérése svn <cmd> -r <revision number Tartomány megadása (kettősponttal elválasztva): svn <cmd> -r <revison number 1>:<revision number 2 HEAD BASE COMMITED PREV {dátum} Néhány revision állapot speciális elnevezést kapott, így azok anélkül is elérhetőek, hogy tudnánk a pontos számot: HEAD A repositoryn lévő legutolsó verzió BASE A working copy alapjául szolgáló legutolsó változat. Gyakorlatilag az utolsó svn update által letöltött vagy svn commit által feltöltött változatot jelenti. COMMITTED Utolsó commitolt változatod. PREV Az előző változat. Az utolsó commit előtti állapot. Nagyjából egyenlő a COMMITTED - 1 verzióval. {dátum} Egy adott dátumkor érvényes változat
Revision példák svn diff -r BASE:HEAD svn diff --revision PREV:COMMITTED foo.c svn checkout --revision {"2009-02-17 15:30"} svn log --revision {2009-11-20}:{2009-11-29} Milyen különbségek vannak a helyi változatunk és a repositoryban lévő legutolsó verzió között: svn diff -r BASE:HEAD shows the last change committed to foo.c: svn diff --revision PREV:COMMITTED foo.c Adott dátumkor érvényes változat kikérése: svn checkout --revision {"2002-02-17 15:30"}
Alapvető munka ciklus #1 Módosítás előtt a legfrissebb változat kérése: svn update Változtatások elvégzése: svn add svn delete svn copy svn move Az svn-bookban olvashatunk egy ajánlást, mely az SVN-nel való munkavégzés ajánlott formáját írja le. Ezzel a munkaciklussal minimálisra csökkenthetjük annak az esélyét, hogy konfliktusok alakuljanak ki, így kevesebb problémát okozhatunk magunknak és a projecten velünk dolgozóknak. Ebben a szakaszban ezt a ciklust tárgyaljuk. Tehát egy tipikus munka ciklus a következőhöz hasonlóan néz ki: Módosítás előtt mindig frissítsük a helyi változatunk. Így elérhetjük, hogy mindig a legfrissebb változat legyen nálunk. svn update Végezzük el a változtatásainkat
Alapvető munka ciklus #2 Történt változás azóta a repositoryban? svn update Ha szükséges, vonjuk vissza a változtatásaink svn revert Szüntessük meg a konfliktusokat (olvasszuk be mások változtatását) svn resolved Commitoljuk a változtatásainkat svn commit
Working copy létrehozása (svn checkout) svn checkout http://example.org/svn/MyProject1 /home/user/dev/MyProject1 Ha nem most hoztuk létre a repositoryt, hanem pl. éppen csatlakozunk egy projecthez, ami már használja az SVN-t, akkor előbb le kell töltenünk a már meglévő fájlokat. Ezt az svn checkout paranccsal tehetjük meg. Ekkor az example.org-ról letöltődik a MyProjecthez tartozó összes file és könyvtár /home/user/dev/MyProject1 könyvtárba.
File hozzáadása (svn add) svn status ? first.file svn add first.file A first.file svn commit -m 'first.file file hozzaadása'; Transmitting file data . Committed revision 2. Mivel a projectünk egyelőre egyetlen fájlt sem tartalmaz, tulajdonképpen haszontalan. Készítsük hát el a hozzá tartozó első fájlunkat, aminek adjuk a first.file Az svn status paranccsal lekérdezhetjük a változásokat. Ekkor a következő kimenetet fogjuk kapni: ? First. File. Láthatjuk, hogy a first.file előtt egy kérdőjel szerepel. Ez azt jelenti, hogy a fájl még nem áll verziókezelés alatt. Ezért az svn add paranccsal adjuk is hozzá a repositoryhoz. Ilyenkor a fájl még csak az svn helyi adatbázisához lesz hozzáadva, ahhoz, hogy ez a repositoryban és így a munkatársaknál is megjelenjen, commitolnunk kell. -m a --message rövidítése A kimeneteken látható Committed revision 2. sor jelzi, hogy az utolsó commit hányadik változtatás repositoryban.
File törlése (svn del) touch second.file svn add second.file A second.file svn commit -m 'second.file hozzaadasa‘ Adding second.file Transmitting file data .. Committed revision 3. svn del second.file D trunk/second.file svn ci -m 'second.file torlese‘ Deleting trunk/second.file Committed revision 4. Előfordulhat, hogy munka közben egy file feleslegessé válik ezért töröljük azt. A törlés demonstrálására hozzunk létre egy ideiglenes fájlt, adjuk hozzá a repositoryhoz, commitoljuk majd töröljük azt az svn delete paranccsal Commitoláskor a file törlődik a merevlemezről, is viszont hála annak, hogy korábban commitoltuk az svn-ből bármikor visszaállíthatjuk azt, ha mégis szükségünk lenne rá. Ezt majd az svn copy paranccsal tehetjük meg - részletesen később.
File áthelyezése, átnevezése (svn mv) svn mv first.file first-moved.file A first-moved.file D first.file Ha egy olyan file-t szeretnénk áthelyezni vagy átnevezni, amely már verzió kontroll alatt van, mindig használjuk az svn move parancsot, hogy a fájlon végzett változtatásokat könnyen nyomon lehessen kísérni. Ha az áthelyezendő file nem commitolt változásokat tartalmaz, az svn figyelmeztetni fog erre és a commit megszakad. Ezt a --force kapcsolóval felülbírálhatjuk. Az svn move parancs kiadását követően az eredeti file az új néven lesz megtalálható a merevlemezen, commit után a változtatás eltárolódik a repositoryban is.
Helyi változtatások visszavonása (svn revert) svn st M first.file D second.file svn revert tmp.file Reverted 'second.file' svn st M first.file Tegyük fel, hogy változtatásokat végeztünk a repositoryban, azonban commitolás előtt meggondoljuk magunkat. Példának vegyük a fájl törlést. Commit előtt mindig érdemes és ajánlott megtekinteni, hogy mely fájlokat változtattuk meg: Az svn status parancs hatására láthatjuk, hogy a first.file nevű file tartalma módosult valamint a second.file nevű fájlt törlésre jelöltük ki. Ekkor azonban eszünkbe jut, hogy szükségünk lehet még a second.file-ra, ezért szeretnénk visszavonni a rá vonatkozó törlést. Ezt az svn revert paranccsal tehetjük meg. A törlést visszavontuk és ha most commitolunk, akkor csak a first.file módosításai fognak felkerülni a repositoryba.
Szerveren lévő változások letöltése (svn update) svn update U first.file Updated to revision 8. Mivel az SVN repositoryt nem egyedül használjuk, hanem a fájlokat mások is szerkesztik, ezért gyakran megesik, hogy munkatársaink is változtatásokat commitolnak. Ebből adódóan a helyi fájlok régebbiek, mint a szerveren lévők. Ahhoz, hogy a local gépen és a szerveren lévő verziók megegyezzenek, le kell töltenünk a változásokat az svn update paranccsal. Ahhoz, hogy elkerüljük a konfliktusokat (azok az esetek, amikor a szerveren lévő verzió újabb, mint a helyi, viszont a helyi fájlunkon is módosítottunk már, tehát nem összeegyeztethető különbségek is lehetnek), a lehető leggyakrabban töltsük le a változásokat és módosításokat követően (miután meggyőződtünk, hogy az elvégzett változtatások nem okoznak gondot a programokban) commitoljunk.
Branch létrehozása svn cp file:///devdirs/svnrepos/MyProject1/trunk file:///devdirs/svnrepos/MyProject1/branches/branch1 -m 'branch1 letrehozasa' Committed revision 13. cd .. svn up A branches/branch1 A branches/branch1/first.file A branches/branch1/second.file Updated to revision 13. Branchet akkor hozunk létre, ha valami olyasmivel szeretnénk kísérletezni, ami nem feltétlenül illik bele az aktuális fejlesztő ágba (trunk). Ilyen lehet például ha mondjuk valamelyik programkönyvtárat le akarjuk cserélni egy másikra. SVN-ben ilyenkor csupán annyit teszünk, hogy a trunkot átmásoljuk a branches könyvtárba. Ezzel még csak a repositoriban van létrehozva a branch, ahhoz, hogy ez helyben is érvényes legyen, csináljunk egy svn update-et a projectünk gyökérkönyvtárában!
Összeolvasztás (svn merge) svn merge -r 13:HEAD file:///devdirs/svnrepos/MyProject1/branches/branch1 U svn-howto.wiki svn ci -m 'branch1 beolvasztasa a fejlesztoi agba' Sending trunk/svn-howto.wiki Transmitting file data . Committed revision 15. svn log --stop-on-copy Miután a branchben elvégeztük a szükséges módosításokat és úgy gondoljuk, hogy alkalmas arra, hogy a módosítások bekerüljenek a fejlesztői ágba, olvasszuk be azokat, majd commitoljunk is egyet. A parancsokat a project trunk mappájában adjuk ki! Előfordul, hogy viszonylag sokat commitoltunk már és nem emlékszünk arra, hogy melyik revisionben történt a branch létrehozása. Ekkor elkezdhetjük az svn log-ot turkálni, greppelni, azonban van egy egyszerűbb módja is. Az SVN-ben van egy funkció arra, hogy könnyen megtalálhassuk, hogy mikor másoltunk valamit, így megtalálhatjuk, hogy mikor hoztuk létre a branchet.
Összeolvasztás #2 svn log --stop-on-copy r30 | ennevem | 2009-11-19 13:33:34 +0100 (Thu, 19 Nov 2009) | 2 lines branch1 utolso commitja r22 | ennevem | 2009-11-19 10:33:34 +0100 (Thu, 19 Nov 2009) | 2 lines branch1 letrehozasa A log utolsó eleme a branch létrehozását fogja jelölni, merge-kor ezt a számot kell alapul venni, viszont ki kell vonni belőle egyet.
Összeolvasztás #3 svn merge -r 21:30 file:///devdirs/svnrepos/MyProject1/branches/branch1 svn merge -r 13:14 file:///devdirs/svnrepos/MyProject1/trunk cd /devdirs/projects/MyProject1/branches/branch1/ svn merge -r 12:13 file:///devdirs/svnrepos/MyProject1/trunk/file1 file1 Tehát mergeljük a branchet a trunkba: A HEAD a branch legutolsó változatát jelöli. Beolvasztás történhet fordítva is, tehát a trunkban történt változásokat beírhatjuk a branchbe. A parancsokat a branch mappájában adjuk ki Összeolvasztáskor a branchre vonatkozó referencia pontként annak létrehozásának revision numberét használjuk, itt 13! Merge a trunkból egy branchbe
Összeolvasztás #4 cd /devdirs/projects/MyProject1/branches/branch1/ svn merge -c 13 file:///devdirs/svnrepos/MyProject1/trunk/ Adott revision változásainak beolvasztása:
Tag létrehozása svn cp file:///devdirs/svnrepos/MyProject1/trunk file:///devdirs/svnrepos/MyProject1/tags/tag1 -m 'tag1 letrehozasa' A tag létrehozásának módja megegyezik a branch létrehozásával. Ez esetben nem a branches mappába másolunk, hanem a tags mappába.
Visszatérés korábbi verzióhoz svn merge -c -17 file:///devdirs/svnrepos/MyProject1/trunk U svn-howto.wiki svn st M first.file svn ci -m 'undoing change committed 17‘ Sending trunk/first.file Transmitting file data. Committed revision 18. Gyakran megeshet, hogy csak commit után jövünk rá arra, hogy nem jó a változtatás, amit végeztünk. Ekkor ugye szeretnénk visszavonni a commitot, amit svn-ben az svn merge paranccsal tehetünk meg. a példában a trunk mappában történt 17. commitot vonjuk vissza. A -c kapcsoló a --change rövidítése. Az svn merge után egy svn commitra is szükség van, hogy érvényesítsük a változtatásokat.
Visszatérés korábbi verzióhoz #2 svn merge -r 19:16 file:///devdirs/svnrepos/MyProject1/trunk U first.file Másik módszer, ha a --change helyett a revision numbereket adjuk meg. A példában a 19-es revisionről a 16-osra tértünk vissza.
Törölt fájl visszaállítása repositoryból svn copy -r 14 file:///devdirs/svnrepos/MyProject1/trunk/deleted.file ./deleted.file Előfordul, hogy töröltünk egy fájlt, a törlést commitoltuk is, viszont eszünkbe jut, hogy mégis szükségünk lenne rá. Ilyenkor tudnunk kell, hogy melyik volt az a revision, ahol még elérhető volt a fájl, majd onnan visszaállíthatjuk. Commit után újra a helyén lesz a fájl.
Fájlok, könyvtárak figyelmen kívül hagyása svn propset svn:ignore second.file . property 'svn:ignore' set on '.' svn propset svn:ignore '*' tempfiles/ Előfordul, hogy egy-egy projectben vannak olyan fájlok is, amiket nem szeretnénk verziókezelés alá helyezni. Ilyen fájlok lehetnek pl.: ideiglenes fájlok, konfigurációs fájlok stb. Az svn propset paranccsal meghatározhatjuk ezeknek a fájloknak és könyvtáraknak a listáját: Ugyanez egy teljes könyvtárra nézve: Ebben az esetben a tempfiles könyvtárban lévő összes file és könyvtár figyelmen kívül lesz hagyva.
Konfliktusok kezelése svn up C first.file Updated to revision 22. ls -1 first.file first.file.mine first.file.r21 first.file.r22 Vegyünk egy példát arra, hogy hogyan jöhet létre konfliktus: Van két felhasználó, Joe és John. Joe commitolt utoljára (revision 21), amit John szépen le is tölt az svn up paranccsal. Ekkor Joe szerkeszt valamit a fájlon, amit szépen fel is commitol (revision 22), azonban eközben John is szerkesztette a sajátját. Commit előtt természetesen leellenőrzi, hogy a repositoryban lévő verzió megegyezik-e a sajátjával: Itt láthatjuk, hogy a first.file előtt egy C karakter szerepel, ami egyenlő azzal, hogy az svn konfliktust érzékelt. Ebben az esetben minden konfliktusban érintett fájl mellé létrehoz az svn létrehoz további 3 fájlt: filename.mine: ez a fájl az aktuálisan szerkesztett fájlunkkal egyenlő. Nem tartalmaz konfliktus jelölőket. filename.rOLDREV: Ebben a fájlban az utolsó checkoutunk szerinti állapot van, mielőtt bármiféle változtatást végeztünk volna rajta. filename.rNEWREV: Ez az a fájl, amit a Subversion kliens a szerverről letöltött, amikor az svn up parancsot futtattuk. Ez a fájl megegyezik a repository HEAD revisionjével. Az OLDREV a .svn könyvtár, a NEWREV pedig a repoistory HEAD revision numberét jelenti.
Konfliktusok kezelése #2 svn ci -m 'try to commit' svn: Commit failed (details follow): svn: Aborting commit: '/devdirs/projects/MyProject1/trunk/first.file' remains in conflict Lehetőségek: Kézzel összeolvasztjuk a konfliktusban érintett fájlokat Az egyik ideiglenes fájllal felülírjuk a munkafájlunkat Futtatjuk az svn revert <filename> parancsot, amivel az összes változtatásunkat visszavonjuk Ha most megpróbálunk commitolni, a Subversion nem fogja engedni:
Konfliktusok kezelése #3 svn resolved first.file Resolved conflicted state of 'first.file' Ha egy konfliktust megoldottál, ezt tudatnunk kell a Subversionnel is, amire az svn resolved parancsot használhatjuk. Ez törli az ideiglenes fájlokat valamint az svn nem fogja konfliktusban lévőként érzékelni a fájlokat.
Kézi összeolvasztás cat first.file 1. sor 2. sor 3. sor 4. sor <<<<<<< .mine John 5. sor John 6. sor John 7. sor ======= Joe 5. sor Joe 6. sor Joe 7. sor >>>>>>> .r25 Kézi összeolvasztást akkor szoktuk használni, amikor mindkét verzió tartalmaz olyan módosításokat, amikre szükség van. Konfliktus esetén az svn konfliktus jelölőket használ a munkafájlunkban, melyek arra valók, hogy könnyen azonosítani tudjuk a különbségeket
Kézi összeolvasztás #2 svn resolved first.file Resolved conflicted state of 'first.file‘ svn ci -m 'A sajat (John) modositasaink beolvasztasa Joe sorai ele' Sending first.file Transmitting file data . Committed revision 26. Látható, hogy a kérdéses rész két szakaszra van osztva: az egyik a saját módosításainkat tartalmazza, a másik a HEAD-ben lévőket. Ha szeretnénk a saját és a HEAD változtatásait is megtartani, egyszerűen töröljük ki a jelölőket, futtassuk le az svn resolved parancsot, majd commitoljunk.
Saját verziónk kikényszerítése svn up C first.file Updated to revision 30. ls first.file* first.file first.file.mine first.file.r29 first.file.r30 cp first.file.r30 first.file svn resolved first.file Resolved conflicted state of 'first.file' Ha úgy ítéljük meg, hogy a saját verziónk való inkább a repositoryba, akkor csupán elég felülírni a munkafájlt a módosításainkat tartalmazó ideiglenes fájllal:
Szerveren lévő verzió elfogadása svn revert <filename> Ha úgy gondoljuk, hogy a szerveren lévő verziónak van nagyobb létjogosultsága, akkor csupán futtassuk le az svn revert <filename> parancsot, ezzel visszavonva saját módosításainkat.
Változások visszakövetése (svn log) #1 svn log r34 | ajnasz | 2009-08-16 00:43:21 +0200 (cs, 16 aug 2009) | 1 line konyvtarstruktura kiegeszitesek r33 | ajnasz | 2009-08-12 18:21:12 +0200 (v, 12 aug 2009) | 1 line typo, formazasok Nem véletlenül ajánlott a message mező kitöltése, sokszor előfordul, hogy nem emlékszünk pontosan, hogy mely módosítást mikor végeztünk, viszont vissza szeretnénk állni az akkori állapotra. Ekkor jön segítségünkre a gondosan kitöltött message mező. Természetesen megadhatunk revision numbereket is, hogy pl csak a 10-től 20-ig történt változtatásokat írja ki.
Változások visszakövetése #2 svn log -r 10:20 svn log -r 20:10 svn log -r 23 svn log -r HEAD Természetesen megadhatunk revision numbereket is, hogy pl csak a 10-től 20-ig történt változtatásokat írja ki. $ svn log -r 10:20 vagy ha fordított sorrendben akarjuk látni az eredményt: $ svn log -r 20:10 Ha csak egy commit logját szeretnénk látni, akkor csak egy számot adjunk meg: $ svn log -r 23 Ha az egyik szám helyett a HEAD kulcsszót adjuk meg, akkor azt a legutólsó commit revision numberének fogja venni. Így megtudhatjuk, hogy mik voltak a módosítások az utolsó commitkor: $ svn log -r HEAD
Változások visszakövetése #3 svn log trunk/svn-howto.wiki svn log http://example.com/svn/file.c -r HEAD Ha paraméterként egy fájl nevét adjuk meg, akkor csak a fájlt érintő változások lesznek kiírva. $ svn log trunk/svn-howto.wiki Ha szeretnénk megtudni, hogy mi változott egy távoli repositoryban, viszont nincs róla helyi másolatunk, mert nem szeretnénk azt letölteni, akkor elegendő megadni a tároló url-jét. $svn log http://example.com/svn/file.c -r HEAD
Módosítások soronkénti áttekintése (svn diff) svn diff first.file Index: first.file --- first.file (revision 43) +++ first.file (working copy) @@ -511,7 +511,7 @@ Lorem ipsum dolor - modositas + Módosítás Lipsum Lorem ipsum Commitolás előtt jó tudni, hogy miket módosítottunk. Ennek megállapítására az svn az svn diff parancsa áll rendelkezésünkre
Módosítások soronkénti áttekintése #2 svn diff -r 40:42 first.file svn di http://example.com/svn/trunk@10 http://example.com/svn/trunk@12 Ha paraméter nélkül hívjuk meg az svn diff parancsot, akkor minden fájl módosítását kiírja vagy megtehetjük, hogy több fájlt is sorolunk fel. Megadhatjuk, hogy bizonyos revisionöket hasonlítson össze $ svn diff -r 40:42 first.file Repositoryt használva is elvégezhetjük az összehasonlítást, ekkor egy @ jellel jelölhetjük, hogy mely verziókra vagyunk kíváncsiak: $ svn di http://example.com/svn/trunk@10 http://example.com/svn/trunk@12
Patch készítése svn di > patch.file Az svn diffel patchet is generálhatunk, csupán a kimenetet kell egy fájlba irányítani.
Working copy helyének megváltoztatása (svn switch) svn switch --relocate http://example.com/regihely http://example.com/ujhely . Néha előfordul, hogy valamilyen okból új elérési úton érhető el a repository, erről tudatni kell a helyi változatunk is:
Felhasználókezelés [general] anon-access = read auth-access = write password-db = jelszo_allomany [USERS] felhasznalo = jelszo Ha azt szeretnénk, hogy a repositoryhoz többen is hozzáférjenek, érdemes beállítani a tárolóhoz való hozzáférést. Ha megnézzük a repository conf alkönyvtárában található svnserve.conf állományt, megtalálhatjuk a következő bejegyzést: A Subversion kétféle felhasználó között tesz különbséget, az anon-access (nem kell felhasználónév és jelszó), illetve auth-access (felhasználónév és jelszó kötelező), illetve megadható jogosultságok lehetnek write (írás és olvasás), read (csak olvasás a tárolóból), illetve none (semmilyen művelet nem engedélyezett). A fenti példában az azonosított felhasználók letölthetik és a változtatásaikat közzétehetik a repositoryban, a felhasználónévvel nem rendelkező felhasználók pedig csak olvshatják annak tartalmát. A hozzáféréshez szükséges felhasználóneveket és jelszavakat a következő módon adhatjuk meg. Módosítsuk az svnserve.conf állomány password-db bejegyzését a következőképpen: Ezzel jeleztük, hogy a felhasználókat tartalmazó állományunkat jelszo_allomany -nak hívják, és az svnserve.conf fájllal egy könyvtárban található, természetesen más fájlnév és elérési út is megadható. Az állomány felépítése a következő: Látható, hogy az [USERS] bejegyzés alatt a felhasználókat és a hozzá tartozó jelszavakat kell megadni, egymástól egyenlőségjellel elválasztva. A példában egy felhasznalo nevű felhasználót hoztunk létre, amelynek a jelszava jelszo lesz.
Parancsokról röviden svn status svn update svn commit svn add svn delete svn revert svn diff A helyi és a repositoryban lévő változatok közötti különbségeket az svn status paranccsal kérdezhetjük le. Ha a szerveren lévő verzió újabb, mint a nálunk lévő, az svn update paranccsal letölthetjük azt. Az általunk elvégzett módosításokat az svn commit tölthetjük fel a szerverre. Commitkor erősen ajánlott a message mező kitöltése, ezzel jelezhetjük magunknak és a projecten dolgozó munkatársainknak, hogy milyen változtatásokat eszközöltünk. Új fájlokat az svn add paranccsal adhatunk a projecthez, fájlokat törölni az svn delete, régebbi verziót visszaállítani az svn revert paranccsal lehet. További gyakran használt parancsok: svn diff, svn update, svn help, stb.
Rövidítések svn commit = svn ci svn checkout = svn co svn status = svn st svn update = svn up svn diff = svn di svn delete = svn del vagy svn rm svn move = svn mv svn copy = svn cp svn list = svn ls svn switch = svn sw