Hlavní navigace

Výlet do říše verzí: hledání v RCS souborech

Petr Baudiš

Dnes se vydáme objevovat svět RCS (a přilehlé okolí) naposledy, povíme si hlavně o kouzelných formulkách, které RCS v souborech umí hledat a občas nám tak zkazit radost. Na rozloučenou se pak ještě krátce zastavíme u SCCS.

$$$ Keywords $$$

Jistě by bylo milé, kdyby RCS uměl nějakým způsobem do souboru ukládat třeba jeho verzi, kdo ho naposledy změnil, seznam všech změn apod. A jistě už jste někdy v nějakém souboru viděli jistý podivný řetězec, něco jako

$Header: /home/pasky/txt/ro­ot/versions3,v 1­.6 2003/03/25 16:11:09 pasky Exp pasky $,

že? Ano, přesně tak — takový řetězec je automaticky vygenerován RCS při checkoutu souboru a obsahuje spoustu zajímavých informací.

RCS vždy (dobrá, téměř vždy) při checkoutu soubor postupně prohledává, dokud nenarazí na řetězec ve formátu $klíčovéslovo$ nebo $klíčovéslovo:co­koliv…$ (takže nevadí, když už je v původním souboru nějaké klíčové slovo v rozvinuté podobě, RCS hodnotu jednoduše automaticky zaktualizuje). V tom případě se zastaví a místo tohoto řetězce dosadí (obvykle) $klíčovéslovo: to, co od něj chceme$. RCS umí klíčových slov několik, my si povíme zejména o těch nejhlavnějších. O těch ostatních se dočtete v manuálové stránce co(1).

Bezesporu nejpoužívanější klíčové slovo je Id. Pokud do souboru napíšeme $Id$, automaticky se nám rozvine na komplikovaně vyhlížející

$Id: versions3,v 1­.6 2003/03/25 16:11:09 pasky Exp pasky $.

Jsou zde shrnuté prakticky všechny důležité informace — jméno souboru, revize, datum a čas registrace této revize (v UTC; pokud chcete nějakou jinou časovou zónu, použijte parametr -z), kdo tuto revizi registroval, status této revize a nakonec i, kdo má pro sebe tuto revizi uzamčenou (pokud vůbec někdo, ovšem). Podobný výstup dává i $Header$, s tím rozdílem, že jméno souboru je uvedeno s plnou cestou. Jednotlivé části výstupu pak můžeme zvlášť získat pomocí klíčových slov RCSfile, Revision, Date, Author, State a

Locker.

Jedno klíčové slovo je poněkud atypické, chová se totiž trošičku zvláštně. Je to klíčové slovo Log, které umožňuje mít přímo uvnitř souboru jeho historii, nebo alespoň její část. Samotné klíčové slovo se totiž rozvine pouze na jméno RCS souboru, ovšem při každé registraci nové změny se na řádky za toto klíčové slovo vygenerují informace o nově vytvořené revizi souboru. Přitom aby to dobře fungovalo i třeba ve zdrojových kódech (a nově vytvořené řádky například byly zakomentované), cokoliv před řetězcem $Log$ se vezme a vloží na začátek každého nově vytvořeného řádku. To znamená, že z

### $Log$

mi vznikne:

### $Log: versions3,v $
### Revision 1.6  2003/03/25 16:11:09  pasky
### Něco o keywordu Log.
###

K čemu všemu jsou vlastně tato klíčová slova dobrá? Kromě jejich samotné informační hodnoty třeba ve zdrojovém kódu můžou být co platná i jinak. Třeba můžete $Revision nechat rozvinout uvnitř řetězce, výsledek přeparsovat a zobrazit jako informaci o verzi skriptu. Existuje však i program ident, který z jakéhokoliv souboru vytáhne všechna klíčová slova, která obsahuje (stačí, aby byla ve správném formátu, nemusí je znát ani samotné RCS). Z jakéhokoliv znamená i z binárního, proto se občas setkáme například v céčkových zdrojácích s variací na téma:

static char *rcsid = "$Id$";

Pak totiž můžeme jednoduše příkazem ident zjistit z .o souboru, z jakého zdrojového souboru (a hlavně z jaké jeho verze) vlastně vznikl.

Existuje mnoho situací, kdy nám však rozvíjení klíčových slov může být na obtíž — například u binárních souborů (pokud by se náhodou uvnitř vyskytlo nějaké klíčové slovo, snaživé RCS by mohlo způsobit katastrofu), při vytváření diffů (tam nás obvykle rozdíly mezi čísly revizí zrovna příliš nezajímají), případně mergování dvou verzí (tam takové rozdíly jednoduše vyvolají konflikt). Proto je zde parametr -k, který může být připojen k příkazu co,rcsdiff nebo rcsmerge a řídí, co se tedy vlastně s těmi klíčovými slovy má dělat. Pokud tento parametr předhodíte příkazu rcs, můžete změnit defaultní hodnotu tohoto parametru pro ostatní příkazy.

Základní hodnoty jsou:

-kkv
Defaultní hodnota, standardní režim expanze klíčových slov.
-kk
Vždy generuj pouze klíčová slova, nikde ať nevidím jejich hodnotu (i když v originálu třeba je). Tento režim je velmi vhodný při generování diffů a mergování. Pozn.: neovlivňuje to však přidávání informací o nových revizích za klíčové slovo Log.
-ko, -kb
Vůbec si klíčových slov nevšímej, jako by neexistovala. -kb navíc říká, aby veškeré operace se soubory byly prováděny v binárním režimu (to nás, šťastné na POSIXových systémech, netrápí, ovšem v DOSoidních systémech to je rozdíl) a navíc rcsmerge s takovými soubory odmítá pracovat.
-kv
Nejbrutálnější metoda — když narazíš na klíčové slovo, zahoď ho a nahraď ho pouze jeho hodnotou. To znamená, že třeba z $Revision$místo $Revision: 1.6 $ vyrobí pouze 1.6. Ne všechny jazyky poskytují dostatečně rozumné metody na parsování klíčových slov, a pokud nás jeho hodnota i tak zajímá, je tento přístup asi nejlepším řešením. Ovšem protože je opravdu poněkud destruktivní, RCS vás nenechá při checkoutu s tímto parametrem soubor zamknout a nedá vám právo na zápis, takže s touto metodou (pochopitelně) nemůžete soubor editovat.

Dědeček na scestí neboli Source Code Control System

Občas se ještě někde setkáte se zkratkou SCCS, která označuje právě tento systém. Na světě se objevil již v roce 1972 (10 let před RCS), rozhodl jsem se však zmínit se o něm až po RCS. Oba systémy sice pracují pouze s jednotlivými soubory a poskytují podobnou množinu funkcí, ovšem RCS je obecně považováno za pokročilejší a bezesporu je rozšířenější. Krom toho rozhraní SCCS je poněkud zvláštní a občas … nejednoduché na pochopení (bezesporu i kvůli ne zcela jednoduše sehnatelné kvalitní dokumentaci).

Dnes již na SCCS narazíte jenom velmi zřídka, obvykle u rozsáhlých closed-source projektů, které jsou již na světě hezkých pár let a nikomu se moc nechce je konvertovat do něčeho rozumnějšího. Existuje několik různých klonů SCCS, které jsou k dispozici s různými komerčními UNIXy, a ne zcela kompletní GNU implementace jménem CSSC (Compatibly Stupid Source Control).

Jak jsem již řekl, SCCS má obecně méně featurek než RCS, o něco těžkopádnější ovládání a hlavně odlišný souborový formát, tzv. weave (narozdíl od delta formátu, který (nebo jeho variace) používá většina ostatních systémů). Přestože je většinou považován za méně efektivní (zvláště z hlediska rychlosti zpracování), má několik velmi zajímavých vlastností, pro které čas od času zažívá v různých podobách renesanci, naposledy v již pověstném BitKeeperu (možná, že v závěru seriálu oba formáty popíšu a porovnám podrobněji). Nejzajímavější vlastnost, kterou SCCS mělo a RCS chybí (a občas je to dosti nepříjemné), je tzv. „annotate“ (také zvané „blame“ ;-). SCCS umožňuje totiž u každého řádku vypsat, ve které revizi a kým byl naposledy změněn (pro historiky: get -m -p), což je vlastnost často nedocenitelná. S RCS ji opět snoubí až CVS (cvs annotate), ovšem zvláště u velkých souborů nijak efektivně (právě kvůli omezením delta formátu).


Prošli jsme tedy konečně lehce bezútěšnou krajinou RCS a SCCS. Budoucnost sice není nijak zvlášť světlá, ovšem odteď to už bude stále jenom lepší ;-). Příště již konečně přijde na řadu úvod do CVS — vysvětlíme si principy jeho funkce a povíme si, jak vytvořit repository a jak pak dostat data dovnitř a zase zpátky ven. Pokud zbyde místo, zkusíme si začít povídat i přes síť.

Našli jste v článku chybu?