Professional Linux Programming, R-02-t, PLP_Rozdział2


2. CVS

Jednym z problemów, który powinien być rozwiązany we wczesnej fazie projektu jest sposób śledzenia zachodzących w nim zmian. Mogą to być zmiany zarówno w kodzie źródłowym, jak i w dokumentacji. Należy je śledzić z dwóch powodów: po pierwsze — po to, aby można było uzyskać informacje o zawartości kodu lub dokumentacji w określonym momencie czasu i po drugie — aby wiedzieć, co i kiedy się działo.

Oczywiście, można tworzyć tylko kopie poszczególnych plików w zapasowych katalogach, nadając im nazwy odpowiednie do daty. Takie proste rozwiązanie staje się jednak bardzo szybko rozwiązaniem nieefektywnym, szczególnie wtedy, gdy w projekcie bierze udział kilku programistów i czas pracy nad projektem wynosi więcej niż kilka tygodni.

Jeżeli programista pracuje samodzielnie, to zwykle wyobraża sobie, że kontrola kodu źródłowego nie daje zbyt wiele, ponieważ do tego kodu nie ma dostępu nikt oprócz niego samego. Niestety, nawet najlepsi programiści od czasu do czasu popełniają błędy i muszą powracać do poprzedniej wersji programu. Użytkownicy mogą zgłaszać błędy dostrzeżone w kolejnych wersjach programu i zamiast śledzenia tych błędów w tradycyjny sposób, łatwiej będzie cofnąć się do wersji poprzedniej i tam sprawdzić zmiany wprowadzone w kodzie. W takich okolicznościach system kontroli kodu źródłowego może dać nieocenione korzyści, ponieważ rejestruje on dokładnie kiedy i co zostało zmienione.

Jeżeli kilku programistów pracuje zespołowo, to wymagania są jeszcze ostrzejsze niż w przypadku programu tworzonego przez jedną osobę. Trzeba wówczas wiedzieć kto, co i kiedy zmienił — ponieważ wtedy można łatwiej zlokalizować miejsce popełniania błędów. Dzięki zastosowaniu odpowiednich komentarzy przy okazji dokonywania zmian w kodzie można również dowiedzieć się, dlaczego zmiany te zostały wprowadzone, co bywa czasami bardzo przydatne.

Mówiąc krótko: istnieje bardzo wiele powodów, dla których warto stosować system kontroli kodu źródłowego, natomiast bardzo mało jest przeciwwskazań, biorąc pod uwagę jakość bezpłatnych narzędzi dostępnych w systemie Linux.

W tym rozdziale omówimy:

Narzędzia dla systemu Linux

Kiedyś istniał tylko jeden sposób kontroli kodu źródłowego w Linuksie, a mianowicie tzw. system kontroli wersji (Revision Control System oznaczany skrótem RCS) wchodzący w skład zestawu narzędzi programowania GNU. System RCS był i jest nadal bardzo użyteczny, ale wielu programistów (szczególnie tych, którzy brali udział w pracach zespołowych lub działali w różnych środowiskach programowania) zaczęło korzystać z nowszego narzędzia, czyli z CVS (Concurrent Versions System).

CVS powstał w roku 1986. jako zestaw kilku skryptów powłoki. Obecnie kod tego systemu opiera się głównie na pracy Briana Berlinera z 1989. roku. CVS ma trzy podstawowe właściwości, dzięki którym bywa coraz częściej stosowany do zarządzania zmianami w kodzie źródłowym zamiast RCS:

Dodajmy do tego fakt, że CVS jest całkowicie bezpłatny i otrzymujemy doskonałe narzędzie, które prawdopodobnie kiedyś trzeba będzie poznać. W tym rozdziale omówimy następujące zagadnienia:

CVS jest dość skomplikowanym systemem i dlatego nie można szczegółowo omówić wszystkich jego właściwości w jednym rozdziale. Myślimy jednak, że udało się tu przedstawić ok. 95% tych szczegółów, które będą potrzebne w praktyce. Jeżeli pojawią się jakieś bardziej zaawansowane potrzeby, to należy samemu przestudiować wszystkie ukryte cechy CVS.

Skoncentrujemy się tutaj na zarządzaniu kodem źródłowym za pomocą CVS. Należy przy tym pamiętać, że odnosi się to tylko do zarządzania zmianami w danych testowych, plikach konfiguracyjnych lub pomocniczych skryptach używanych w projekcie. Oczywiście, wszystkie elementy projektu mogą być przechowywane w systemie CVS.

CVS może także przechowywać specyfikację projektu, która jest często bardziej wartościowa niż sam kod źródłowy. Jeżeli jednak jakiś element projektu jest zapisany w postaci binarnej, to informację o tym należy przekazać do CVS. Dodatkowo, system nie będzie wówczas mógł automatycznie sygnalizować różnic między poszczególnymi wersjami takiego elementu. Pod koniec tego rozdziału powiemy więcej na temat zarządzania plikami binarnymi.

Terminologia

Przed rozpoczęciem pracy z systemem CVS musimy zapoznać się ze stosowaną w nim terminologią:

W dalszych częściach rozdziału wprowadzimy jeszcze kilka dodatkowych określeń, ale podane wyżej definicje wystarczają już do rozpoczęcia pracy z CVS.

Repozytorium

System CVS wchodzi w skład wszystkich ważniejszych dystrybucji Linuksa, a więc w tym rozdziale skoncentrujemy się na jego konfiguracji. Jeżeli zdarzy się (co jest bardzo mało prawdopodobne), że dana dystrybucja nie zawiera CVS, to należy skorzystać z informacji źródłowych podanych na końcu rozdziału i pobrać go samemu z jakiegoś serwera.

Przed uruchomieniem CVS należy utworzyć repozytorium, które posłuży do przechowywania głównych kopii plików źródłowych i wewnętrznych plików konfiguracyjnych.

Lokalizacja repozytorium jest sprawą osobistego wyboru. Ponieważ będzie ono zawierać główne kopie plików źródłowych, to warto ulokować je w zabezpieczonym miejscu i regularnie tworzyć kopie zapasowe! Całkowicie wykonalne jest utworzenie na tym samym komputerze wielu repozytoriów, z których każde będzie niezależnie przechowywać struktury wielu projektów. Każde repozytorium może obejmować wiele podkatalogów, a więc konfiguracja systemu CVS jest bardzo elastyczna.

W naszym przypadku utworzymy repozytorium CVS w katalogu /usr/local/cvsrep. Jeżeli projekt jest duży, to na repozytorium można przeznaczyć oddzielną partycję dysku i wydzielony punkt zamontowania katalogu. Aby zachować kontrolę dostępu do CVS, co jest związane z odpowiednimi uprawnieniami do zapisu w repozytorium, należy utworzyć grupę użytkowników, którzy będą korzystali z systemu CVS.

W celu łatwiejszego zapamiętania nazwiemy tę grupę cvs-user. Dowolny użytkownik, który chce uzyskać dostęp do repozytorium CVS będzie musiał należeć do tej grupy. Przed dopisaniem użytkowników musimy skonfigurować nasze repozytorium. Najpierw z konta root utworzymy grupę:

# groupadd cvs-user

a następnie katalog:

# mkdir /usr/local/cvsrep

Po utworzeniu katalogu przeznaczonego na repozytorium system CVS musi utworzyć pliki służące do zarządzania repozytorium. W tym celu z konta root należy uruchomić polecenie:

# cvs -d /usr/local/cvsrep init

CVS utworzy w katalogu /usr/local/cvsrep katalog CVSROOT, a w nim różne wymagane pliki konfiguracyjne.

Można teraz przejść do tego katalogu i zmienić grupowe prawa właścicielskie katalogu z repozytorium i wszystkich zawartych w nim plików na grupę cvs-user:

# cd /usr/local/cvsrep

# chmod g+w .

# chgrp -R cvs-user .

Od tego momentu wszyscy użytkownicy należący do grupy cvs-user będą mogli bez ograniczeń korzystać z repozytorium CVS. Starszym użytkownikom systemu UNIX przypominamy, że Linux, podobnie jak większość współczesnych wersji systemu UNIX, pozwala użytkownikom należeć do wielu grup, a więc przynależność do grupy cvs-user nie pociąga za sobą żadnych ograniczeń.

Obsługa CVS przez jedynego użytkownika

Pokażemy tutaj sposób korzystania z systemu CVS przez jedynego użytkownika repozytorium, a przy okazji zobaczymy jak CVS zarządza naszym własnym kodem źródłowym.

Format polecenia CVS

CVS jest narzędziem uruchamianym z wiersza poleceń i taki interfejs będzie omawiany w tym podrozdziale. Później omówimy także kilka interfejsów graficznych opracowanych dla CVS.

Wszystkie polecenia CVS mają następującą postać:

cvs [opcje standardowe] polecenie [opcje polecenia] [nazwy plików]

Jak widać, polecenia te zawierają argument opisujący faktyczną wymaganą operację. Taka postać pozwala na użycie dla CVS całkowicie nowej tablicy nazw i ich uproszczenie. Opcje standardowe są dostępne dla większości poleceń CVS. Poniżej podajemy podstawowe z nich:

-d <repository>

Definicja używanego repozytorium. Jeśli nie korzystamy z wielu repozytoriów, to na ogół wygodniej jest zdefiniować zmienną środowiskową. Opcja -d zastępuje wartość zmiennej środowiskowej CVSROOT (którą wyjaśnimy wkrótce), co zapewnia wygodny dostęp do rzadko używanych repozytoriów.

-e <editor>

Definicja edytora używanego wówczas, gdy CVS żąda podania danych wejściowych, np. przy wpisach do logu.

--help, -H

Wyświetlenie tekstu pomocy dla danego polecenia.

-n

Brak działania. Umożliwia podgląd operacji CVS bez ich faktycznego wykonywania.

-q, -Q

Praca ze zmniejszoną liczbą komunikatów wyjściowych CVS (-q) lub całkowicie bez tych komunikatów (-Q).

-t

Śledzenie działania.

-v, -version

Wyświetlenie numeru wersji CVS.

-z <level>

Stopień kompresji przesyłanych danych. Opcja używana przy dostępie z sieci. Wartość 1 oznacza najmniejszą kompresję, a 9 — kompresję maksymalną. Wartość 4 stanowi dobry kompromis między wykorzystaniem procesora i szerokością pasma zajmowanego przy transmisji.

Zmienne środowiskowe

Przed rozpoczęciem pracy w systemie CVS trzeba jeszcze zapoznać się z kilkoma przydatnymi zmiennymi środowiskowymi używanymi przez ten system (tutaj opisujemy tylko trzy zmienne, w rzeczywistości jest ich nieco więcej):

CVSROOT

Definiuje repozytorium, do którego będą się odnosić polecenia CVS.

CVSEDITOR

Definiuje edytor, wywoływany przez CVS jeśli istnieje potrzeba wpisania jakiegoś tekstu.

CVSIGNORE

Definiuje listę nazw plików i wzorce nazw plików, które mają być ignorowane podczas wykonywania poleceń CVS.

Wartość zmiennej środowiskowej CVSROOT może być zawsze zastąpiona wartością opcji -d, jak już wspomnieliśmy w poprzednim podrozdziale. Będziemy ją ustawiać przed następnymi czynnościami. Podane niżej polecenia dotyczą powłoki typu BASH, przy powłoce csh należy użyć polecenia setenv.

$ export CVSROOT=/usr/local/cvsrep

$ export CVSEDITOR=emacs

$ export CVSIGNORE="foo bar *.class"

Od tego momentu będą obowiązywać następujące wartości i zachowania domyślne: /usr/local/cvsrep jako repozytorium, emacs jako edytor używany przez CVS, a polecenia CVS zawsze będą ignorowały pliki o nazwach foo i bar oraz pliki o nazwach z końcówką .class.

W praktyce CVS rozpoznaje wiele rodzajów plików pośrednich powstających przy kompilacji, łącznie z plikami o nazwach kończących się na .o, .a i ~, a także pliki core ignorując je automatycznie.

Import nowego projektu

Rozpocznijmy od bardzo wczesnego etapu naszego projektu, gdy mamy tylko trzy pliki zawierające polecenia SQL:

create_tables.sql

drop_tables.sql

insert_data.sql

Nie jest to zbyt wiele, ale wystarczy do zapoznania się z działaniem systemu CVS. Najpierw musimy wybrać nazwę naszego projektu. CVS używa tej nazwy jako nazwy katalogu, a więc musi ona spełniać określone reguły. Nazwiemy więc nasz projekt plip-app, a ponieważ powstał on dla wydawnictwa Wrox, to umiejscowimy go także w katalogu wrox.

Zaimportujemy nasz niewielki zbiór plików za pomocą plecenia cvs import. Wykorzystamy tu jedynie opcję -m, która definiuje komunikat wpisywany do logu (jeśli nie podamy tej opcji w wierszu poleceń, to CVS tego zażąda). Użytkownicy zaznajomieni z systemem RCS korzystają często w poleceniu import z opcji -b, która umożliwia nadanie początkowego numeru sekwencji.

Ciekawscy czytelnicy mogą znaleźć opisy rzadziej stosowanych opcji na stronach podręcznika systemowego man oraz info i w publikacjach wymienionych na końcu tego rozdziału.

Mamy więc następującą składnię polecenia cvs import:

cvs import [opcje] nazwa-projektu znacznik-autora znacznik-wydania

Polecenie cvs import wyszukuje wszystkie pliki w bieżącym katalogu i importuje je kolejno do projektu. W naszym przypadku użyjemy opcji -m podając w niej komunikat do logu, jako znacznika autora użyjemy nazwy stixen oraz jako znacznika wydania użyjemy start:

$ cvs import -m"Initial version of demonstration application for PLiP"

wrox/plip-app stixen start

Komunikaty CVS będą zbliżone do poniższych:

N wrox/plip-app/create_tables.sql

N wrox/plip-app/drop_tables.sql

N wrox/plip-app/insert_data.sql

I wrox/plip-app/create_tables.sql~

No conflicts created by this import

W odpowiedzi na polecenie importu mogą się pojawiać różnego rodzaju komunikaty. Pierwsza litera komunikatu określa jego rodzaj, a za nią następuje nazwa pliku. Jako komunikat końcowy często pojawia się też dodatkowa informacja. Istnieją następujące rodzaje odpowiedzi systemu CVS (nie tylko dla polecenia import):

C

Konflikt (conflict) — plik już istnieje w repozytorium, lecz różni się od pliku lokalnego, co wymaga ręcznego dołączenia.

I

Zignorowany (ignored) — plik został zignorowany.

L

Dowiązanie (link) — plik jest dowiązaniem symbolicznym i dlatego został zignorowany (CVS nie obsługuje dowiązań symbolicznych).

M

Zmodyfikowany (modified) — plik został zmodyfikowany w repozytorium.

N

Nowy (new) — nowy plik został dodany do repozytorium.

R

Usunięty (removed) — plik został usunięty.

U

Zaktualizowany (updated) — plik został zaktualizowany.

?

Zapytanie (query) — znaleziono nie występujący w repozytorium plik lokalny, który nie ma oznaczenia, że powinien być ignorowany.

W naszym przykładzie mamy trzy nowe pliki dodane do repozytorium i zignorowany plik kopii zapasowej create_tables.sql~ utworzony przez edytor emacs (wzorzec *.~ jest rozpoznawany automatycznie przez CVS jako nazwa pliku, który należy zignorować).

Jeżeli później zechcemy dodać do repozytorium kolejne nowe pliki (co jest wielce prawdopodobne zważywszy na szczupłość naszych początkowych danych), to możemy postąpić dwojako. Jeżeli projekt jest pobierany i przerabiany, to możemy posłużyć się poleceniem cvs add, omówionym dalej. Jeżeli projekt nie był przerabiany, to dodatkowe pliki można dodać posługując się poleceniem cvs import. Załóżmy, że po imporcie plików źródłowych zauważamy np. brak pliku README. Możemy utworzyć go w katalogu bieżącym i dodać go bezpośrednio do repozytorium za pomocą polecenia:

$ cvs import -m"Added README" wrox/plip-app stixen start

U wrox/plip-app/create_tables.sql

U wrox/plip-app/drop_tables.sql

U wrox/plip-app/insert_data.sql

N wrox/plip-app/README

I wrox/plip-app/create_tables.sql~

No conflicts created by this import.

CVS zauważa istniejące pliki, ale do repozytorium dodaje tylko nowy plik README.

Początek prac nad projektem w CVS

Mamy już utworzony nasz projekt CVS, a więc możemy oczyścić katalog bieżący i pobrać z repozytorium kopie plików, z którymi będziemy pracować. W zasadzie należałoby usunąć katalog lokalny i wszystkie pliki zaimportowane do CVS, ale w praktyce autorzy wolą pozostawić to wszystko, zmieniając tylko nazwę katalogu, przynajmniej do czasu uzyskania całkowitej pewności, że wszystkie pliki w repozytorium CVS są prawidłowe i o niczym nie zapomniano.

W rzeczywistości autorzy książki nigdy nie utracili plików z repozytorium CVS, ale postępują tak dlatego, że wolą dmuchać na zimne.

Aby pobrać pliki z repozytorium należy użyć polecenia cvs checkout. Polecenie to ma kilka opcji, z których podaliśmy niżej tylko najważniejsze:

-D <date>

Pobranie projektu z podaną datą. Przeważnie data jest podawana albo w zalecanym formacie ISO jako „1999-09-24 16:05”, albo można użyć „24 Sep 1999 16:05” lub nawet specjalnych fraz, takich jak „yesterday” lub „last Monday”.

-d <dir>

Pobranie projektu do wskazanego katalogu. Domyślnie, tak jak to wspomniano wcześniej, nazwa projektu jest używana jako nazwa katalogu.

-p

Pobranie projektu i przekazanie go na standardowe wyjście zamiast zapisania go w katalogu, co jest zachowaniem domyślnym.

-r <tag>

Pobranie projektu w stanie określonym przez dany znacznik. Do znaczników powrócimy już za chwilę.

W poleceniu należy także podać nazwę projektu, który ma być pobrany i opcjonalnie nazwy pobieranych plików. Domyślnie pobierane są wszystkie pliki.

Po przejściu do pustego katalogu możemy więc pobrać do niego nasz projekt i rozpocząć pracę:

$ cvs checkout wrox/plip-app

cvs checkout: Updating wrox/plip-app

U wrox/plip-app/README

U wrox/plip-app/create_tables.sql

U wrox/plip-app/drop_tables.sql

U wrox/plip-app/insert_data.sql

Zostanie utworzony podkatalog o nazwie wrox/plip-app, a w nim ostatnie wersje każdego pliku, którymi można się posługiwać w dalszej pracy. Oprócz tego pojawi się podkatalog o nazwie CVS (wielkie litery). Jest to katalog roboczy systemu CVS i nie wolno zmieniać w nim czegokolwiek, pomimo że w niektórych dokumentach mówi się o tym. Zalecamy tu ścisłe trzymanie się oficjalnych poleceń, nawet wtedy, gdy wymagają one większej liczby uderzeń w klawisze.

Porównywanie zmian z zawartością repozytorium

Po pobraniu kopii projektu pracujemy nad nią lokalnie. Załóżmy więc, że po kilku godzinach pracy osiągnęliśmy jakiś kolejny stabilny stan, przetestowaliśmy wprowadzone zmiany i chcemy przenieść zmienione pliki źródłowe ponownie do repozytorium. Przed dokonaniem tej operacji zalecamy jednak ponowne sprawdzenie wprowadzonych zmian.

Pliki przechowywane można porównać lokalnie z plikami znajdującymi się w repozytorium używając polecenia cvs diff. Ma ono kilka opcji:

-c

Kontekstowe wyświetlenie różnic zawartości plików za pomocą programu diff (wiersze zmienione w otoczeniu wierszy sąsiednich) co ułatwia wzrokową identyfikację zmian.

-b

Ignorowanie różnic w liczbie spacji oddzielających wewnątrz danego wiersza.

-B

Ignorowanie wstawionych lub usuniętych pustych wierszy.

-D <date>

Wyszukiwanie różnic odniesionych do plików w repozytorium o określonej dacie.

-r <tag>

Porównanie z plikami o podanym numerze wersji lub znaczniku tekstowym.

Można podać dwie opcje -r i wtedy polecenie cvs diff służy do porównań wewnętrznych w repozytorium między dwoma różnymi wersjami. Pliki lokalne są wówczas ignorowane.

Można opcjonalnie podać w tym poleceniu listę plików i wówczas zostaną pokazane różnice ich zawartości. Jeżeli lista plików nie będzie podana, to polecenie cvs diff wskaże różnice zawartości wszystkich plików projektu i plików w bieżącym katalogu.

Należy pamiętać, że polecenie cvs diff ignoruje pliki utworzone w lokalnym katalogu, które nie są umieszczone w repozytorium. Na pierwszy rzut oka takie zachowanie domyślne nie wydaje się dobrym rozwiązaniem, ale w praktyce okaże się to przydatne, ponieważ pozwala uniknąć wielu komunikatów o braku jakichś tymczasowych plików w repozytorium.

Po modyfikacji naszych dwóch przykładowych plików uruchamiamy cvs diff i możemy porównać ich bieżące kopie robocze z kopiami znajdującymi się w repozytorium CVS:

$ cvs diff -B

cvs diff: Diffing .

Index: create_tables.sql

===============================================================

RCS file: /usr/local/cvsrep/wrox/plip-app/create_tables.sql,v

retriving revision 1.1.1.1

diff-B -r1.1.1.1 create_tables.sql

47a50,55

> );

>

> create table genre (

> genre_id INT NOT NULL,

> genre_name CHAR(21),

> CONSTRAINT genre_id_uniq UNIQUE(genre_id)

Index: drop_tables.sql

=============================================================

RCS file: /usr/local/cvsrep/wrox/plip-app/drop_tables.sql,v

retriving revision 1.1.1.1

diff -B -r1.1.1.1 drop_tables.sql

10a11

> drop table genre;

Jak widać, wyświetlona została nazwa każdego zmienionego pliku oraz wprowadzone w nim zmiany. Można także zauważyć odnośniki do RCS. Starsze wersje CVS były zbudowane na bazie RCS, a nowsze nadal korzystają z pewnych rozwiązań i nazw plików tego systemu.

Inny sposób porównywania plików lokalnych z plikami w repozytorium polega na użyciu polecenia cvs status, które generuje listę zmienionych plików. Polecenie cvs status -v umożliwi obejrzenie większej liczby komunikatów.

W tym momencie możemy zdecydować, czy chcemy utrzymać wprowadzone zmiany, czy też je pominąć. Jeśli chcemy pominąć zmiany, to najprostszym sposobem jest usunięcie lokalnego pliku i użycie polecenia cvs update — wtedy w katalogu lokalnym pojawi się „czysta” kopia pliku z repozytorium.

Aktualizacja repozytorium

Załóżmy, że zmiany wprowadzone w plikach lokalnych są zgodne z oczekiwaniami i chcemy przekazać zmienione pliki do repozytorium. Operacja ta nazywa się „zatwierdzaniem” i jest przeprowadzana za pomocą polecenia cvs commit.

Polecenie cvs commit ma tylko dwie często używane opcje:

-m <message>

Dołączenie komunikatu informacyjnego. Jeśli komunikat nie zostanie wpisany, to CVS wywoła edytor określony przez zmienną środowiskową CVSEDITOR lub, jeśli to się nie uda, przez zmienną EDITOR, albo domyślny edytor systemowy (zwykle jest to vi), w którym trzeba będzie wpisać komunikat.

-r <rev>

Zatwierdzenie korekty o określonym numerze. Jest to zalecane tylko wtedy, gdy projekt ma rozgałęzienia omówione w dalszej części tego rozdziału.

Po uruchomieniu polecenia cvs commit pojawi się informacja o plikach zmienianych w repozytorium:

$ cvs commit

Ponieważ nie podano komunikatu, a zmienna środowiskowa CVSEDITOR ma wartość emacs, to zostanie wywołany emacs i pojawi się żądanie wpisania komunikatu:

CVS: ------------------------------------------------------------

CVS: Enter Log. Lines beginning with 'CVS:' are removed automatically

CVS:

CVS: Committing in .

CVS:

CVS: Modified Files:

CVS: create_tables.sql drop_tables.sql

CVS: ------------------------------------------------------------

Po wpisaniu komunikatu i zamknięciu edytora emacs (i wcześniejszym zapisie pliku) polecenie cvs commit wznawia działanie:

Checking in create_tables.sql;

/usr/local/cvsrep/wrox/plip-app/create_tables.sql,v <-- create_tables.sql

new revision: 1.2; previous revision: 1.1

done

Checking in drop_tables.sql;

/usr/local/cvsrep/wrox/plip-app/drop_tables.sql,v <-- drop_tables.sql

new revision: 1.2; previous revision: 1.1

Na podstawie tych komunikatów widać, że CVS automatycznie określa, które pliki wymagają przetwarzania.

Wydanie projektu

Po zakończeniu pracy nad projektem należy go „wydać”, czyli spowodować, aby system CVS usunął wszelkie informacje o tym projekcie. W praktyce nie ma to zbyt wielkiego znaczenia w przypadku projektu prowadzonego przez jednego programistę lub mało skomplikowanego projektu prowadzonego przez wielu programistów, ale warto przestrzegać tego dobrego zwyczaju. W naszym przypadku wydanie (zwolnienie) projektu polega na przejściu do katalogu położonego o stopień wyżej niż katalog plip-app i użyciu polecenia cvs release. Polecenie to ma tylko jedną opcję:

-d

Automatyczne usunięcie zwolnionego katalogu.

Jeżeli w katalogu lokalnym istnieją jakieś zmiany nie przekazane do repozytorium, to pojawi się ostrzeżenie i można będzie anulować polecenie cvs release.

Przegląd zmian wprowadzanych do projektu przez cały okres pracy można uzyskać za pomocą polecenia cvs history. Polecenie to umożliwia zapoznanie się z całą historią projektu w postaci niezbyt przystępnie zbudowanej listy:

$ cvs history -e -a

O 04/15 17:23 +0000 rick wrox/plip-app =wrox/plip-app= ~/wrox/plip-app

M 04/15 21;15 +0000 rick 1.2 create_tables.sql wrox/plip-app == ~/wrox/plip-app

M 04/15 21;15 +0000 rick 1.2 drop_tables.sql wrox/plip-app == ~/wrox/plip-app

F 04/15 21:20 +0000 rick =plip-app= ~/wrox/*

Na podstawie powyższych komunikatów można poznać historie projektu. Najważniejsze opcje polecenia cvs history są następujące:

-a

Wyświetlenie historii działań wszystkich użytkowników.

-D <date>

Wyświetlenie zmian wprowadzonych od podanej daty.

-e

Wyświetlenie wszystkiego (domyślnie pokazywane są tylko pobrania).

-r <rev>

Wyświetlenie zmian, które wprowadzono od podanej korekty.

-u <user>

Wyświetlenie zmian dokonanych przez danego użytkownika.

Przeglądanie zmian

Po wprowadzeniu zmian do plików w repozytorium możemy zobaczyć co się zmieniło, używając polecenia cvs log. Należy w tym celu przejść ponownie do katalogu z zapisanym projektem. CVS może wówczas określić, którego projektu dotyczy polecenie. Rozmiar wyświetlanego tekstu jest raczej dosyć duży, a więc tutaj pokażemy tylko jego fragment:

$ cd plip-app

$ cvs log create_tables.sql

----------------------------

revision 1.2

date: 2000/04/15 21:15:08, author: rick; state: Exp; lines: +8 -0

Added the genre table.

----------------------------

revision 1.1

date: 2000/04/15 15;57:22, author: rick; state: Exp;

branches: 1.1.1;

Initial revision

Jeżeli w poleceniu cvs log nie zostanie podana nazwa pliku, to pojawią się zapisy z logu dotyczące wszystkich plików wchodzących w skład projektu. Polecenie cvs log ma kilka użytecznych opcji:

-D <date>

Wyświetlenie zmian wprowadzonych od podanej daty.

-h

Wyświetlenie tylko informacji nagłówkowej o każdym pliku.

Dodawanie i usuwanie plików z projektu

W miarę postępu prac nad projektem prawie zawsze pojawia się konieczność dodawania nowych plików do repozytorium CVS. Służy do tego polecenie cvs add z argumentem, którym jest nazwa dodawanego pliku. Polecenie to ma trzy główne opcje:

-kb

Oznaczenie pliku binarnego.

-ko

Zakaz rozwijania słów kluczowych (patrz poniżej)

-m <message>

Dopisanie do logu CVS komunikatu o przyczynie dodania pliku.

Przy dodawaniu nowego pliku do projektu nie jest on natychmiast dodawany do repozytorium. Polega to na tym, że nazwa pliku pojawia się na liście plików aktualizowanych w następnym poleceniu cvs commit.

Podobnie jest wykonywane usuwanie plików z projektu za pomocą polecenie cvs remove. Jeżeli plik o danej nazwie istnieje w katalogu lokalnym, to polecenie to nie uda się, chyba że zostanie użyta opcja -f, która służy do usuwania także plików lokalnych. Podobnie jak przy poleceniu cvs add, zawartość repozytorium jest zmieniana dopiero po zatwierdzeniu zmian za pomocą polecenia cvs commit.

Jeżeli plik zostanie usunięty i operacja ta zostanie zatwierdzona, a następnie zechcemy odtworzyć go ponownie, to nieusunięte pozostałości pliku można znaleźć w podkatalogu Attic w repozytorium CVS. Trzeba je wówczas skopiować do nowego katalogu i tam korzystając z edytora otworzyć oryginalny plik.

Rozwinięcia słów kluczowych

Jedną z cennych właściwości CVS jest możliwość używania słów kluczowych w pobieranym pliku. Właściwość ta została zaadoptowana z RCS i jest podobnie obsługiwana. Podczas pobierania plików z repozytorium lub zatwierdzania zmian używane są następujące „magiczne” napisy:

$Author$

Rozwinięcie na nazwę dostępową.

$Date$

Rozwinięcie na datę ostatniego zatwierdzenia.

$Headers$

Rozwinięcie na niektóre standardowe informacje nagłówkowe.

$Id$

Rozwinięcie na standardowe informacje nagłówkowe, bez nazw ścieżek.

$Log$

Rozwinięcie na zestaw komunikatów logu.

$Name$

Rozwinięcie na dowolną nazwę znacznika użytą przy pobieraniu danego pliku.

$Revision$

Rozwinięcie na numer korekty.

$State$

Ogólnie nie używane.

Najłatwiej wyjaśnić działanie tych słów kluczowych po ich rozwinięciu:

$Author: rick $

$Date: 2000/04/16 17:38:08 $

$Header: /usr/local/cvsrep/wrox/plip-app/README,v 1.4 2000/04/16 17:38:08 rick Exp

$

$Id: README,v 1.4 2000/04/16 17:38:08 rick Exp $

$Log: README,v $

Revision 1.4 2000/04/16 17:38:08 rick

Added keyword strings

$Name: $

$Revision: 1.4 $

$State: Exp $

System CVS automatycznie aktualizuje te słowa kluczowe po każdym pobraniu pliku, a więc nie ma potrzeby martwić się o ich poprawność.

Ogólnie mówiąc, warto uwidocznić przynajmniej jeden z tych napisów w ostatecznej skompilowanej wersji aplikacji, przyporządkowując go jakiejś zmiennej statycznej. Pozwoli to uniknąć usunięcia takich nieużywanych zmiennych przez kompilator dokonujący optymalizacji kodu. Autorzy sądzą, że najbardziej przydaje się wyświetlanie wersji programu łącznie z napisem $Id$. Nawet wówczas, gdy nie chcemy aby występował on w wersji skompilowanej, to warto przechowywać go w kodzie źródłowym jako komentarz. Polecamy strony podręcznika systemowego dla polecenia ident (z systemu RCS), które służy do wyszukiwania napisów w tym formacie w plikach skompilowanych.

Korekty, znaczniki i rozgałęzienia

Dotychczas jedynie wspomnieliśmy o korektach i rozgałęzieniach i pokazaliśmy kilka poleceń wykorzystujących znaczniki, nie precyzując dokładnie znaczenia tych pojęć. Uczynimy to teraz.

Korekty

Przy każdym zatwierdzaniu zmian w pliku w repozytorium CVS tworzona jest nowa korekta tego pliku. Przeważnie korekty mają kolejną numerację w postaci 1.1, 1.2, 1.3 itd. Można wprawdzie zmienić numer początkowy, co stanowi znaczny postęp w stosunku do RCS, ale w zasadzie w systemie CVS nie ma takiej potrzeby. Jak wkrótce zobaczymy, znaczniki stosowane w CVS dają znacznie więcej swobody niż numeracja wersji używana w RCS.

Jak widzieliśmy, w komunikatach generowanych przez CVS występują czasami odwołania do numerów gałęzi w postaci liczb oddzielonych kropkami oraz do numerów korekt mających postać dwóch liczb oddzielonych kropką. Może to być trochę mylące, ale dopóki nie używa się rozgałęzień, należy brać pod uwagę tylko numery korekt.

Znaczniki

Jeżeli wydajemy projekt składający się z wielu plików, to zazwyczaj każdy plik ma wiele korekt dokonywanych na różnym poziomie. Bardzo ważna jest więc możliwość przechwycenie nie tylko odpowiedniej wersji każdego pliku źródłowego wchodzącego w skład wydawanego projektu, ale także korekty o właściwym numerze. Można to sobie ułatwić stosując nazwane znaczniki odnoszące się do całego zestawu plików tworzących cały projekt, niezależnie od faktycznych numerów wersji tych plików.

Załóżmy, że chcemy w tej chwili wydać nasz projekt plip-app. Nie znajduje się on obecnie w najlepszym stanie, ale chcemy np. przekazać komuś polecenia SQL tworzące naszą bazę danych w celu umożliwienia mu dalszej pracy. Oczywiście, ponieważ jest jeszcze daleko do ukończenia projektu, to prawdopodobnie będziemy musieli zmieniać budowę tabel w bazie danych. Musimy więc odnotować, co udostępniamy innym osobom, aby w przyszłości móc je informować o dokonanych zmianach.

Mamy obecnie cztery pliki, ale nie wszystkie mają ten sam numer korekty. Pliki create_tables.sql i drop_tables_sql mają numer korekty 1.2, zaś pozostałe pliki mają numer 1.1. Oczywiście, przy czterech plikach w projekcie zachowanie kontroli jest bardzo proste, ale gdy liczba plików wynosi kilkadziesiąt i występują korekty o różnych numerach, to może to spowodować niemały kłopot.

Posłużymy się więc znacznikiem dodanym do projektu, który możemy później wykorzystać jako tekstową etykietę na równi z numerami korekt nadawanymi automatycznie przez system CVS. Do nadania znacznika służy polecenie cvs tag, które ma kilka opcji:

-b

Utworzenie rozgałęzienia (opiszemy to w następnym podrozdziale).

-c

Sprawdzenie, czy wszystkie zmiany w repozytorium zostały zatwierdzone. Jeśli tak nie jest, to polecenie utworzenia znacznika nie uda się.

-D <date>

Znacznik odnoszący się do korekt nie są starszych niż od podanej daty.

-d

Usunięcie znacznika. Należy tu postępować ostrożnie, ponieważ nie jest tworzony zapis historii modyfikacji znaczników i po ich usunięciu nie zostaje po nich żaden ślad.

-F

Wymuszona zmiana nazwy istniejącego znacznika, stosowana przy konflikcie nazw.

-r <rev>

Nadanie znacznika korektom o danym numerze (może się to odnosić także i do znacznika, choć nie wydaje się to bardzo użyteczne).

Oznaczmy więc aktualny stan naszego projektu gotowego do przekazania dla klienta.

$ cvs tag -c release-schema-to-wrox-01

cvs tag: Tagging .

T README

T create_tables.sql

T drop_tables.sql

T insert_data.sql

Takie polecenie spowoduje po prostu dodanie znacznika do każdego pliku w projekcie. Użyliśmy to opcji -c, aby sprawdzić, czy wszystkie zmiany zostały zatwierdzone, co jest bardzo dobrym zwyczajem.

Znacznik możemy zobaczyć przeglądając zapisy historii jednego z plików w logu :

$ cvs log -h create_tables.sql

RCS file: /usr/local/cvsrep/wrox/plip-app/create_tables.sql,v

Working file: create_tables.sql

head: 1.2

branch:

locks: strict

access list:

symbolic names:

release-schema-to-wrox-01: 1.2

start: 1.1.1.1

stixen: 1.1.1

keyword substitution: kv

total revisions: 3

=============================================================

Możemy teraz przekazać kopie plików naszemu klientowi i kontynuować pracę.

W celach demonstracyjnych zmienimy definicję niektórych pól typu CHAR na pola typu VARCHARS i zatwierdzimy zmiany w repozytorium. Klient może się zapytać o to, czy były wprowadzone jakieś modyfikacje od czasu otrzymania przez niego ostatniej wersji plików. Odpowiedź na to pytanie możemy uzyskać kilkoma sposobami. Najprościej jest przejrzeć zapis w logu za pomocą polecenia cvs log wyszukując nazwę naszego znacznika, a następnie za pomocą polecenia cvs diff odszukać wprowadzone zmiany. Ponieważ polecenie cvs diff działa globalnie na cały projekt, to nie musimy nawet podawać nazw plików, które nas interesują:

$ cvs diff -r release-schema-to-wrox-01

cvs diff: Diffing .

Index: create_tables.sql

================================================================

RCS file: /usr/local/cvsrep/wrox/plip-app/create_tables.sql,v

retriving revision 1.2

retriving revision 1.3

diff -r1.2 -r1.3

8,10c8,10

< fname CHAR(26),

< lname CHAR((26) NOT NULL,

house_flat_ref CHAR(26) NOT NULL,

---

> fname VARCHAR(26),

> lname VARCHAR(26) NOT NULL,

> house_flat_ref VARCHAR(26) NOT NULL,

60c60

< err_text CHAR(50)

---

> err_text VARCHAR(50)

Jak widać, CVS nie tylko rozpoznaje pliki, które zostały zmienione, ale także pokazuje wprowadzone zmiany używając standardowego formatu polecenia diff.

Możemy także przekazać kopię projektu w takim stanie, w jakim się on znajdował podczas oznaczania go określonym znacznikiem. Jest to bardzo proste, ponieważ pobieramy pliki z repozytorium za pomocą polecenia cvs checkout z opcją -r <znacznik>. Niestety, system CVS nie zawsze prawidłowo obsługuje prawa dostępu do plików i trzeba samemu się upewnić, czy prawo do zapisu w pobranych plikach ma grupa cvs-user.

Jeżeli tak nie jest, to trzeba zmienić ręcznie odpowiednie atrybuty pobranych plików używając polecenia chgrp -R cvs-user w katalogu /usr/local/cvs-rep. Czasami można także zauważyć, że uprawnienia do pliku nie są takie, jakie były ustawione podczas jego sprawdzania. Mamy nadzieję, że te drobne niedogodności zostaną usunięte w następnych wersjach CVS.

Załóżmy teraz, że istnieje inny użytkownik o nazwie neil, który chce pobrać z repozytorium pliki w takim samym stanie, w jakim były przekazane klientowi Wrox. Należy pamiętać o pobieraniu plików do pustego katalogu, bowiem będą one zastępować pliki już istniejące, co grozi przypadkową utratą danych:

$ cvs checkout -r release-schema-to-wrox-01 wrox/plip-app

cvs checkout: Updating wrox/plip-app

U wrox/plip-app/README

U wrox/plip-app/create_tables.sql

U wrox/plip-app/drop_tables.sql

U wrox/plip-app/insert_data.sql

Jeżeli sprawdzimy zawartość pliku create_tables.sql, to stwierdzimy, ze nie ma w nim ostatnio wprowadzonej zmiany typu pola na VARCHAR.

Przekazaliśmy użytkownikowi neil zmienną środowiskową CVSROOT, która wskazuje na nasze repozytorium. Można także użyć opcji -d w poleceniach CVS.

To jest w zasadzie wszystko, co można powiedzieć na temat podstawowego użycia znaczników w systemie CVS. Nie należy sądzić, że łatwość ich stosowania oznacza, iż nie są one ważne. Musimy pamiętać, że wskaźniki wyznaczają kolejne stabilne punkty w naszym projekcie.

Rozgałęzienia projektu

Czasami możemy sobie zażyczyć podziału projektu na dwie lub więcej wersji, które będą rozwijane niezależnie. Jako przykład może tu posłużyć wydanie projektu, dla którego trzeba utworzyć poprawki bez wprowadzania zmian przeznaczonych dla następnego wydania. Rozgałęzienie projektu pozwoli na niezależną pracę ze starymi i nowymi wersjami.

Ten problem można rozwiązać tworząc niezależne projekty: jeden dla starych wersji a drugi dla nowych. Oczywiście, musimy być absolutnie pewni, że poprawki błędów dokonane w starym wydaniu zostaną przeniesione do nowego wydania. CVS ułatwia automatyczne dołączanie poprawek ze starego do nowego wydania.

Załóżmy, że w wersji przekazanej naszemu klientowi musimy zmienić polecenia SQL niezależnie od postępu głównych prac w projekcie. Zamiast tworzenia prostej kopii plików źródłowych na wszelki wypadek, powinniśmy myśleć perspektywicznie i utworzyć rozgałęzienie używając opcji -b przy nadawaniu znacznika za pomocą polecenia cvs tag. Następnie, jeżeli programista będzie pobierał kopię roboczą plików oznaczonych tym znacznikiem, będzie pracował na danym rozgałęzieniu a nie na głównej kopii projektu.

Rozważmy zmiany wprowadzane w aplikacji podczas jej rozwoju. Jeśli korzystamy z systemu CVS, to mamy elegancko ponumerowane kolejne wersje, jak na poniższym rysunku:

Wydanie 1

Wydanie 2

1.1 1.2 1.3 1.4 1.5 1.6

Jeżeli jedni programiści kontynuują pracę nad kodem z wydania 1. a drudzy zajmują się wydaniem 2., to konieczne jest rozgałęzienie:

Wydanie 1 1.2.1 1.2.2 1.2.3

Wydanie 2

1.1 1.2 1.3 1.4 1.5 1.6

Mamy tu w rozgałęzieniu wersje 1.2.1, 1.2.2 itd., które są rozwijane niezależnie od głównego nurtu prac w postaci wersji 1.2, 1.3 itd.

Nie wszystko jest jednak stracone. Możemy zdecydować przemieszczając się wstecz, że nadany znacznik powinien być odgałęzieniem, a nie tylko prostym znacznikiem. Załóżmy, że neil chce rozpocząć prace nad czystą kopią projektu wydaną klientowi. Najprostszym sposobem uzyskania tego jest użycie polecenia cvs release usuwającego istniejącą kopię i następnie ponowne pobranie plików za pomocą polecenia cvs checkout -r release-schema-to-wrox-01 wrox/plip-app, dzięki czemu uzyskamy właściwą kopię.

Możemy teraz oznaczyć pobraną wersję jako rozgałęzienie, używając polecenia cvs tag.

$ cvs tag -b release-schema-to-wrox-01-branch

cvs tag: Tagging .

T README

t create_tables.sql

T drop_tables.sql

T insert_data.sql

W tym momencie musimy zacząć postępować ostrożnie. Oznaczyliśmy przed chwilą w repozytorium wszystkie pliki pobrane z katalogu (release-schema-to-wrox-01) jako należące do głównego wątku aplikacji. Nie mamy faktycznie bieżącej kopii roboczej tego rozgałęzienia — co może być pułapką dla nieuważnych.

W jaki sposób należy więc zmodyfikować kopię lokalną? Musimy ponownie pobrać bieżącą kopię, tak aby system CVS odnotował informację, że jest ona częścią rozgałęzienia. W tym celu najpierw zwolnimy istniejące pliki:

$ cvs release -d wrox/plip-app

Teraz możemy zrobić kopię tej kopii rozgałęzienia, które oznaczyliśmy:

$ cvs checkout -r release-schema-to-wrox-01-branch wrox/plip-app

cvs checkout: Updating wrox/plip-app

U wrox/plip-app/README

U wrox/plip-app/create_tables.sql

U wrox/plip-app/drop_tables.sql

U wrox/plip-app/insert_data.sql

Może się zdarzyć, że w tym momencie zamiast różnych komunikatów pojawi się komunikat o błędzie spowodowanym niewłaściwymi uprawnieniami do pliku val-tags. Oznacza to, że jeden z użytkowników tworząc jakieś znaczniki spowodował utworzenie w obszarze sterującym repozytorium pliku val-tags. Jeżeli pierwotną grupą, do której należy ten użytkownik nie jest cvs-user, to byłoby lepiej aby utworzone przez niego pliki nie mogły być modyfikowane przez innych członków tej grupy. Administrator CVS powinien wówczas odpowiednio zmodyfikować uprawnienia.

Trzeba więc przejść do innego katalogu roboczego w repozytorium CVS i skorygować uprawnienia właścicielskie (dla cvs-user) oraz zmienić uprawnienia do pliku val-tags na takie, jakie mają inne pliki w katalogu CVSROOT.

Mamy więc kopię lokalną projektu wydanego klientowi, która jest odgałęzieniem głównego wątku aplikacji. Znacznik tego odgałęzienia można zobaczyć za pomocą polecenia cvs status. Jeżeli użytkownik rick pracujący z głównym wątkiem wyda takie polecenia, to zobaczy:

$ cvs status create_tables.sql

File create_tables.sql Status: Up-to-date

Working revision: 1.3 Sat Apr 15 22:59:50 2000

Repository revision: 1.3 /usr/local/cvsrep/wrox/plip-

app/create_tables.sql,v

Sticky Tag: (none)

Sticky Date: (none)

Sticky Options: (none)

Jeśli to samo polecenie wyda użytkownika neil, pracujący w odgałęzieniu projektu Wrox, to otrzymamy:

File: create_tables.sql Status: Up-to-date

Working revision: 1.2 Sat Apr 15 21:15:08 2000

Repository revision: 1.2 /usr/local/cvsrep/wrox/plip-

app/create_tables.sql,v

Sticky Tag: release-schema-to-wrox-01-branch (branch: 1.2.2)

Sticky Date: (none)

Sticky Options: (none)

Widać więc, że obydwaj użytkownicy pracują z różnymi wersjami tego samego pliku. Wiersz Sticky Tag oznacza, że kopia lokalna jest wyróżniona jako część oznakowanego wydania. Określenie „Sticky” (czyli „przyklejany”) oznacza, że system CVS będzie w kolejnych poleceniach automatycznie uwzględniał status tego pliku. Możemy się o tym przekonać wprowadzając w nim niewielką zmianę i wywołując polecenie cvs diff:

$ cvs diff create_tables.sql

Index: create_tables.sql

=================================================================

RCS file: /usr/local/cvsrep/wrox/plip-app/create_tables.sql,v

retrieving revision 1.2

diff -r1.2 create_tables.sql

29a30

> actor3 CHAR(51),

60c61

< err_text CHAR(50)

---

> err_text CHAR(75)

Jak stąd wynika, polecenie cvs diff automatycznie rozróżnia fakt, że pracujemy w odgałęzieniu i wyświetla różnice odniesione do plików w repozytorium wchodzących w skład tego odgałęzienia, a nie odniesione do głównego wątku projektu. Jeżeli ręcznie porównamy zawartość pliku, z którym pracuje użytkownik neil, z plikiem, z którym pracuje rick, to stwierdzimy, że różnice są większe:

$ diff ~rick/wrox/plip-app/create_tables.sql create_tables.sql

8,10c8,10

< fname VARCHAR(26),

< lname VARCHAR(26) NOT NULL,

< house_flat_ref VARCHAR(26) NOT NULL,

---

> fname CHAR(26),

> lname CHAR(26) NOT NULL,

> house_flat_ref CHAR(26) NOT NULL,

29a30

> actor3 CHAR(51),

60c61

< err_text VARCHAR(50)

---

> err_text CHAR(75)

Niech użytkownik neil zmieni w celach demonstracyjnych zawartość pliku insert_data.sql, który nie jest zmieniony przez użytkownika rick. Wprowadźmy te zmiany do repozytorium za pomocą polecenia cvs commit. Zobaczymy, że zmiany dotyczą odgałęzienia (ze względu na „przyklejony” znacznik) i wyglądają inaczej gdy neil sprawdza je w wersji głównej:

$ cvs commit -m"Fix minor bugs in Wrox version"

cvs commit: Examining .

Checking in create_tables.sql;

/usr/local/cvsrep/wrox/plip-app/create_tables.sql,v <-- create_tables.sql

new revision: 1.2.2.1; previous revision: 1.2

done

Checking in insert_data.sql;

/usr/local/cvsrep/wrox/plip-app/insert_data.sql,v <-- insert_data.sql

new revision: 1.1.1.1.2.1; previous revision: 1.1.1.1

done

Jak widać, system CVS utworzył nową wersję z zagnieżdżonym numerem. W tym momencie wystarczy stwierdzić, że CVS nie ogranicza się do pojedynczych odgałęzień. Można tworzyć kilka różnych odgałęzień głównego wątku a nawet odgałęzienia w tych odgałęzieniach. Nie jest to jednak zalecane rozwiązanie, mimo że system na nie pozwala. Należy dobrze się zastanowić przed utworzeniem odgałęzienia i bardzo ostrożnie podchodzić do każdej sugestii mówiącej o posiadaniu większej liczby aktywnych wątku projektu.

Możemy teraz przekazać klientowi niewielkie zmiany wprowadzone do projektu i zachować je oddzielnie od reszty głównego wątku.

Załóżmy, że wszystko jest gotowe na połączenie odgałęzienia z głównym wątkiem. Odgałęzienie zawierające poprawki błędów, które powinny znaleźć się także w wydaniu 2., musimy włączyć ponownie w główny wątek aplikacji.

Prace w odgałęzieniu mogą być kontynuowane lub zakończone

Wydanie 1 1.2.1 1.2.2 1.2.3

Wydanie 2

połączenie

1.1 1.2 1.3 1.4 1.5 1.6

Użytkownik rick najpierw musi poznać status projektu za pomocą polecenia cvs status -v. Opcja -v jest potrzebna dlatego, że zwykłe polecenie cvs status nie podaje informacji o odgałęzieniach. Ponieważ generowane wówczas komunikaty są bardzo obszerne, to niżej pokazujemy tylko ich niewielki fragment dający pojęcie o całości:

File: create_tables.sql Status: Up-to-date

Working revision: 1.3 Sat Apr 15 22:59:50 2000

Repository revision: 1.3 /usr/local/cvsrep/wrox/plip-

app/create_tables.sql,v

Sticky Tag: (none)

Sticky Date: (none)

Sticky Options: (none)

Existing Tags:

release-schema-to-wrox-01-branch (branch: 1.2.2)

release-schema-to-wrox-01 (revision: 1.2)

start (revision: 1.1.1.1)

stixen (branch: 1.1.1)

Ponowne łączenie rozdzielonych wątków może sprawiać kłopoty, ponieważ zmiany w pliku create_tables.sql były wprowadzane w obydwu wersjach i, co gorsza, niektóre z nich wykluczają się wzajemnie. Widzieliśmy np. w wyniku wcześniejszego polecenia diff:

60c61

< err_text VARCHAR(50)

---

> err_text CHAR(75)

Która wersja jest więc poprawna? Nie ma automatycznego sposobu rozsądzenia problemów tego rodzaju. CVS wspomaga jednak automatyczne łączenie innych zmian, które nie są tak dowolne.

Możemy więc, nie martwiąc się zupełnie o bezpieczeństwo projektu, pozwolić na automatyczne łączenie dwóch wątków aplikacji ponieważ mamy dwa zabezpieczenia. Po pierwsze — CVS nie dołączy zmian, jeżeli występuje wyraźny konflikt, a po drugie — zawsze przegląda się zmiany w odniesieniu do głównej wersji przechowywanej w repozytorium. Trzeba tu jednak podkreślić, że takie operacje powinny być przeprowadzane ze szczególną ostrożnością oraz że przed ich wykonaniem zarówno główny wątek, jak i odgałęzienie powinny zostać zatwierdzone w repozytorium.

Do połączenia odgałęzień użyjemy nowego polecenia cvs update, które jest często używane jeśli w projekcie bierze udział wielu użytkowników. Połączenie dwóch wątków odbywa się po użyciu opcji -j i po podaniu znacznika wątku, wyróżniającego odgałęzienie, które ma być dołączone do bieżącego katalogu z projektem.

Użytkownik rick (pobierający główny wątek jako ostatni) używa polecenia cvs update do ponownego włączenia odgałęzienia z bieżącą wersją:

$ cvs update -j release-schema-to-wrox-01-branch

cvs update: Updating .

RCS file: /usr/local/cvsrep/wrox/plip-app/create_tables.sql,v

retriving revision 1.2

retriving revision 1.2.2.1

Merging differences between 1.2 and 1.2.2.1 into create_tables.sql

rcsmerge: warning: conflicts during merge

RCS file: /usr/local/cvsrep/wrox/plip-app/insert_data.sql,v

retriving revision 1.1.1.1

retriving revision 1.1.1.1.2.1

Merging differences between 1.1.1.1 and 1.1.1.1.2.1 into insert_data.sql

Jak widać, CVS ostrzega o konflikcie w pliku create_tables.sql. Powinniśmy się tego spodziewać, ponieważ obydwaj użytkownicy wprowadzili w tym pliku niezależne zmiany, z których przynajmniej dwie wykluczają się wzajemnie.

Mając podgląd wyników łączenia możemy otworzyć plik create_tables.sql w edytorze. Zobaczymy tam, że tylko jeden fragment pliku się nie zgadza:

create table errtext (

err_code INT,

<<<<<<< create_tables.sql

err_text VARCHAR(50)

=======

err_text CHAR(75)

>>>>>>> 1.2.2.1

);

Pozostałe zmiany zostały dołączone z niezwykłą dokładnością. Musimy tylko zmodyfikować plik create_tables.sql usuwając konflikt, tak aby plik w głównym wątku zawierał pożądaną treść. Ponieważ mamy wskazane niezgodne ze sobą miejsca w obydwu plikach źródłowych, to zadanie jest bardzo łatwe do wykonania. Po ponownym sprawdzeniu zmian (dla pewności) za pomocą polecenia cvs diff, możemy ostatecznie zatwierdzić zawartość repozytorium:

$ cvs commit -m"Merge changes from release-schema-to-wrox-01-branch to mainstream"

Checking in create_tables.sql;

/usr/local/cvsrep/wrox/plip-app/create_tables.sql,v <-- create_tables.sql

new revision: 1.4; previous revision: 1.3

done

Checking in insert_data.sql;

/usr/local/cvsrep/wrox/plip-app/insert_data.sql,v <-- insert_data.sql

new revision: 1.2; previous revision: 1.1

done

Zawsze należy przestrzegać zasady, że dołączenie odgałęzienia do repozytorium odbywa się jednoetapowo. Nie należy próbować wprowadzania dodatkowych zmian „chyłkiem”. Warto także dodać w tym momencie znacznik zarówno do głównego wątku, jak i do odgałęzienia, co ułatwi ich przyszłe śledzenie.

Po tych wszystkich operacjach włączyliśmy więc wprowadzone zmiany do głównego wątku aplikacji i ponownie możemy zająć się jednym zestawem plików źródłowych.

CVS dla wielu użytkowników

Omawiając odgałęzienie wspomnieliśmy o niektórych aspektach użycia CVS w środowisku wielu użytkowników. W tym podrozdziale omówimy te zagadnienia nieco szerzej.

Większość narzędzi do kontroli kodu źródłowego jest przeznaczona dla jednego użytkownika i blokuje dostęp do źródeł dla innych użytkowników. Zaledwie kilka z nich umożliwia opcjonalnie pracę zespołową. W systemie CVS zastosowano zupełnie odmienne podejście — założono, że nad projektem pracuje wielu programistów jednocześnie i że będą oni zmieniać praktycznie ten sam plik źródłowy.

Problemy powstające przy zmianach kodu przez wielu użytkowników są podobne do tych, które spotyka się przy dołączaniu w dowolnym czasie odgałęzionych wątków projektu prowadzonych przez wiele osób.

Istnieją dwa sposoby pracy wielu użytkowników w systemie CVS, wybierane zależnie od liczby użytkowników i stopnia porozumienia między nimi. Jeśli liczba użytkowników wspólnie użytkujących pliki jest niewielka i pracują oni blisko siebie, to nie wymaga się od systemu CVS jakichś specjalnych działań — wystarczy po prostu praca zespołowa. Jeżeli jednak użytkowników jest wielu i nie mogą oni ściśle ze sobą współpracować, to system CVS może wykonać większą część zadań administracyjnych umożliwiając programistom obserwację tego, kto co zmienia. Nie ma tu odmiennych trybów pracy CVS, ale nieco odmienny sposób wykorzystania tego systemu do osiągnięcia tych samych celów.

Praca zespołowa

Przy takim sposobie pracy użytkownicy korzystają z systemu CVS podobnie jak pojedynczy użytkownik, z tym wyjątkiem, że przy aktualizacji swoich kopii roboczych za pomocą polecenia cvs update wprowadzają oni także zmiany dokonane przez innych.

Najważniejsze opcje polecenia cvs update są następujące:

-A

Usunięcie dowolnej opcji „przyklejanej”, umożliwiające pracę tak jak ze świeżą kopią głównego projektu.

-D <date>

Aktualizacja wersji plików począwszy od określonej daty.

-d

Odtworzenie brakujących katalogów.

-j <rev>

Połączenie dwóch odgałęzień w jeden wątek.

-p

Zapis plików na standardowe wyjście zamiast do katalogu.

-r <rev>

Aktualizacja plików zgodnie z określonym numerem korekty lub znacznikiem.

Załóżmy, że są dwaj programiści rick i neil, którzy pobrali kopie pliku README i obydwaj redagują ten plik. Dodatkowo rick zmienia plik create_tables.sql, a neil zmienia plik drop_tables.sql.

Na tym etapie pracy żaden z nich nie widzi zmian wprowadzanych przez drugiego, ponieważ w repozytorium żadne zmiany nie zostały jeszcze zatwierdzone. Załóżmy, że neil zatwierdza wprowadzone przez siebie zmiany jako pierwszy. Jego poprawki są zapisywane w repozytorium bez żadnych kłopotów, ponieważ wszystko działa na zasadzie „kto pierwszy, ten lepszy”. Jeżeli rick będzie gotowy do zatwierdzenia swoich zmian, to sprawdzi, czy nikt nie modyfikuje jego plików uruchamiając polecenie cvs status. Zobaczy wówczas następujący wynik:

File: README Status: Needs Merge

Working revision: 1.1.1.1 Sat Apr 15 16:13:02 2000

Repository revision:1.2 /usr/local/cvsrep/wrox/plip-app/README,v

Sticky Tag: (none)

Sticky Date: (none)

Sticky Options: (none)

=====================================================================

File: create_tables.sqlStatus: Locally Modified

Working revision: 1.4 Sun Apr 16 12:21:34 2000

Repository revision:1.4 /usr/local/cvsrep/wrox/plip-app/create_tables.sql,v

Sticky Tag: (none)

Sticky Date: (none)

Sticky Options: (none)

=====================================================================

File: drop_tables.sql Status: Needs Patch

Working revision: 1.2 Sat Apr 15 21:15:08 2000

Repository revision:1.3 /usr/local/cvsrep/wrox/plip-app/drop_tables.sql,v

Sticky Tag: (none)

Sticky Date: (none)

Sticky Options: (none)

=====================================================================

File: insert_data.sql Status: Up-to-date

Working revision: 1.2 Sun Apr 16 12:21:34 2000

Repository revision:1.2 /usr/local/cvsrep/wrox/plip-app/insert_data.sql,v

Sticky Tag: (none)

Sticky Date: (none)

Sticky Options: (none)

Na podstawie tych informacji rick może się zorientować, że:

Może się to wydawać nieco zagmatwane, ale jak już wcześniej widzieliśmy, CVS dobrze sobie radzi z automatycznym sortowaniem i pokazywaniem niezgodności. Pierwszym krokiem jest więc zezwolenie na wprowadzenie modyfikacji lokalnych plików przez sam system:

$ cvs update

cvs update: Updating .

RCS file: /usr/local/cvsrep/wrox/plip-app/README,v

retriving revision 1.1.1.1

retriving revision 1.2

Merging differences between 1.1.1.1 and 1.2 into README

rcsmerge: warning: conflicts during merge

cvs update: conflicts found in README

C README

M create_tables.sql

U drop_tables.sql

Widzimy, że CVS informuje o konieczności ręcznej modyfikacji pliku README w celu rozwiązania konfliktu, że do pliku create_tables.sql zmiany zostały wprowadzone automatycznie oraz że lokalna kopia pliku drop_tables.sql została zastąpiona aktualną kopią z repozytorium.

Po ręcznej edycji pliku README i zaznaczonych w nim wykluczających się zmian (tak jak to się działo przy opisanym wcześniej dołączaniu odgałęzienia do wątku głównego) użytkownik rick może użyć polecenia cvs diff w celu sprawdzenia, czy zadowalają go wprowadzone modyfikacje, a następnie za pomocą polecenia cvs commit zatwierdzić zmiany w repozytorium. W praktyce warto również przeprowadzić kilka testów dla uzyskania pewności, że wprowadzone zmiany rzeczywiście dają to, o co chodzi. System CVS działa wprawdzie dobrze, ale nie jest w stanie rozpoznać intencji i logiki programisty, a więc obserwacja zmian jest pożądana.

Praca ze śledzeniem

Istnieje zestaw zaawansowanych poleceń CVS służących do śledzenia, które umożliwiają powiadamianie zarejestrowanych użytkowników (zwykle za pomocą poczty elektronicznej) o edycji i modyfikacji plików w repozytorium. Taki tryb pracy jest bez wątpienia bardzo zaawansowany i rzadko spotykany, a więc tutaj nie będziemy się nim szerzej zajmować. Informacje te trzeba zdobyć we własnym zakresie korzystając z danych bibliograficznych umieszczonych na końcu rozdziału.

Dodatkowa zabawa z CVS

Istnieje jeszcze wiele innych poleceń i właściwości systemu CVS, o których tutaj nie wspomnieliśmy. Poniżej omówimy te, z którymi należy się wcześniej zapoznać.

Pliki binarne

System CVS jest bardzo dobry — nie ma jednak rzeczy doskonałych i dlatego nie obsługuje on obecnie tak dobrze plików binarnych, jak mógłby je obsługiwać. CVS można wykorzystać do przechowywania plików binarnych, ale informację o tym należy do niego wprowadzić ręcznie.

Można to uczynić w dwojaki sposób: używając opcji -kb w poleceniu cvs add (jak już to widzieliśmy wcześniej) lub użyć polecenia cvs admin -kb nazwa_pliku. Niestety, obydwa polecenia działają tylko na pliki w repozytorium, a nie na ich kopie lokalne, najlepiej więc odnowić zwartość katalogu lokalnego pobierając świeżą kopię do oczyszczonego katalogu.

Obecnie CVS nie może pokazywać różnic w plikach binarnych za pomocą polecenia diff.

Poprawianie błędnych adnotacji

Ludzie są omylni i czasem zdarza się im wstawić błędną informację do logu podczas zmian w repozytorium. Taki dość często spotykany błąd można jednak naprawić. Aby zmienić komunikat w logu dotyczący jakiejś specyficznej korekty pliku, należy użyć polecenia:

$ cvs admin -mrev:"New message"

Komunikat ten zastąpi komunikat wprowadzony poprzednio, po którym zaginie wszelki ślad, należy więc ostrożnie korzystać z tej właściwości.

Sieciowy dostęp do CVS

Jedną z najbardziej użytecznych właściwości systemu CVS jest jego zdolność do pracy w sieci. Można udostępniać repozytorium w sieci na kilka sposobów, ale najpopularniejszą metodą jest pserver (nazwa pochodzi od słów „password authenticating server”).

Usługi CVS korzystają zazwyczaj z portu o numerze 2401. Ten numer można zmienić w razie potrzeby, ale w praktyce nie jest to stosowane. Ponieważ uruchomienie usług CVS nie obniża znacząco wydajności komputera przy wykonywaniu zdalnych poleceń tego systemu, to najlepiej użyć do tego celu demona inetd, który będzie monitorował port i uruchamiał odpowiednią usługę na żądanie.

Najpierw należy sprawdzić, czy usługi CVS są odpowiednio zdefiniowane i czy korzystają ze standardowego portu. W pliku /etc/services powinien się znajdować następujący wpis:

Cvspserver 2401/tcp

Jeżeli takiego wpisu nie ma, to należy go dodać. Może się okazać, że istnieje wpis dla UDP, ale normalnie system CVS korzysta z TCP. Istniejącego wpisu dla UDP nie należy usuwać.

Następnie trzeba zmodyfikować plik konfiguracyjny demona inetd, nakazując mu uruchamianie serwera CVS po odebraniu wywołania żądającego dostępu do usług CVS.

W pliku /etc/inetd.conf musimy dodać następujący wiersz (cały tekst musi być podany w jednym wierszu):

cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/usr/local/cvsrep

pserver

Należy sprawdzić, czy podana jest prawidłowa ścieżka do programu CVS oraz ścieżka do repozytorium, które ma być udostępnione w sieci. Opcja allow-root informuje serwer CVS, że zdalni użytkownicy są uprawnieni do korzystania z podanego repozytorium. Można użyć wielu opcji allow-root jeśli zachodzi taka konieczność.

Po tych operacjach zmuszamy inetd do ponownego odczytu pliku konfiguracyjnego:

# killall -HUP inetd

Możemy teraz sprawdzić, czy usługi CVS są dostępne, łącząc się przez telnet z podanym portem. Nie uzyskamy wprawdzie w taki sposób dostępu do repozytorium, ale jest to najprostsza metoda sprawdzenia poprawności działania serwera.

$ telnet localhost 2401

Po kilkakrotnym naciśnięciu klawisza Return powinniśmy zobaczyć coś takiego:

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

cvs [pserver aborted]: bad auth protocol start:

Connection closed by foreign host.

Wiemy teraz, że serwer CVS jest dostępny na porcie 2401.

Aby dostać się w sposób zdalny do repozytorium trzeba użyć polecenia o specjalnej postaci:

:pserver:uzytkownik@oddalony-komputer:sciezka-do-repozytorium polecenie

Spróbujmy teraz zalogować się przez sieć jako rick na komputerze gw1:

$ cvs -d :pserver:rick@gw1:/usr/local/cvsrep login

(Logging in to rick@gw1)

CVS password:

$

Od tego momentu można wydawać poprzez sieć polecenia CVS odnoszące się do oddalonego repozytorium. CVS przechowuje hasła użytkowników w pliku ~/.cvspass, a więc nie ma potrzeby ponownego wpisywania hasła przed wylogowaniem. Czyż nie jest to proste? Niestety, taki sposób postępowania ma kilka wad, z których najważniejszą jest obniżenie poziomu bezpieczeństwa serwera. Użytkownicy logują się z sieci korzystając ze swoich normalnych haseł, a metoda przekazywania haseł stosowana przez pserver nie jest zbyt bezpieczna (mimo, że nie jest tu stosowane przesyłanie haseł w postaci niezakodowanej). Możemy poprawić bezpieczeństwo systemu oddzielając nazwy użytkowników korzystających z systemu CVS od nazw rzeczywistych użytkowników oraz podając listę użytkowników uprawnionych do zapisu i odczytu w repozytorium.

Załóżmy więc, że chcemy zezwolić użytkownikowi rick na dostęp do repozytorium, lecz pod inną nazwą i z innym hasłem. Musimy w tym celu utworzyć plik o nazwie passwd w katalogu /usr/local/cvsrep/CVSROOT.

Każdy wpis w tym pliku zawiera nazwę użytkownika stosowaną w systemie CVS, zaszyfrowane hasło i rzeczywistą nazwę tego użytkownika używaną przy logowaniu na komputerze. Obecnie nie ma prostego sposobu generacji zaszyfrowanych haseł z wiersza poleceń w systemie Linux, a więc można spróbować zmienić hasło czasowo na takie, które ma być użyte w systemie CVS i następnie skopiować je z pliku /etc/shadow (przy założeniu, że tam są przechowywane hasła dostępu do komputera) do pliku CVSROOT/passwd.

Żądany wpis w tym pliku dla użytkownika rick, wykorzystywany tylko w systemie CVS, może mieć następującą postać:

rick-cvs:HhyGFguuGuyiuhgiuGiuiuUhh:rick

Od tego momentu rick może zalogować się zdalnie na serwer CVS używając nazwy rick-cvs i hasła innego niż przy normalnym logowaniu do komputera. Jeśli trzeba zmienić hasło zdalnego użytkownika bez zmiany nazwy używanej przy logowaniu, to należy po prostu pominąć w tym wpisie końcową rzeczywistą nazwę użytkownika a CVS sam zmieni go na jedną z nazw użytkowników, którzy domyślnie mają pozwolenie na logowanie.

W taki sam sposób można umożliwić anonimowy dostęp do serwera CVS, tworząc rzeczywistą nazwę użytkownika komputera i odwzorowując ją w pliku CVSROOT/passwd w nazwie anonymous używanej przy logowaniu do CVS.

Oczywiście, nie można zezwalać na anonimowy zapis w repozytorium. W tym celu należy utworzyć listę użytkowników mających faktycznie uprawnienia do zdalnego zapisu i odczytu repozytorium. Jest proste, bowiem w katalogu CVSROOT należy utworzyć dwa pliki: jeden o nazwie readers i drugi o nazwie writers. Plik readers powinien zawierać nazwy użytkowników uprawnionych tylko do odczytu, zaś plik writers — nazwy użytkowników uprawnionych do zapisu. Ponieważ sama obecność pliku writers automatycznie oznacza blokadę zapisu dla użytkowników, którzy nie są do niego wpisani, to należy zawsze pamiętać o jego utworzeniu. Obydwa pliki mają prostą strukturę wierszową, a w każdym wierszu podawana jest nazwa użytkownika stosowana w systemie CVS. Jeżeli chcemy np. ograniczyć uprawnienia użytkownikom neil i anonymous, zezwalając im tylko na odczyt, zaś rick ma być uprawniony także do zapisu, to plik readers powinien mieć następującą zawartość:

neil

anonymous

W pliku writers należy wówczas wpisać:

rick

Klienty CVS z interfejsem graficznym

Do tej pory mówiliśmy jedynie o lokalnym i sieciowym korzystaniu z systemu CVS za pomocą wiersza poleceń. Obecnie istnieje już kilka klientów wyposażonych w interfejs graficzny. Jako przykład można podać interfejs Tk do systemu CVS, który można znaleźć pod adresem http://tkcvs.sourceforge.net/

Rysunek

Ponieważ system CVS może działać w sieci, to użytkownicy mający do niego dostęp nie muszą korzystać z systemu operacyjnego UNIX lub Linux. Powstał więc program WinCVS dostępny pod adresem http://www.wincvs.org/

Rysunek

Wyjątkową przenośnością charakteryzuje się klient napisany w języku Java, który znajduje się pod adresem http://www.jcvs.org/

Rysunek

Całkiem interesujące wydaje się korzystanie z systemu CVS poprzez przeglądarkę WWW. Tego klienta można znaleźć pod adresem http://stud.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi/

Materiały źródłowe

W Internecie istnieje wiele materiałów źródłowych dotyczących CVS, a kilka z nich prawdopodobnie jest już zainstalowanych na komputerze Czytelnika.

Najpierw należy zapoznać się ze stronami podręcznika systemowego man cvs lub informacjami podawanymi przez info cvs. Jeśli to się nie uda, to należy zajrzeć do /usr/doc/cvs-<numer wersji>, gdzie najprawdopodobniej znajduje się więcej dokumentów na ten temat.

Dobrym punktem wyjścia do poszukiwań na stronach internetowych mogą być strony projektu GNU pod adresem: http://www.gnu.org/software/cvs/cvs.html.

Adres http://www.cyclic.com jest także dobrym punktem wyjściowym. Należy zapoznać się zwłaszcza z doskonałym dokumentem znanym jako „Cederqvist” (od nazwiska autora Pera Cederqvista). Lista interfejsów użytkownika, które można wykorzystać w systemie CVS podana jest pod adresem http://www.sourcegear.com/CVS/Dev/interface.

Pod adresem: http://goanna.cs.rmit.edu.au/~lukem/papers/3rdparty-and-cvs.html znajduje się interesujący artykuł dotyczący zarządzania cudzym kodem źródłowym za pomocą CVS napisany przez Luke'a Mewburna.

Jedną z książek, do której na pewno warto zajrzeć, jest Open Source Development with CVS Karla Fogela (Coriolis, ISBN 1-57610-490-7). Pewne fragmenty tej książki są dostępne także w sieci — należy zajrzeć na stronę WWW wydawnictwa Coriolis pod adres: www.coriolis.com.

Podsumowanie

W tym rozdziale omówiliśmy sposób korzystania z systemu CVS, czyli z wydajnego, bezpłatnego narzędzia służącego do śledzenia zmian kodu podczas tworzenia oprogramowania. Obsługa wielu użytkowników i dostępu przez sieć powoduje, że system CVS jest wybierany przez wielu programistów jako podstawowe narzędzie do zarządzania wersjami kodu źródłowego.

Omówiliśmy sposób konfiguracji i korzystania z systemu CVS przez pojedynczego użytkownika i przez wielu użytkowników łączących się przez sieć.

Wymieniliśmy także kilka klientów z interfejsem graficznym obsługującym CVS.

Ponieważ w systemie CVS dostępnych jest wiele poleceń, to podajemy tu krótkie zestawienie poleceń stosowanych najczęściej:

add

Dodanie nowego pliku lub katalogu do repozytorium.

admin

Interfejs administratora dla rcs.

checkout

Pobranie kodów źródłowych do edycji.

commit

Zatwierdzenie plików w repozytorium.

diff

Pokazanie różnic między korektami.

history

Pokazanie historii dostępu do repozytorium.

init

Utworzenie nowego repozytorium CVS (jeśli jeszcze nie istnieje).

log

Wyświetlenie informacji o historii plików.

release

Wydanie (uwolnienie) modułu oznaczające, że nie jest on już używany.

remove

Usuwanie wpisu z repozytorium.

status

Wyświetlenie informacji o statusie pobranych plików.

tag

Dodanie symbolicznego znacznika do pobranych wersji plików.

update

Modyfikacja wątku roboczego synchronizująca jego zawartość z repozytorium.

Dodatkową pomoc na temat dowolnego z powyższych poleceń można uzyskać używając polecenia cvs -H <polecenie>.

Polecenia CVS mają zawsze następującą składnię:

cvs opcja-ogólna polecenie opcja-polecenia [nazwy-plików]

Opcje ogólne, dostępne dla większości poleceń CVS, są następujące:

-d <repository>

Określanie używanego repozytorium.

-e <editor>

Określanie używanego edytora.

--help, -H

Wyświetlenie informacji pomocniczych o danym poleceniu.

-n

Brak działania.

-q, -Q

Brak komunikatów.

-t

Śledzenie działań.

-v, --version

Wyświetlenie wersji CVS.

-z <level>

Stopień kompresji używany podczas dostępu z sieci.

23 Część I Podstawy obsługi systemu WhizBang (Nagłówek strony)

23 F:\helion\R-02-t.doc

prop. klientów



Wyszukiwarka