Linux v příkazech - správci verzí

Nástrojů pro správu projektů je celá řada. Podrobněji rozebereme dva z nich - RCS a CVS.

9.8.2005 06:00 | Jiří Václavík | přečteno 34084×

Ať už jste básník nebo programátor, určitě se vám už někdy stalo, že jste se při úpravě složitějšího souboru potřebovali vrátit k jeho starší verzi. Pokud jste nepoužili nějaký SCM (Source Code Management; program, který si pamatuje změny projektu - tedy to, o čem je celý článek), nezbývalo než opět pracně přepisovat verzi stávající. Z tohoto důvodu je nutné myslet na sledování změn už od samého začátku projektu.

Pojďme už ale k jednotlivým SCM.

RCS (Revision Control System)

RCS je poměrně jednoduchý a efektivní program. Je poněkud starší a proto má oproti CVS, SVN nebo GNU Archu méně funkcí Přesto si i dnes (i když jen zřídka) najde uplatnění. Používá se v případech jednoduchých projektů, kdy je sledován jen jediný soubor.

RCS lze získat z www.cs.purdue.edu/homes/trinkle/RCS/. Instaluje se klasicky pomocí ./configure; make; make install. Pravděpodobně ale už bude součástí vaší distribuce.

Pro předvedení vlastností RCS si vytvoříme konfigurační soubor .vars, který bude vykonán vždy po přihlášení. Obsahovat tak bude uživatelské nastavení systémových proměnných.

$ touch .vars

Dále vytvoříme adresář ./RCS. V něm se budou ukládat pomocné soubory. Adresář ./RCS není povinný - pokud neexistuje, budou se ukládat do aktuálního adresáře ./. - nicméně jeho vytvoření kvůli přehlednosti doporučuji.

$ mkdir RCS

Vytvoření projektu

Vše máme připraveno k tomu, abychom mohli začít samotné RCS. Ze všeho nejdříve je vždy nutné založit projekt. K tomu slouží příkaz ci (check in) s názvem souboru jako argumentem.

$ ci .vars
RCS/.vars,v  <--  .vars
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> Tento konfiguracni soubor bude proveden vzdy po prihlaseni do
systemu. Obsahovat bude uzivatelske nastaveni systemovych promennych.
>> .
initial revision: 1.1
done
$

RCS po nás chce nějaký komentář k verzi (bude ho chtít ke každé verzi), který končí tečkou na samostatném řádku. Je dobré si nechat na komentářích záležet a nějaký čas jim věnovat. Výrazně usnadňují čitelnost. Oceníme je obzvláště při hledání nebo rychlém prohlížení historie změn sledovaného souboru. Komentář nebude vyžadován pouze pokud ho předáme pomocí přepínače -m. Ekvivalentní příkaz poslednímu by tak byl:

$ ci -m"Tento konfiguracni soubor bude proveden vzdy po prihlaseni do systemu.
Obsahovat bude uzivatelske nastaveni systemovych promennych." .vars

Tím jsme vytvořili projekt ve verzi 1.1. RCS bude implicitně každé další verzi iterovat druhé číslo. To znamená, že po 1.1 budou následovat verze 1.2, 1.3, 1.4, 1.5 atd.

Nelekejme se, že nám soubor .vars zmizel! Lze ho opět vyvolat - za chvíli si povíme jak. Místo něj se teď v adresáři ./RCS vytvořil jiný soubor s názvem .vars,v s informacemi o stavu a kompletním seznamem změn projektu. V jednom okamžiku díky tomuto mechanizmu může na souboru pracovat (přesněji zapisovat) pouze jeden člověk, který si na něj dal zámek.

Vyvolání aktuální verze projektu

$ co .vars
RCS/.vars,v  -->  .vars
revision 1.1
done
$

Příkaz co (check out) soubor .vars opět z adresáře RCS vyvolá. Ve výpisu mimo jiné zobrazuje i vyvolaná verze projektu. Zkusme ho ale editovat. Nepůjde to. Za to může už zmiňovaný systém zamykání. Abychom mohli pokračovat v projektu, musíme soubor zamknout. Nejjednodušší způsob je už vyvolávat s přepínačem -l. Tak se zamkne okamžitě při vyvolání a dále se o nic nemusíme starat.

$ co -l .vars
RCS/.vars,v  -->  .vars
revision 1.1 (locked)
done
$

Ve výpisu přibylo (locked). Soubor .vars tak může být upravován.

RCS umožňuje podporu zámků vypnout. K tomu slouží příkaz

$ rcs -U .vars

K mechanizmu zamykání se zas vrátíme pomocí

$ rcs -L .vars

Přidání nové verze

Nejprve uděláme v souboru nějaké změny. Tak například přidáme tyto řádky:

export CVSROOT=/home/cvsroot
export HISTSIZE=1500

Nyní nám nic nebrání vytvoření verze 1.2. K tomuto úkonu slouží stejný příkaz jako pro vytvoření projektu:

$ ci .vars
RCS/.vars,v  <--  .vars
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> Pridano: CVSROOT (umisteni repozitare CVS)
>> Pridano: HISTSIZE (pocet pamatovanych prikazu shellu)
>> .
done
$

Čísla verzí lze nastavit ručně. Opět vyvoláme soubor .vars.

$ co -l .vars

a přidáme další řádek:

export FIGNORE='~:.backup:.log'

Teď vytvoříme ne verzi 1.3, ale přímo 2.1. Přepínačem -r specifikujeme číslo verze, jako kterou chceme projekt uložit.

$ ci -r2.1 .vars
RCS/.vars,v  <--  .vars
new revision: 2.1; previous revision: 1.2
enter log message, terminated with single '.' or end of file:
>> Pridano: FIGNORE (omezuje tabulatorovou expanzi o soubory s uvedenymi priponami)
>> .
done
$

Vyvolání starší verze a větvení

Stejně jako má parametr -r příkaz ci, má ho i co. Pokud po vyvolání starší verze projekt opět pomocí ci uložíme, dochází k větvení. Projekt se dělí do dvou větví, přičemž každá může být vyvíjena nezávisle.

$ co -l -r1.2 .vars

Teď byla vyvolána verze 1.2. Už ale existují novejší. Verzi 1.2 editujeme a přidáme do projektu.

$ ci .vars
RCS/.vars,v  <--  .vars
new revision: 1.2.1.1; previous revision: 1.2

Pokud budeme projekt vyvolávat bez udání parametru -r, automaticky se vyvolá verze 2.1. Je ale možné vyvolat i verzi 1.2.1.1. V takovém případě se změny na verzi uloží jako 1.2.1.2. Následovaly by 1.2.1.3, 1.2.1.4 atd. Tato řada je větví projektu, kdežto řada 1.x je kmen.

Větvit se samozřejmě dá i z aktuální verze. Dejme tomu, že máme aktuální verzi 2.1 a chceme oddělit veřejnou větev 2.1.1 (4. číslo se doplní automaticky s commitem - teď ještě žádná verze 2.1.1.1 neexistuje):

$ ci -f -u2.1.1 .vars

Další příkaz, rcsmerge, umí takové věci jako rozdíl mezi verzemi 1.3 a 1.4 automaticky aplikovat i na aktuální verzi 1.2.1.2. To se často hodí v případech, kdy byla (verzí 1.4) opravena chyba a chceme ji opravit i v jiné větvi.

$ rcsmerge -r1.3 -r1.4 .vars

Často dojde k nějakému konfliktu a je nutný ruční zásah. Na případné konflikty vás příkaz rcsmerge upozorní. V upravovaném souboru jsou konflikty konkrétně vyznačeny. V souvislosti s CVS je v tomto článku vyznačení konfliktů rozebráno podrobněji.

Výpis historie

Dalším užitečným příkazem, který patří do RCS, je rlog. Jeho výstupem je seznam všech verzí. U každé je mimo další uvedeno i datum a čas vytvoření, autor, stav a také nezbytný komentář.

$ rlog .vars

Je možné omezit výpis historie pouze na podmnožinu verzí. Informace o verzi 2.1 získáme příkazem

$ rlog -r2.1 .vars

Obzvláště při hledání v komentářích se hodí zobrazení informací o několika po sobě jdoucích verzí. Užívá se opět přepínač -r, kterému se předává řetězec od:do. od znamená verzi, od které má výpis začínat a do bude poslední vypsaná verze. Vše od verze 1.2 do 2.1 získáme příkazem

$ rlog -r1.2:2.1 .vars

Zachycení rozdílů mezi dvěma verzemi

Příkaz rcsdiff má mnoho společného s unixovým diff. Chceme-li porovnat právě zpracovávanou verzi s nějakou starší, například 1.2, použijme přepínač -r:

$ rcsdiff -r1.2 .vars

Přidáním dalšího -r porovnáme dvě libovolné verze. Rozdíl mezi verzí 1.1 a 1.2:

$ rcsdiff -r1.1 -r1.2 .vars

Stavy verzí

Implicitně je stav verze vždy Exp, což znamená Experimental. Lze ji změnit na Stab (Stable) a nebo Rel (Release). Pokud bychom tedy chtěli verzi 2.1 uvolnit, změníme stav na Release.

$ rcs -sRel:2.1 .vars

Parametr -s lze přidat přímo za co nebo ci. V případě co vyvoláme poslední Release verzi, v případě ci bude už spolu s vytvořením nové verze její stav Release.

$ ci -sRel -r3.1 .vars

To je RCS k téměř vše. Nakonec ještě zmiňme, že RCS podporuje klíčová slova. Popsány jsou dále v tomto článku v části o CVS, které klíčová slova podporuje také.

CVS (Concurrent Versions System)

CVS pracuje už s rozsáhlými projekty. Udržuje pořádek ve větším množstvím souborů. Můžeme tak spravovat vývoj většího programu, celé sbírky básní nebo třeba projekt webové stránky. Mezi často využívané možnosti patří práce v síti nebo multiuživatelský režim.

CVS můžeme stáhnout z ccvs.cvshome.org/servlets/ProjectDocumentList. Opět se instaluje přes ./configure; make; make install.

Repozitář

V RCS byly informace o různých projektech vždy na různých místech adresářové struktury. Záleželo na umístění sledovaného souboru. CVS řeší tento problém jinak a přehledněji. Všechny projekty jsou umístěny v jednom adresáři (repozitář), například /home/cvsroot nebo /cvsroot. Každý projekt bude mít v repozitáři svůj adresář.

Cestu k repozitáři je třeba uložit do systémové proměnné CVSROOT.

$ mkdir /home/cvsroot
$ export CVSROOT="/home/cvsroot"

Pokud z nějakého důvodu proměnnou CVSROOT nemáme nebo ji chceme překrýt, je nutné uvádět globální volbu -d/cesta/k/repozitáři.

Nyní tento adresář inicializujeme (to je samotné vytvoření repozitáře). CVS si v něm vytvoří podadresář CVSROOT a v něm řadu souborů, kterými CVS spravuje repozitář.

$ cvs init

Ještě to samé pro případ, že nemáme cestu určenou proměnnou CVSROOT. Dále budeme už vždy předpokládat, že máme proměnnou CVSROOT nastavenou.

$ cvs -d/home/cvsroot init

Nyní máme vše připraveno a můžeme začít spravovat.

Zabezpečení

Pokud je nutné, aby k repozitáři měli přístup jen určení uživatelé, cesta vede přes skupiny. Vytvoří se skupina cvs, která bude vlastnit repozitář. Nastavením práv pro tuto skupinu dosáhneme toho, že přístup k repozitáři budou mít pouze její členové.

# groupadd cvs
# chgrp -R cvs /home/cvsroot/
# chmod g+w /home/cvsroot/

Příkaz cvs

cvs je poměrně členitý příkaz. Proto si v něm udělejme jasno ještě dříve, než budeme pokračovat dále.

$ cvs [globální_volby] příkaz [volby_příkazu] [soubor]

globální volby jsou volby samotného příkazu cvs. Nejsou závislé na příkazech. Následuje podpříkaz a za ním volby specifické pro každý podpříkaz.

Občas užitečnou globální volbou může být -n, která simuluje práci s CVS, ale soubory přitom nemění (tzn. výpisy jsou normální, ale nic se neděje). Postupně se seznámíme i s dalšími přepínači.

Vytvoření projektu

Po vytvoření úvodní verze projektu ji chceme importovat do CVS. Přesuneme se tedy do adresáře, kde máme soubory projektu (ne do adresáře $CVSROOT) a založíme projekt. K tomu nám poslouží příkaz cvs import:

$ cd /cesta/k/souborum/projektu
$ ls #jen pro informaci
head.c  data  index.c  INSTALL
$ cvs import -m"novy projekt" pro DEV START
N pro/index.c
N pro/head.c
N pro/INSTALL
N pro/data

No conflicts created by this import

$

Přepínač -m má stejný význam jako u vytváření RCS projektů - specifikuje se jím komentář. Následují parametry pro DEV START. pro je název projektu, DEV dodavatel a START je úvodní tag. Všechny argumenty jsou povinné.

cvs import vytiskl seznam souborů, které byly nalezeny v aktuálním adresáři (ne vždy je totožný se seznamem importovaných souborů). Před každým je písmeno označující odezvu. Možné odezvy:

OdezvaPopis
Nnew - přidán nový soubor
Mmodified - změněm soubor
Uupdated - aktualizován soubor
L, I, Csymbolický odkaz, ignored, conflict - ignorováno

Ignorovány jsou například soubory s názvem končícím tildou, soubory specifikované v systémové proměnné CVSIGNORE nebo symbolické odkazy.

To je vše, nyní je projekt úspěšně založen. Původní soubory projektu narozdíl od RCS nezmizely. V adresáři $CVSROOT/pro se vytvořily jejich kopie s poznámkami CVS.

Vyvolání aktuální verze projektu

Přesuňme se do adresáře, do kterého chceme projekt vyvolat. Mimochodem - toto je příjemná vlastnost. Projekt můžeme vyvolat kdekoliv. To u RCS nešlo. Ve vybraném adresáři spusťme příkaz

$ cvs checkout pro

nebo jeho kratší variantu cvs co. Existuje také příkaz export, který se používá stejně jako checkout s tím rozdílem, že nevytváří pracovní soubory (nevytváří podadresář CVS), ale jen soubory zkopíruje.

V aktuálním adresáři se vytvořil podadresář pro, kde jsou umístěny vyvolané soubory projektu pro. Navíc je tam další adresář CVS.

Vyvolání starší verze projektu

Možná znáte tuto situaci. Rozhodli jste se k radikální změně v projektu. Přepíšete soubory, změníte strukturu (i když změnu struktury berte s rezervou - pokud nenavrhnete správnou strukturu napoprvé, asi se u CVS objeví problémy...) a ono to stále ne a ne fungovat. Pokud používáte SCM, nemusíte se takových chvil bát. CVS totiž umožňuje vyvolat verzi projektu z libovolného okamžiku. Vyvoláme stav projektu z 6. 6. 2005 22:55, kdy vše ještě fugovalo. K příkazu co nebo up se přidává přepínač -D, který určuje datum a čas. Obvykle se uvádí ve formátu RRRR-MM-DD HH:MM, ale můžeme použít i DD MMM RRRR HH:MM, kde MMM jsou první tři písmena anglického názvu měsíce (Jan, Feb atd.), nebo některou ze speciálních frází. Těmi jsou myšleny řetězce jako "yesterday", "1 hour ago" nebo třeba "last Sunday".

$ cvs co -D"2006-06-06 22:55" pro

Změny a přidání verze projektu

Jsme ve stavu, kdy máme projekt vyvolán. To je chvíle, kdy můžeme pracovat na další verzi. Když jsme s úpravami hotovi, budeme chtít projekt zase uložit.

$ cvs commit -m"opraveny chyby"

Je opět možný i kratší zápis - commit lze nahradit za ci.

Problém nastává v případě, kdy se rozroste počet souborů projektu. CVS totiž kontroluje jen změny souborů, zapsaných v projektu. V takovém případě je to nutné dát systému CVS na vědomí.

$ cvs add passwd

Systému CVS jsme právě řekli, aby příště kontroloval i soubor passwd. Jsme v situaci, kdy CVS se souborem passwd počítá, ale přesto zatím není součástí projektu. To musíme udělat opět příkazem cvs commit. Pokud přidáváme soubory v novém podadresáři projektu, musíme stejným způsobem přidat i tento podadresář.

Složitější je to s přidáváním souborů, které nejsou čistým textem - tedy obrázky apod. Je nutné přidat přepínač -k s hodnotou 'b', který specifikuje binární soubor (více o tomto přepínači v části klíčová slova).

$ cvs add -kb foto.png

A co když naopak chceme nějaký soubor odstranit? Mechanizmus je úplně stejný jako u přidávání souborů, jen místo cvs add použijeme cvs remove. Užitečná je volba -f, která soubor odstraněný z projektu smaže i na disku (pokud tam ještě je).

Historii práce na projektu ukáže příkaz

$ cvs history -e

Výpis z historie, příkaz cvs log

Protože CVS spravuje více souborů, není už práce s historií tak jednoduchá. Svědčí o tom výpis příkazu

$ cvs log

Výstupem totiž je seznam historií jednotlivých souborů projektu (CVS udržuje historii každého souboru zvlášť).

Ve výstupu je u každé verze datum a čas vzniku, autor verze, stav a komentář - tedy stejné informace jako u RCS.

Protože většinou nechceme kompletní informace o projektu, ale jen nějakou jejich část, lze příkaz cvs log všelijak modifikovat. Například pro vytisknutí historie 1 souboru z projektu stačí na konec přidat jméno souboru.

$ cvs log index.c

cvs log s přepínačem -h vypisuje jen hlavičku.

Protože výstup příkazu cvs log je často velmi dlouhý, může se občas hodit přesměrování do souboru.

$ cvs log index.c > ../log/index.c.log

Další užitečné informace o souboru lze získat zadáním příkazu

$ cvs status index.c

Seznam registrovaných souborů projektu získáme příkazem

$ cvs log -R

cvs log dále umí zobrazovat, jak projekt vypadal někdy v minulosti. Změny, provedené do okamžiku 1.1.2005, 12:00 zobrazíme příkazem

$ cvs log -d"2005-01-01 12:00"

Pokud na začátek řetězce, který je hodnotou přepínače -d, připíšeme znaménko <, vypíší se změny od toho okamžiku. Od a do lze kombinovat, navíc lze používat speciální fráze, takže pak vznikají řetězce jako "1 month ago <= 2005-06-29".

Klíčová slova

Často je nutné přímo v projektu udržovat informace o verzi apod. CVS obsahuje mechanizmus klíčových slov, který takové situaci řeší. Pokud chceme, aby v nějakém souboru bylo vždy datum poslední změny souboru bez ručního zásahu, lze přidat klíčové slovo. Do místa souboru, kde chceme datum stačí umístit řetězec $Date$. Dále se o nic nemusíme starat - stačí uložit projekt a při checkoutu se $Date$ nahradí za $Date:datum a čas vydání verze$ (klíčové slovo $Date$ zůstává, aby CVS poznalo, že zde je tag a příště nahradilo opět aktuálními informacemi).

Mimo $Date$ existují i další klíčová slova.

Klíčové slovoPopis
$Author$autor
$Date$čas poslední změny souboru
$Header$, $Id$hlavička souboru - cesta, verze, datum, čas, autor, stav; rozdíl - $Header$ vypisuje absolutní cestu, $Id$ jen název souboru
$Locker$jméno toho, kdo má uzamčený soubor
$Log$informace o poslední změně souboru
$Name$jméno tagu
$RCSfile$jméno souboru
$Revision$číslo revize
$Source$absolutní cesta k souboru
$State$stav souboru - Exp, Stab nebo Rel

V souvislosti s příkazem add jsme se setkali s přepínačem -kb. To mimo jiné znamená, že se nebudou nahrazovat klíčová slova. Existují ještě další podobné přepínače. -kkv a -kkvl znamená, že se klíčová slova budou normálně nahrazovat, -kk nenahrazuje a navíc maže to, co bylo nahrazeno, -kv nahrazuje pouze jednorázově a přepínače -ko a -kb říkají, že se nic nahrazovat nemá.

Rozdíly mezi verzemi

Změny verze 1.5 oproti 1.4 se vytisknou příkazem

$ cvs diff -r1.4 -r1.5 pro

Tagy

Tagy jsou symbolická jména pro jednotlivé verze. Občas se hodí jasně označit určité milníky v historii projektu, abychom se k nim mohli snadno vracet.

Obvykle se tagy pojmenovávají velkými písmeny. Vytvoříme tedy tag RELEASE_1 na aktuální verzi.

$ cvs tag RELEASE_1

Kdekoliv, kde bychom psali číslo verze můžeme psát tag. Například pro získání rozdílů mezi verzemi RELEASE_1 a RELEASE_2 nemusíme dávat přepínači -r čísla verzí, ale postačí symbolický zápis.

$ cvs diff -rRELEASE_1 -rRELEASE_2 index.c

Tag můžeme použít i při checkoutu. Verzi RELEASE_1 získáme opět přes přepínač -r.

$ cvs co -rRELEASE_1 pro

Seznam tagů na souboru index.c tiskne příkaz status:

$ cvs status -v index.c

Větvení

Představme si situaci. Máme projekt ve verzi 1.5 a chceme ho rozdělit do 2 větví. K tomu vytvoříme speciální tag, který označíme přepínačem -b jako větev.

$ cvs tag -b VETEV

Člověk, který bude pracovat na větvi bude volat projekt volat příkazem

$ cvs co -rVETEV pro

Obě větve mohou být nerušeně vyvíjeny vedle sebe.

Příkaz cvs diff v takové situaci samozřejmě porovnává dvě poslední verze aktuální větve.

Dalším krokem je sloučení. CVS ho zvládá s přehledem. Pro samotné spojení verze VETEV s kmenem projektu zadejme příkaz:

$ cvs update -j VETEV

Na konflikty vás CVS upozorní a ty je třeba dodělat ručně. Po spojení větve a kmenu je ještě nutné poslat změny příkazem

$ cvs ci -m"Slouceni vetve VETEV s kmenem"

CVS nám to dovolí pouze v případě, že jsme odstranili konflikty. Proběhl-li příkaz bez chyb, vývoj může směle pokračovat dále ve sloučené verzi.

Ruční řešení konfliktů

Ještě si ukážeme, jak CVS zvýrazňuje konflikt. Dojde k němu například v případech, kdy byl modifikován v obou slučovaných verzích stejný řádek. Konflikt začíná řetězcem <<<<<<< soubor a končí >>>>>>> slučovaná_verze. Uvnitř jsou řetězce z obou slučovaných verzí oddělené pomocí =======. U RCS je to podobné - jen verze a název souboru jsou jsou prohozené.

<<<<<<< index.c
retezec_v_prvni_slucovane_verzi
=======
retezec_v_druhe_slucovane_verzi
>>>>>>> 1.26

Vybereme jeden z úseků nebo je vhodně sloučíme. Zbytek smažeme a konflikt je vyřešen.

Přesun souborů

V této oblasti má CVS velkou mezeru, protože přesun souborů (nemluvě o adresářích) neumožňuje. Používá se několik postupů, jak alespoň nedokonale přesun uskutečnit. Lze hrubě zasáhnout do repozitáře a použít mv (potom to bude vypadat, jako by byl v projektu odjakživa), další možností je soubor nepřesunovat, ale zkopírovat pomocí a pomocí cvs remove starý soubor odebrat. Více se o přesouvání dozvíte např. v manuálu nebo ve speciálním díle seriálu Výlet do říše verzí na root.cz. Ani jedna metoda není dokonalá a vždy mohou nastat problémy.

Administrace

Příkaz cvs admin umí nebezpečnou věc - měnit historii souborů. Je třeba ho tedy používat opatrně. My si ukážeme jen dvě nejčastější užití, ale v dokumentaci najdeme spoustu dalších možností.

To, že se přepíšeme při komentáři se občas stane téměř každému. Protože jde o důležitou součást informací o verzi, je nutná oprava. Ke změně komentáře slouží přepínač -m.

$ cvs admin -m 1.17.1.2:"novy opraveny komentar" data

Příkaz změnil komentář k verzi 1.17.1.2 souboru data. Všimněme si, co a jak je předáváno volbě -m. Číslo verze je dvojtečkou odděleno od samotného komentáře.

Další častá změna nastává, když zjistíme, že jsme do projektu importovali binární soubor jako textový. Přepínač -k mění systém nahrazování klíčových slov.

$ cvs admin -kb foto.png

Více uživatelů

Zatím jsme se nezabývali situací, kdy pracují vývojáři současně na projektu a ve stejném okamžiku ho upravují. Podobný problém jsme už řešili - při slučování větví projektu.

Máme dva uživatele - petr a adam. Oba ve stejné chvíli pracují na projektu. adam změnil soubor data a odeslal jej do repozitáře. petr nezávisle na něm změnil soubory data a index.c. Nyní by je chtěl také odeslat.

Předtím se musí petr přesvědčit příkazem cvs status, zda již někdo neupravil některý ze souborů, který změnil. Pozná to podle položky Status: Needs Merge. Pro rychlý přehled je užitečné volat

$ cvs status | grep Status

Zde jsou ty nejčastější statusy:

StatusPopis
Up-to-datepracovní soubor je aktuální
Need Mergekonflikt
Locally Modifiedpracovní soubor je novější než soubor v repozitáři
Needing Patchpracovní soubor je naopak starší - někdo ho změnil a měli bychom updatovat projekt
Locally Addedv pracovní kopii je nový soubor, který ještě není v repozitáři
Locally Removedv pracovní kopii je smazán soubor, který ještě v repozitáři je

petr vidí, že soubor data upravoval současně s ním adam. Proto musí nejprve sloučit svoji a adamovu verzi:

$ cvs update

Konflikty je opět nutné řešit ručním zásahem. Teď už petrovi nic nebrání poslat sloučenou verzi do repozitáře.

Ještě si velmi stručně povíme, jak je to u složitějších projektů. Tam se používají tzv watches (kukátka). Vývojář si nechá hlídat, zda někdo nemění sledovaný soubor. Pokud ano, pošle se mu automaticky email.

Je nutné vytvořit nový administrační soubor $CVSROOT/CVSROOT/users a upravit soubor $CVSROOT/CVSROOT/notify. Obsah adresáře $CVSROOT/CVSROOT je pouze pro čtení. Lze ale, stejně jako u obyčejných projektů, vyvolat jeho pracovní kopii:

$ cvs co CVSROOT

V souboru $CVSROOT/CVSROOT/notify odkomentujeme (případně přidáme) řádek:

ALL mail -s "CVS notification" %s

Je samozřejmě možné použít jakýkoliv jiný příkaz než mail nebo si ten stávající upravit k obrazu svému.

Vytvoříme soubor users. Bude obsahovat řádky ve formátu uživatel:hodnota. Právě zde uvedenou hodnotou se nahradí %s z minulé ukázky kódu. V našem případě bude hodnotou emailová adresa. Sem se budou posílat upozornění. Tedy konkrétně například:

petr:petr@neco.cz

A nakonec projekt CVSROOT commitneme.

$ cvs add users
$ cvs ci

Necháme si jako uživatel petr hlídat soubor index.c.

$ cvs watch add -aall index.c

To je vše. Teď se přihlásí adam. Vyvolá projekt a příkazem cvs edit index.c dá najevo, že bude soubor index.c upravovat. Jakmile zadá cvs edit, pošle se email uživateli petr, který si nechal tento soubor hlídat.

CVS a síť

Co si pod tím vlastně představit? Jednoduše to, že repozitář (server) bude na speciálním počítači. Na jiných počítačích budou klienti a ti mohou stahovat z repozitáře data.

Vytvoříme si takový server. Do /etc/services přidejme řádek:

cvspserver 2401/tcp

Dále vytvořme soubor /etc/xinetd.d/cvspserver s tímto obsahem:


service cvspserver
{
  disable = no
  socket_type = stream
  protocol = tcp
  wait = no
  user = root
  server = /usr/bin/cvs
  server_args = -f --allow-root=/cesta/k/repozitari pserver
}

Teď restartujeme xinetd:

# /etc/init.d/xinetd restart

Nakonec ještě vytvoříme soubor $CVSROOT/CVSROOT/passwd, do kterého přidáme řádky ve tvaru

cvs_login:passwd_des:systemovy_login

Takto vytvoříme uživatele user bez hesla se systémovým loginem petr:

user::petr

Server je připraven, teď zbývá nakonfigurovat klienta. Jako $CVSROOT nastavíme

:pserver:uzivatel@adresa_pocitace:/cesta/k/repozitari

Tedy konkrétně například

$ export CVSROOT=:pserver:user@192.168.0.1:/home/cvsroot

Zalogujeme se příkazem cvs login:

$ cvs login
Logging in to :pserver:user@192.168.0.1:2401/home/cvsroot
CVS password:
$

A to je vše! Teď můžeme vesele pracovat se vzdáleným repozitářem.

Nicméně v této souvislosti zmíňme ještě jeden globální parametr, a to -z. Jako hodnotu mu přiřaďme číslo 1 - 9, které specifikuje úroveň komprese (1 - nejmenší, 9 - největší). Takže budeme vzdáleně checkoutovat například takto:

$ cvs -z5 co pro

GUI nadstavby

Pro ty, kteří používají KDE je dobrou volbou Cervisia. Umí spolupracovat s Quantou a Konquerorem. Volbou Repository->Získat checkoutujeme projekt a následně zobrazíme jeho pracovní kopii pomocí Soubor->Otevřít repository. Ovládání je více méně intuitivní.

Cervisia - hlavní okno

Dalším GUI klientem je TkCVS.

TkCVS

Vynikající utilitou je také CvsGraph. Z CVS a RCS repozit souborů umí generovat grafické stromy. Příkazem

$ cvsgraph -r/cesta/k/repozitáři -ostrom.png soubor,v

se zapíše grafický strom souboru soubor,v do strom.png. Může vypadat přibližně takto:

Strom vygenerovaný pomocí CvsGraph

Další správci verzí

CVS není zdaleka dokonalé (o čemž hovoří např. článek Stinné stránky CVS na root.cz) a postupem času to lidem začalo docházet. Vzniklo tak mnoho projektů, které měly za cíl CVS nahradit. Asi nejvíce se cíli přiblížil Subversion.

Cílem Subversion je podobné ovládání jako CVS a zároveň odstranění jeho nedostatků. Podporuje už i přesouvání souborů a mazání adresářů. Více se o Subversion nebudu rozepisovat, protože se chystá zvláštní článek.

Dalším velmi známým správcem verzí je BitKeeper. Problémem je, že má komerční licenci a uzavřený zdrojový kód. O jeho mimořádných kvalitách svědčí i to, že do letoška byl využíván i při vývoji linuxového jádra.

Jinými známými SCM jsou GNU Arch a Monotone.

Zdroje

Online verze článku: http://www.linuxsoft.cz/article.php?id_article=897