Správa verzí

Lukáš Strmiska (xstrmisk@fi.muni.cz)


Obsah


Proč systém pro řízení verzí

Systém pro řízení verzí spravuje soubory a adresáře nějakého projektu v průběhu času. Systém si udržuje informace o každé změně a umožňuje získat libovolnou starší verzi projektu nebo prozkoumat historii změn. Systém také výrazně usnadňuje týmový vývoj, neboť umožňuje souběžnou práci vývojářů, přičemž hlídá jednotlivé změny, aby nedošlo ke kolizím.

Většina systémů má centrální repository (jako například Subversion a CVS), ke které se uživatelé vzdáleně připojují a to umožňuje vyvíjet projekt kdekoliv. Také existují systémy distribuovanou repository (GNU Arch, BitKeeper a další). Systémy s centrálními repository fungují tak, že repository je na jednom serveru, kam se všichni klienti připojují. Systémy s distribuovanou repository fungují tak, že každý uživatel má u sebe aktuální repository, protože ta je neustále distribuována mezi všemi klienty. Výhodou může být větší rychlost a odolnost proti výpadku.

Repozitory

Repozitory je centrální úložiště, kde je uložena hierarchie souborů projektu včetně historie všech změn. Je uložena na serveru a mohou k ní přistupovat klienti. Tito klienti mohu data do repozitory ukládat a tím je zpřístupnit ostatním klientů, nebo je mohou číst a získat tak data poskytnutá ostatními klienty.

Problém souběžné modifikace stejných souborů:

Systémy s centrální repository -- Subversion nebo CVS?

Subversion je modernější a mladší projekt. Vychází z CVS a umí všechno dobré, co umí staré CVS. Při jeho vývoji se hledělo na požadavky, zkušenosti a stížnosti uživatelů CVS, takže Subversion něco jako lepší alternativa CVS, oproti které

Nejen z těchto důvodů se dál v referátu budu zabývat systémem Subversion.

Subversion

Instalace v systému Debian

# pokud nemáme, nainstalujeme Apache2
apt-get install apache2 # nainstalujeme apache
apt-get install apache2-threaded-dev # kvuli apxs - APache eXtenSion tool

# stáhneme zdrojové kódy subversion do /usr/local/src
tar zxvf subversion-1.3.2.tar.gz # rozbalení
cd subversion-1.3.2

./configure --with-apxs=/usr/bin/apxs2 # konfigurace s apcxs2
make #build
make check #overeni
make install #instalace

# Konfigurace modulu v Apache
cd /etc/apache2/mods-available # pridame moduly do apache
echo "LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so" > dav_svn.load
echo "LoadModule authz_svn_module /usr/lib/apache2/modules/mod_authz_svn.so" > authz_svn.load
cd ../mods-enabled # nastavime, aby se spustily pri startu apache
ln -s ../mods-available/dav.load
ln -s ../mods-available/dav_svn.load

# Přidáme virtuální host s repository
cd /etc/apache2/sites-available
# zde vytvoříme soubor s virtuálním hostem svn.

<VirtualHost *>
ServerName svn.speo.lab.fi.muni.cz
ServerAlias svn.speo

DocumentRoot /var/svn
ServerAdmin root@speo.lab.fi.muni.cz
ErrorLog /var/log/apache2/svn-error.log
CustomLog /var/log/apache2/svn-access.log combined

<Location />
DAV svn
SVNPath /var/svn
SVNIndexXSLT "/svnindex.xsl"

AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/svn.htpasswd
<LimitExcept GET PROPFIND OPTIONS REPORT> # krome cteni je potreba se autentizovat
Require valid-user
</Location>
</VirtualHost>

cd ../sites-enabled
ln -s ../sites-available/svn # a přidáme do povolených sajtů

# Vytvoříme složku pro repository. Složka musí být vlastněná uživatelem, pod kterým běží Apache
mkdir /var/svn
chown www-data:www-data /var/svn
su – www-data
svnadmin create /var/svn # založíme repository

/etc/init.d/apache2 reload # restart apache

#Přidání uživatelů
cd /etc/apache2
htpasswd -c svn.htpasswd your_username

Nyní na http://svn.speo.lab.fi.muni.cz/ je prázdná repository

Základní příkazy

Založení repozitory

Repozitory se zakládá prostřednictvím příkazu
svnadmin create <cesta_k_repozitory>

Import projektu

Do repozitory dáme první verzi projektu
svn import [cesta_k_projektu] <url>

Je dobré dodržet doporučenou adresářovou strukturu projektu, která má tvar
myproject
   branches
   tags
   trunk

V adresáři branches se ukládají jednotlivé vývojové větve, v adresáři tags se ukládají konkrétní verze, které si chceme nějak označit (např. release10 apod.) a v adresáři trunk je pak hlavní vývojová větev.

Pracovní kopie

Pracovní kopie je lokální verze souborů z repozitory. Při práci s projektem používáme a modifikujeme tyto soubory a jejich změny potom hromadně posíláme do repozitory. Pracovní kopii získáme příkazem

svn checkout <url> trunk

kde <url> je adresa repozitory. Pokud chceme získat určitou revizi, použijeme parametr -r <číslo revize>. Pokud již máme pracovní kopii staženou a chceme pouze stáhnout případné změny, použijeme příkaz
svn update

Pokud v pracovní kopii uděláme nějaké změny a budeme se chtít vrátit k původní verzi, použijeme příkaz
svn revert <soubor>

kde <soubor> je jméno souboru, který chceme vrátit do původního stavu. Chceme-li do projektu přidat další soubor, použijeme příkaz
svn add <soubor>

a pokud jej chceme naopak odebrat, použijeme příkaz
svn delete <soubor>

Odeslání změn

Pokud v pracovní kopii provedeme nějaké změny, můžeme je do repozitory odeslat pomocí příkazu
svn commit -m "<popis zmeny>"

Chceme-li před odesláním změn vidět, které soubory jsme změnili, použijeme příkaz
svn status

Chceme-li vidět i všechny provedené změny, použijeme příkaz
svn diff

Řešení konfliktů

Pokud dva vývojáři budou modifikovat stejný soubor naráz, dojde k takzvanému konfliktu. Pokud jsou změny na různém místě, subversion tento konflikt vyřeší automaticky.

Pokud jsou však na stejném místě, je nutné nejdříve provést update, pak konflikt vyřešit ručně a poté teprve provést odeslání změn do repozitory.

Při konflitku subversion vytvoří soubory

Dále v souboru s původním jménem budou označena místa, kde jsou změny konfliktní, a v těchto místech se musí provést ruční úpravy a dát tak soubor do pořádku. Subversion si pamatuje, že je soubor konfliktní a dokud se neřekne, že je problém vyřešen, tak nepovolí změny commitnout.

V zásadě jsou tři možnosti, jak s konfliktním souborem naložit:

  1. Spojit změny ručně přímo na místech, kde byly konflikty označeny.
  2. Překopírovat jeden z nově vytvořených souborů na pracovní soubor. Pokud to tak uděláme se souborem soubor.mine, prosadíme svou změnu, pokud se souborem soubor.rYY, akceptujeme změnu provedenou někým jiným.
  3. Poslední možností je příkaz svn revert soubor, což způsobí návrat k původní verzi z poslední aktualizace (BASE revision). V podstatě je to totéž, jako pracovní soubor překopírovat souborem soubor.rXX z bodu 2.

Jakmile je konflikt vyřešen, je potřeba dát o tom Subversion vědět. To se dělá příkazem svn resolved soubor. Tímto příkazem se smažou všechny pomocné soubory a povolí se commit do repository. Je potřeba si dobře rozmyslet a zkontrolovat, jestli už mohu říct, že konflikt byl vyřešen. Po tomto příkazu je možné commitovat i v případě, že v souboru zůstanou místa označená jako konfliktní.

Jiné přístupy

URL se podle typu přístupu k repozitory tvoří následovně

Stand-alone server

Ke spuštění samostatného interního serveru slouží program svnserve. Má jen pár parametrů, které je rozumné použít.

-d  'svnserve' se spustí v daemon režimu
-r Jeho účelem je zkrátit cestu v URL a je to částečná nebo celá cesta k repository. Pokud bude repository v /home/user/repository a použijeme svnserve -d -r /home/user/, zkrátí se cesta na svn://adresa_stroje/repository/ místo svn://adresa_stroje/home/user/repository
--listen-port  port, na kterém bude server otevřen
--listen-host hostname, na kterém bude server otevřen

Aby bylo možné s repository trochu pracovat, je potřeba definovat nějaká přístupová práva. Nastavení se provádí v souboru /cesta/k_repository/conf/svnserve.conf, kde je potřeba dopsat, resp. odkomentovat, několik řádků.

[general]
anon-access = read
auth-access = write
password-db = soubor_s_uzivateli
realm = moje repository

Soubor s hesly má jednoduchý formát
[users]
user1 = user1_pass
user2 = user2_pass

Další příkazy

svn info - vypíše informace o pracovní kopii
svn log - vypíše historii změn
svn status - vypíše stav jednotlivých souborů v lokální kopii
svn copy - zkopíruje soubor na jiné místo (tzv. lehká kopie)
svn move - přesune soubor na jiné místo

Zálohování repository

Vytvoření zálohy

svnadmin dump /cesta/k_repository/ | gzip -9 > backup.gz

Obnovení ze zálohy

gunzip -c backup.gz | svnadmin load /cesta/k_repository/

Vytváření větví a značek

Pokud chceme vytvořit nějakou vývojovou větev, jednoduše zkopírujeme adresář trunk (příkazem svn copy) jako podadresář adresáře branches. Např:
svn copy <url projektu>/trunk <url projektu>/branches/<nazev vetve>

Pokud chceme nějakou verzi označit, zkopírujeme adresář trunk do adresáře tags. Např.:
svn copy <url projektu>/trunk <url projektu>/tags/ver1.0

Zásady

Distribuované systémy řízení verzí

U distribuovaných systémů pro řízení verzí neexistuje centrální repository, ale ta je distribuovaná mezi všemi vývojaří.

Malý přehled

GNU Arch

Každý vývojář má archiv, ten je definován jménem a e-mailovou adresou. Archívy se dají vkládat do stromu. Archívy archu je možné kromě lokálního přístupu zpřístupnit i prostřednictvím FTP, sftp, WebDAVu nebo prostého HTTP. Chcete-li tedy své archívy vystavit pro čtení, stačí je umístit na své WWW stránky. Slučování verzí probíhá tak, že se promítají změny v jednotlivých větvích, můžeme vybrat jaké změny chceme provést, případně které větve aktualizovat. Obsahuje též star-merge, který umožňuje slučovat jednotlivé vývojové větve.

Instalace na Debianu

apt-get install tla tla-doc

Nápověda k příkazům

tla help #základní nápověda
tla commit -H # kompletní nápověda k commit
tla commit -h # jen seznam voleb

Založení archivu

tla make-archive adresa@nějaká.doména--archive-name /some/directory
tla make-category adresa@nějaká.doména--archive-name/test
tla make-branch adresa@nějaká.doména--archive-name/test--mainline
tla make-version adresa@nějaká.doména--archive-name/test--mainline--0.1

Vytvoření aspoň jedné kategorie, její větve a verze je povinné. Příslušné tři kroky lze také provést jediným příkazem

tla archive-setup adresa@nějaká.doména--archive-name/test--mainline--0.1

Nyní si můžete založit zdrojový strom (nebo použít již existující) a importovat ho do archívu:

mkdir /source/tree
cd /source/tree
tla init-tree adresa@nějaká.doména--archive-name/test--mainline--0.1
tla import

Commit

tla commit

Checkout

tla update

Použité materiály