Hlavní navigace

Výlet do říše verzí: historické verze repository, tagování

Petr Baudiš

Dnes si budeme vyprávět spoustu zajímavých věcí o práci s různými historickými verzemi repository a pronikneme i do tagování.

Připomeňme si na úvod opět, že CVS je uvnitř postaveno na RCS a díky tomu je mu v mnoha ohledech značně podobné. Bude tomu tak i co se týče tagů a větvení vývoje, přesto však existují jisté odlišnosti, nutné k tomu, aby nám to elegantně pracovalo i nad více než jedním souborem (a nutné k tomu, abych si o tom mohl dovolit napsat několik článků). Zvídavějším (či naopak těm pomalejším ;-) čtenářům doporučuji si opět pročíst díl druhý a třetí tohoto seriálu. Ovšem nejdříve si musíme prozradit několik důležitých věcí.

Pracujeme s různými verzemi repository

Často je velmi užitečné se vrátit zpět do minulosti a podívat se na repository v nějakém konkrétním okamžiku (třeba 2. 3. 2004 v 5:06, těsně před tím, než jsme úplně přepsali polovinu projektu a celé to přestalo fungovat). To je samozřejmě možné a dokonce velmi jednoduché. Stačí použít parametr -D, za nímž napíšeme datum, které nás zajímá. Tomuto (lokálnímu) parametru rozumí checkout i update:

pasky@machine:~$ cvs -d/home/cvs/test co -D"2004/03/02 5:06:00" test
pasky@machine:~/test$ cvs update -D"2004/03/02 5:06:00" -dP 

V našem úvodu do CVS jsme se již krátce zmínili o cvs diff, nyní je na čase se mu podívat na zoubek poněkud důkladněji. Pokud mu nedáme žádné upřesňující parametry, porovnává náš současný strom s tím, jak vypadá v repository, tedy nám vypíše změny, které jsme v něm provedli. Ovšem můžeme mu dát parametr -D, pak bude porovnávat náš současný strom se stavem v daném okamžiku. A pokud mu předáme dokonce dva parametry -D, vypíše nám náš milý příkaz rozdíly ve stromu mezi těmito dvěma daty.

Příkazy update a diff standardně pracují s celým pracovním adresářem (včetně podadresářů, pokud jim to nezakážeme). Ovšem můžeme je požádat, aby pracovaly pouze s jedním nebo několika určitými soubory. Pokud tyto příkazy pracují pouze s jedním souborem, má smysl použít místo parametru-D parametr -r, jímž můžeme specifikovat číslo revize onoho souboru, která nás zajímá (tu můžeme získat například z výstupu cvs log). Tedy pokud se chceme v souboru ahoj vrátit k revizi 1.2 nebo bychom si rádi vypsali rozdíly třeba mezi revizí 1.1 a 1.3…

pasky@machine:~/test$ cvs update -r 1.2 ahoj
pasky@machine:~/test$ cvs diff -u -r 1.1 -r 1.3 ahoj 

Parametr -r můžeme předat i příkazu checkout a v příkazech update a diff ho můžeme použít, i když pracujeme s více soubory, v takovém případě však nemá smysl používat (až na výjimky; za domácí úkol si rozmyslete, za jakých okolností by to šlo) nějaká absolutní čísla revizí. Ovšem čtěte dále…

Lepkavé stromečky

Ovšem po takových příkazech se náš strom ocitl v takzvaném „sticky“ stavu. To znamená, že jsme k danému datu (či revizi) „přilepeni“ a žádné další updaty nám nepomohou, jenom se budou držet daného data (revize, nebo v příštím dílu větve). To si můžeme snadno ověřit příkazem status, který nám mimo jiné i prozradí, jestli je verze, kterou právě editujeme, up-to-date (tedy řádně zaktualizovaná proti té v repository), a některé další intimní podrobnosti: cvs status ahoj.

Poté, co jsme se již nabažili historických verzí našeho projektu a chceme se opět vrátit do současnosti, se můžeme samozřejmě zase odlepit, a to pomocí příkazu update s parametrem -A. Oblíbený zápis je cvs update -dPAC: -dP již známe, -A taktéž. -Czpůsobí, že jsou zahozeny jakékoliv případné modifikace, které ve své lokální kopii máme. Ať jsme tedy se svým stromem prováděli sebehorší zvěrstva, takhle vše můžeme snadno a rychle napravit.

Tagy aneb symbolická jména

Po nějaké delší době práce v CVS nás napadne, že by bylo velmi užitečné, abychom si mohli označit určité body v historii projektu a pak se na ně snadno odkazovat. Například bychom mohli říci, že právě teď verze celého projektu dosáhla 3.47, a napříště bychom chtěli mít možnost snadno a rychle například vycheckoutovat z CVS repository strom právě v tomto okamžiku, generovat si diffy mezi jednotlivými verzemi projektu apod.

K tomu nám CVS nabízí právě tagy (česky značky, což je ovšem na můj vkus až příliš neurčitý pojem), tedy jakási symbolická jména, která vyjadřují stav repository v určitém okamžiku. Tedy tag REL3_47může vyjadřovat například stav repository 1. 4. 2003 v 17:34. Nyní můžeme řetězec REL3_47 používat všude, kam bychom jinak psali číslo revize, tedy obvykle u parametru -r různých příkazů. V době RCS jsme také symbolická jména asociovali spíše s čísly revizí (a vnitřně to tak stále funguje), ovšem v CVS může mít v daný okamžik každý soubor úplně jiné číslo revize, proto je zřejmě lepší si to představit takhle.

Jak tagy pojmenovávat? Obecně tag musí začínat písmenem a následovat může libovolná kombinace písmen, číslic, pomlček a podtržítek. Často je zvykem, že se tagy píší velkými písmeny a např. místo teček v číslech verzí se používají podtržítka. Já osobně jsem zvyklý pro jednotlivé verze používat tagy ve stylu REL_číslo_verze, ovšem důležité je zejména, abyste všechny tagy jednoho druhu pojmenovávali stejně a pak nemuseli přemýšlet a hledat v seznamech tagů, jakým způsobem jste zrovna tohle pojmenovali. Ovšem pozor, tagy HEAD a BASE jsou vyhrazeny pro potřeby CVS. HEADodkazuje na poslední verzi souboru v repository, zatímco BASE míří vždy na verzi souboru, kterou jsme naposledy z repository vycheckoutovali.

Nuže, přikročme k dílu:

pasky@machine:~/test$ cvs tag REL_3_47
cvs tag: Tagging .
T ahoj
T zpivanky
pasky@machine:~/test$

Obvykle tagujeme aktuální podobu stromu, se kterým právě pracujeme, ovšem samozřejmě můžeme použít náš starý známý parametr -D a přiřadit tak tag k libovolnému datu.

Co se tedy vlastně stalo? Příkaz tag prošel všechny soubory v repository, zaznamenal si jejich aktuální revizi (případně revizi, kterou měly v zadaném čase) a do každého souboru zapsal, jakému číslu revize odpovídá tag REL3_47.

Seznam všech tagů a odpovídajících revizí můžeme kdykoliv získat příkazem cvs log -h ahoj. Parametr -h způsobí, že bude vypsána pouze hlavička logu (tedy právě seznam tagů a nějaké další nesmysly), nikoliv samotný výčet jednotlivých revizí, který obvykle od tohoto příkazu očekáváme.

Alternativní způsob, jak získat seznam tagů, je cvs status -v ahoj. Parametr -v zde naopak způsobí, že je příkaz status výřečnější než obvykle a zobrazí navíc právě i seznam tagů. Vyberte si, který způsob se vám líbí víc.

Bystřejší čtenáři si možná již uvědomili, že tedy vlastně můžeme používat parametr -r s tagem i při update či diffování více souborů najednou a dokonce i pro checkoutování! Pokud si chceme vycheckoutovat projekt ve verzi 3.47, stačí: cvs -d/home/cvs/test co -r REL3_47 test.


Příště se těšte na větvení a slučování (mergování, chcete-li). Pokud zbude čas, snad se dostaneme i na slibované sledování cizích zdrojáků (a případně vlastních úprav v nich) ve vlastním repository.

Našli jste v článku chybu?