Portál AbcLinuxu, 25. dubna 2024 23:42

Jak spravovat software pomocí Subversion - II

20. 2. 2004 | Ondřej Zloský
Články - Jak spravovat software pomocí Subversion - II  

Tentokrát již dojde na ty zajímavé věci. Konfigurace. Práce s repozitářem. Řešení komplikací.

Na straně klienta

V tomto díle se konečně podíváme na to, jak se vlastně Subversion ovládá a jak ji využít ke své práci. Základní pracovní cyklus je stejný jako u CVS; stáhnout aktuální verzi (checkout, update), udělat nějaké změny na souborech (add, delete, copy, move), zjistit, co je na pracovní verzi změněno (status, diff, revert), vypořádat se s konflikty (merge, resolved) a následně změny uložit do repository (commit). Existuje ale ještě mnoho dalších příkazů, a zdaleka ne o všech si tu něco povíme. Všechny jsou samozřejmě popsány v dokumentaci.

Řádkový klient Subversion se jmenuje svn a po normální instalaci leží v /usr/bin/svn. Všechny následující příkazy se tedy zapisují ve tvaru:

svn <příkaz> <parametry>

Ještě než se pustím do popisu příkazů, upozorním na jednu, mně ne úplně sympatickou, věc. Pokud se přistupuje k autentizované repository a klient žádá pro přístup heslo, pak se toto heslo implicitně ukládá do souboru ~/.subversion/auth/svn.simple/nějaký_hash. V tomto souboru je uloženo uživatelské jméno a heslo v textové podobě. Proto je potřeba ohlídat to, kdo má k tomuto souboru přístup, případně zakázat ukládání hesla do tohoto souboru (viz dále). Proč tomu tak je, a jak tento soubor vypadá, se můžete dočíst zde.

Pár základních znalostí

Specifikace čísla verze (revision number)

číslo
pokud je známé číslo verze, je možné ho zadat přímo
{datum}
mezi složené závorky je možné zapsat datum v několika formátech (u vyjádření, kde jsou mezery, jsou vyžadovány uvozovky):
klíčová slova (revision keywords)
slovně reprezentují nejčastějí používané revize
HEAD
číslo poslední revize v repository
BASE
původní číslo revize souboru v pracovní kopii
COMMITTED
číslo poslední revize, ve které byl soubor změněn
PREV
revize o jedno menší, než ve které proběhla změna na souboru, v podstatě jde o COMMITTED-1
rozsah
v některých případech (např. diff nebo log) je vhodné zadat dvě revizní čísla nebo jejich rozsah, obojí se řeší dvojtečkou mezi dvěma čísly zadanými jakoukoli formou, u diff je to chápano jako rozdíl mezi první:druhou revizí, u log jako rozsah od:do

Konfigurační soubor

Nachází se v ~/.subversion/config a lze v něm nastavit pár hodnot, se kterými pak klient pracuje. Pokud mají být tyto parametry užitečné, je třeba je v konfiguračním souboru odkomentovat, včetně příslušné kategorie zapsané v hranatých závorkách. Patří mezi ně:

store-auth-creds = [yes|no]
Z kategorie [auth]. Může nabývat hodnot yes|no a určuje, jestli se mají ukládat autentizační údaje (viz poznámka výše). V konfiguračním souboru je tato položka nazvána chybně 'store-password', takže pozor ať nemáte v konfiguráku 'store-password = no' a nedivili se, že se vám hesla vesele ukládají na disk.
editor-cmd = [vim|pico|joe|..]
Z kategorie [helpers]. Určuje, jaký editor se má spustit při psaní logu. Tento editor se spustí, pokud nezadáte log přímo na řádku za parametr '-m'.
diff-cmd
Z kategorie [helpers]. Říká, jaký program se má spouštět při vytváření rozdílového výpisu. Někomu se může hodit více například zdiff, xmldiff nebo třeba nějaký vlastní. Záleží na tom, jaké soubory se v repository skladují. V případě použití nějakého externího diffu je ale nutné pouštět ho přes nějaký skript, protože Subversion mu předhodí stejné parametry jako klasickému diffu, což celkem dělá neplechu. Je tedy možné řešit to třeba následovně:

diff-cmd=muj_diff_skript.sh

a v muj_diff_skript.sh mít:

#!/bin/bash
/usr/local/bin/muj_diff $6 $7

$6 a $7 jsou právě ty argumenty, které určují cestu k souborům, mezi kterými se má muj_diff provést.

global-ignores
Sekce [miscellany]. Specifikuje masku souborů, které nejsou verzované a nemají se zobrazovat při výpisu u 'svn status'. V normálním případě se neverzované soubory zobrazují se značkou '?'. Je to užitečné, třeba když jsou v pracovní kopii např. zkompilované binárky, dočasné soubory, ..., které se stejně nebudou commitovat.
log-encoding
Sekce [miscellany]. Říká, v jakém kódování budou ukládány "commit logy".

Najde se ještě pár dalších parametrů, které tu už ale nebudu v tuhle chvíli rozebírat.

Konečně začínáme pracovat s repository

To nejhorší máme za sebou, teď už to bude vesměs legrace. V dalším textu budu předpokládat existující repository na adrese svn://svn.example.cz/repository/. Budou zde ukázány jen nejčastěji používané parametry. Kompletní výpis možných parametrů se dělá příkazem

svn help <příkaz>

Vložení souborů do repository

Pokud už máme nějaký rozpracovaný projekt a chceme ho jen vložit pod Subversion, není nutné tyto soubory kopírovat, a poté přidávat v pracovní kopii, ale je možné je rovnou importovat do repository. Import se nepoužívá příliš často, většinou jen při vytvoření nové repository a jejím naplnění již nějakými existujícími soubory.

svn import jméno svn://svn.example.cz/repository

Kde 'jméno' je buď jméno adresáře nebo souboru. Vzhledem k tomu, že se v podstatě jedná o commit zatím neverzovaných souborů přímo do repository, má tedy i import stejné parametry jako commit, tj. hlavně povinný log.

Počáteční checkout

svn checkout svn://svn.example.cz/repository working_copy

Stáhne poslední revize ze zadané adresy do adresáře working_copy. Uvedu některé parametry, které se dají u checkout využít:

-r nebo --revision
Číslo revize, která se má stáhnout.
-N nebo --non-recursive
Implicitně se prochází celá repository rekurzivně. Tento parametr zajistí, že se bude procházet pouze zadaný adresář.
--no-auth-cache
Neukládá se heslo do souboru na disk (viz výše).

Získání aktuální verze

svn update working_copy

Do adresáře s pracovní kopií nahraje aktuální verzi repository, resp. verzi, která se explicitně určí. Důležité parametry jsou stejné jako u checkout. Při stahování aktuální verze (HEAD) se před každým souborem vypisuje atribut, který oznamuje stav souboru oproti naší pracovní kopii. Tyto atributy se budou ukazovat i u svn status. Jsou to:

U soubor
soubor byl aktualizován
A soubor
soubor byl přidán do pracovní kopie
D soubor
soubor byl smazán z pracovní kopie
R soubor
soubor byl přesunut na jiné místo v pracovní kopii
G soubor
soubor byl stažen z repository v aktuální verzi, ale soubor v naší pracovní kopii byl také změněn. Nicméně změny proběhly na odlišných místech v souboru a mohly být spojeny do jednoho souboru(merGed)
C soubor
Změny na souboru jsou v přímém konfliktu s našimi změnami v pracovní kopii. Tento konflikt se musí řešit ručně a patřičné kroky na vypořádání se s tímto problémem budou probrány za chvíli.

Změny na pracovní kopii

Soubory v pracovní kopii je možné editovat, přidávat, mazat, kopírovat nebo přesouvat. Kromě editace, která se provádí naším oblíbeným editorem, existují pro práci se soubory speciální příkazy. Používáním těchto příkazů nepřicházíme o historii souborů, což je jejich hlavní přednost. Bylo by například možné v pracovní kopii soubor někde smazat a posléze ten samý vytvořit o adresář vedle. Ale svn move udělá tu samou práci plus zachová historii. Příkazy jsou velmi intiutivní:

svn add soubor
Přidá soubor do pracovní kopie. Tento soubor musí být fyzicky přítomen. V podstatě se tím říká, že se má tento soubor začít verzovat. Pokud není zadán soubor, ale adresář, přidají se všechny soubory v tomto adresáři
svn delete soubor
smaže soubor z pracovní kopie
svn copy soubor1 soubor2
zkopíruje soubor1 do soubor2 s tím, že soubor2 si sebou nese historii soubor1
svn move soubor1 soubor2
Přesune soubor1 na soubor2. Jde o spojení dvou příkazů a to svn copy soubor1 soubor2 a svn delete soubor1

Kontrola provedených změn

svn status working_copy

Vypíše soubory z pracovní kopie, na kterých se stala nějaká změná oproti verzi, která byla naposledy stažena. Jako u svn update vypíše atribut a jméno souboru. Tyto atributy jsou stejné jako u svn update plus existuje ještě pár dalších:

M soubor
Soubor v pracovní kopii byl změněn.
L soubor
Soubor má na sobě zámek. To se může stát například ve chvíli, kdy právě probíha commit.
? soubor
Soubor nebo adresář se vyskytuje v pracovní kopii, ale nebyl přidán do správy verzí (svn add).
! soubor
Soubor nebo adresář je pod správou verzí, ale v pracovní kopii chybí (nebyl smazán příkazem svn delete, ale třeba příkazem rm.
~ soubor
Soubor je sice verzován, ale v pracovní kopii není v podobě, v jaké by měl být, tj. je veden jako soubor, ale v tuto chvíli je to adresář nebo obráceně.

svn status má kromě těch, které už byly popsány u svn checkout, navíc několik parametrů o kterých se zmíním:

-u nebo --show-updates
svn status pro zjištění změn nemusí kontaktovat repository, protože má historii uloženou v pracovní kopii. V případě, že chceme vědět, jestli nepracujeme se soubory, které už jsou zastaralé, pak k tomu slouží právě tento parametr. Soubory, které jsou v repository novější než v pracovní kopii, jsou označeny hvězdičkou.
-v nebo --verbose
"ukecaný výstup" znamená, že se vypisuje status o všech souborech, tedy nejen těch, se kterými se něco stalo. Navíc vypisuje číslo verze, ve které byl soubor naposledy změněn, a kdo ho změnil.

Takový výpis svn status working_copy --show-updates --verbose pak může vypadat třeba takto:

Status Update? Aktuální
revize
Poslední změna
- revize
Poslední změna
- uživatel
Jméno souboru
M * 50 31 cipisek working_copy/my_prog.c
50 10 cipisek working_copy/my_prog.h
? working_copy/my_prog
* 50 16 rumcajs working_copy/INSTALL
A 0 ? ? working_copy/README
D 50 27 cipisek working_copy/test

Prohlížení změn (diff)

svn diff [soubor] [verze]

Pokud se napíše svn diff přímo v adresáři s pracovní kopií, vypíše se diff na všech změnených souborech. Je možně ale určit pouze jeden soubor a zároveň i mezi jakými verzemi se má diff provést. Výpis je v "unifikovaném diff formátu", to znamená, že před odebranými řádky je znaménko '-', před přidanými '+'. Dále obsahuje vždy jméno souboru a čísla řádků, kde změny proběhly. To umožňuje jednoduše generovat "patche". Příklad:

svn diff soubor1 soubor2 -r 60:80 > r60-r80.patchfile

Vytvoří "patch" na soubory soubor1 a soubor2 mezi verzemi 60 a 80 a uloží jej do souboru r60-r80.patchfile.

Řešení konfliktů

Pokud se při update nebo commit ukáže, že soubor, na kterém jsme prováděli nějaké změny, byl během našich úprav v těch samých místech změněn a "commitnut" někým jiným, vznikne konflikt, který je třeba řešit ručně. V případě, že Subversion označí soubor jako konfliktní, provede pár akcí, které je dobré znát. Jednak vytvoří několik nových souborů, a to:

soubor.mine
Je soubor ve verzi, která byla před update v pracovní kopii.
soubor.rXX
Je soubor v původním stavu, tj. stav po poslední aktualizaci, ale před provedením jakýchkoli změn (BASE revision). rXX označuje číslo revize tohoto souboru
soubor.rYY
Je soubor, který je v současné chvíli v repository (HEAD revision). rYY označuje číslo nové revize.

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:

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í.

Konečně commit

Nejdůležitější a také poslední akcí, kterou člověk při svém pracovním cyklu udělá, je odeslání změn zpátky do repository. Před samotným commitem by tedy měly proběhnout akce jako svn status pro kontrolu toho, co jsme změnili, a svn update pro kontrolu, jestli někdo nepracuje na stejných souborech jako my.

svn commit [soubory]

V pracovním adresáři je možné zadat jen svn commit a odešlou se všechny změněné soubory. Je možné je ale určit jednotlivě. Commit má několik následujících parametrů:

-m nebo --message
V uvozovkách se zde zapisuje zpráva přiřazená k dané verzi. Pokud nebude zadána na řádek, spustí se definovaný textový editor, ve kterém je možné tento log zapsat.
-F nebo --file
Pokud například vytváříme log během práce do externího souboru nebo se první commit nepovedl a log byl uložen do dočasného souboru, je možné říct v jakém souboru je tento log uložen.
--encoding
Říká, v jakém kódování je log napsán.

Závěr

Myslím, že už toho bylo probráno celkem dost a na tomto místě bych tento miniseriálek ukončil. Subversion toho sice skrývá ještě mnohem víc, ale tento základní kurz by měl obsáhnout všechny běžně používané akce, které obyčejný uživatel potřebuje. Pokud by se ukázalo, že je zájem o pokračování v takových už spíše lahůdkách, je klidně možné, že ještě nějaký ten díl vznikne.

Související články

Jak spravovat software pomocí Subversion - I
Apache Ant - jak na složité projekty
Jaderné noviny

Odkazy a zdroje

Subversion - project home
Subversion book
Single-User Subversion
Multiuser Subversion
Apache Software Foundation
Berkeley DB

Další články z této rubriky

LLVM a Clang – více než dobrá náhrada za GCC
Ze 4 s na 0,9 s – programovací jazyk Vala v praxi
Reverzujeme ovladače pro USB HID zařízení
Linux: systémové volání splice()
Programování v jazyce Vala - základní prvky jazyka

Diskuse k tomuto článku

20.2.2004 11:13 Maude Lebowski
Rozbalit Rozbalit vše cvs
Odpovědět | Sbalit | Link | Blokovat | Admin
Nelze se samo ubranit srovnani s CVS, pouziti neni moc odlisne a prijde me, ze na jednuduche soukrome projekty v podstate moc rodilu neni. Takze mam dve otazky. Vyplati se to? Existuje konvertor z cvs? Cestu ze si to nahraju z cvs a ulozim nepovazuju za dobrou protoze se ztraci zmeny, zmatek ve vetvych atd. Vyplati se treba mit stare projekty v cvs a nove radeji zakladat tady? Vyvoj muze byt ale dlouhodoby proces a cvs se treba nebudeme moct vzdat za 10 let...
20.2.2004 13:22 Radek Podgorny
Rozbalit Rozbalit vše cvs
CVS vs. Subversion je vecne tema na flame. Ja k tomu muzu dodat jen svoji zkusenost. Zkousel jsem oboji a zustal u Subversion. Pripada mi mnohem jednodussi k pochopeni...

...a taky se tam mnohem lip prejmenovavaji a presouvaji soubory a adresare, zkuste to v CVS... :-)

Pokud by se tedy nekdo zeptal mne, rekl bych "CVS zahodit, Subversion pouzivat"... (Muj nazor - no flame, please)
20.2.2004 21:33 zlosyn | skóre: 24
Rozbalit Rozbalit vše cvs
Konvertor existuje. Je soucasti subversion a je to skript v pythonu, ktery se jmenuje cvs2svn. Pomoci neho by melo jit prekonvertovat cvs repository na svn.
20.2.2004 19:06 Michal
Rozbalit Rozbalit vše Mazani historie
Odpovědět | Sbalit | Link | Blokovat | Admin
Zajimalo by mne, jestli se daji v subversion nebo CVS mazat starsi release verze.

Rekneme, ze HEAD je release 6000 a ja bych chtel zachovat pouze release 5000 az 6000. Jde to nejak provest? Nebo jak se to resi, kdyz uz je repozitory neunosne velky?
20.2.2004 21:38 zlosyn | skóre: 24
Rozbalit Rozbalit vše Mazani historie
Predpokladam, ze by to melo jit pomoci 'svnadmin dump /path/to/repos -r 5000:6000 > backup' a pak pomoci 'cat backup | svnadmin load /path/to/repos'.
21.2.2004 13:52 Radek Podgorny
Rozbalit Rozbalit vše Mazani historie
...obavam se, ze by to ale rozbilo cislovani. Vsechno by asi zacalo opet od nuly, ne?
24.2.2004 08:38 Petr Slansky | skóre: 30 | blog: slansky
Rozbalit Rozbalit vše Repozitory SVN x CVS?
Odpovědět | Sbalit | Link | Blokovat | Admin
V CVS muze byt v jednom repozitory nekolik projektu. Jak je to v SVN? Zda se mi, ze kazdy projekt musi mit vlastni repozitory. Je to tak??
24.2.2004 09:28 zlosyn | skóre: 24
Rozbalit Rozbalit vše Repozitory SVN x CVS?
Ano je to tak. V CVS jsou to pouze adresare a to, ze muze byt v repository vice projektu plyne z toho, ze je kazdy soubor verzovan zvlast. V SVN je potreba pro kazdy projekt mit vlastni repository.
27.2.2004 01:50 MarSik | skóre: 16 | Brno
Rozbalit Rozbalit vše Repozitory SVN x CVS?
Neni to potreba pokud vam nevadi spolecne cislovani (dokonce samotne subversion sdili repozitar s cimsi) a btw: dat rozdilne projekty do rozdilneho repozitare je podle me vhodne i pri pouziti cvs.
Nothing is foolproof...fools are very clever.
31.7.2006 16:15 tomk
Rozbalit Rozbalit vše Zamykani exclusive
Odpovědět | Sbalit | Link | Blokovat | Admin
Nemuzu najit jak v subversion excl. zamknout soubor pro praci nebo nastavit soubory ktere je treba zamykat np. (binarni soubory nebo skripty SQL). Zamek se pouze zamkne neexcl a jiny user kdyz si toho nevsiimnne tak muze nadelat zmatek.
6.12.2006 15:50 janek
Rozbalit Rozbalit vše Re: Jak spravovat software pomocí Subversion - II
Odpovědět | Sbalit | Link | Blokovat | Admin
Není mi z toho bšeho jasné zda můžu pomocí jediného serveru SVN nasdílet více repozitářů, které si dávám kamkoliv na síť a když se k nim chci připojit zvenčí, server je prostě nabídne a mám-li práva pustí dovnitř... Jde to?

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.