CVS

PLD Team

1999.11.24

Abstrakt

Narzędzie pracy grupowej powszechnie stosowane w projektach Open Source.


Spis treści

Rozdział 1. Concurrent Versioning System (CVS)

Doskonałe wprowadzenie do obsługi CVS, jednego z podstawowych narzędzi wykorzystywanych przy tworzeniu PLD.

<authorblurb>

Jacek Jankowski, Marcin Kowalczyk <qrczak@pld.org.pl>, Tomasz Krysiński, Wersja texinfo - Arkadiusz Miśkiewicz <misiek@pld.org.pl>

</authorblurb>

1.1. Co to jest system kontroli wersji?

CVS jest narzędziem pomagającym w organizacji tworzenia projektu, zwłaszcza przez wiele osób.

CVS pamięta historię zmian. Pozwala m.in. dotrzeć do poprzednich wersji każdego pliku, porównywać se sobą różne wersje, tworzyć odgałęzienia w rozwoju modułu i nanosić na jedną wersję zmiany powstałe niezależnie od siebie albo powstałe w innych wersjach.

1.2. Zasady pracy CVS

Wszystkie pliki projektu są trzymane w jednym miejscu, w tzw. repozytorium (repository). Użytkownik najpierw pobiera fragment z repozytorium do swojego lokalnego katalogu. Po wprowadzeniu w nim zmian może wysłać poprawki z powrotem do repozytorium, żeby stały się dostępne dla innych.

Jeśli w międzyczasie ktoś inny zmienił coś w tych samych plikach co my, jesteśmy zmuszeni do pogodzenia naszych poprawek z jego poprawkami zanim uda nam się wysłać nasze. Jeśli poprawki dotyczą nienakładających się fragmentów plików, CVS potrafi zrobić to automatycznie. W trudniejszych przypadkach CVS zaznacza miejsca konfliktów -- musimy je jakoś rozwiązać, żeby wysłać zmiany do repozytorium.

Każdy plik w repozytorium ma przypisany numer rewizji (revision). Kiedy wysyłamy poprawioną wersję pliku, zawsze tworzona jest nowa rewizja, a poprzednie pozostają bez zmian.

Numery rewizji idą niezależnie dla każdego pliku. Żeby zaznaczyć, że dany zbiór plików w konkretnych rewizjach stanowi wersję pakietu jako całości, albo żeby dla innych potrzeb związać ze sobą rewizje różnych plików, możemy nadać danemu zbiorowi plików o ustalonych rewizjach symboliczną nazwę (tag). Takie nazwy mogą być potem używane zamiast numerów rewizji.

Podstawowym programem pakietu CVS jest program o nazwie cvs. Wszystkie polecenia wydajemy przez niego. Polecenie ma ogólną postać następującą:

cvs [-opcje ogólne] komenda [-opcje danej komendy] [argumenty]

Dobra dokumentacja jest w dystrybucji CVS (info cvs).

1.3. Pobranie plików z repozytorium

Do pobrania plików służy komenda `checkout', w skrócie `co' albo `get'. Na przykład:

	  [qrczak ~]$ cvs -z9 get prezentacja
	  cvs checkout: Updating prezentacja
	  U prezentacja/cvs.tex
	  U prezentacja/cvs1.tex
	  [qrczak ~]$ cd prezentacja
	  [qrczak ~/prezentacja]$ ls -l
	  razem 5
	  drwxr-xr-x  2 qrczak  bin  1024 Mar 10 19:32 CVS
	  -rw-r--r--  1 qrczak  bin   545 Mar 10 19:22 cvs.tex
	  -rw-r--r--  1 qrczak  bin  2287 Mar 10 19:32 cvs1.tex

Możemy teraz oglądać i edytować pliki. Katalog CVS zawiera kontrolne informacje CVSa i nie ma potrzeby do niego zaglądać.

Opcja -z9 oznacza kompresję transmisji, co jest przydatne w przypadku zdalnego repozytorium.

1.4. Wysłanie poprawionych wersji

Kiedy uznamy, że wypada ogłosić repozytorium nasze poprawki, używamy komendy commit, w skrócie ci:

	  [qrczak ~/prezentacja]$ cvs commit
	  cvs commit: Examining .

W tym przypadku nie podałem nazwy pliku, więc domyślnie pod uwagę został wzięty bieżący katalog. CVS zapisał sobie, skąd on pochodzi, w katalogu CVS. Teraz CVS otwiera nam edytor, w którym musimy opisać krótko poprawki, które nanieśliśmy. (Nasz ulubiony edytor powinniśmy określić w zmiennej środowiskowej $EDITOR albo $CVSEDITOR.)

Checking in cvs1.tex;
/home/qrczak/cvsroot/prezentacja/cvs1.tex,v  <--  cvs1.tex
new revision: 1.4; previous revision: 1.3
done

Zamiast wpisywania opisu interakcyjnie, możemy podać go w ten sposób:

	  [qrczak ~/prezentacja]$ cvs commit -m "Opisana komenda checkout"

1.5. Równoczesne zmiany przez wiele osób

Może się jednak okazać, że ktoś nas ubiegł i porobił własne zmiany równolegle z nami:

	  [qrczak ~/prezentacja]$ cvs commit
	  cvs commit: Examining .
	  cvs commit: Up-to-date check failed for `cvs1.tex'
	  cvs [commit aborted]: correct above errors first!

Musimy wtedy uaktualnić naszą lokalną wersję, tak żeby zawierała zarówno nasze poprawki, jak i poprawki innych. Robi to komenda `update', w skrócie `up':

	  [qrczak ~/prezentacja]$ cvs update
	  cvs update: Updating .
	  RCS file: /home/qrczak/cvsroot/prezentacja/cvs1.tex,v
	  retrieving revision 1.4
	  retrieving revision 1.6
	  Merging differences between 1.4 and 1.6 into cvs1.tex
	  M cvs1.tex

Możemy ją wydać kiedykolwiek, kiedy chcemy mieć pewność, że pracujemy na najnowszej dostępnej wersji.

W tym przypadku było łatwo: CVSowi udało się połączyć wszystkie poprawki, bo były naniesione w rozłącznych fragmentach pliku.

To w ogólnym przypadku nie oznacza, że takie nałożenie wszystkich poprawek daje sensowny wynik. Jeśli pracujemy nad źródłami programu, to może się okazać, że np. zmieniliśmy nazwę jakiejś funkcji, a ktoś inny właśnie użył tej funkcji w innym miejscu, i program po uwzględnieniu obu poprawek już się nie kompiluje, mimo że każda z osobna jest w porządku.

Przed wysłaniem tej połączonej wersji możemy obejrzeć, jak ona wygląda. Pomaga w tym komenda log, która wypisuje m.in. komentarze, jakie zostały wpisane przy commit, oraz diff, która pokazuje ścisłe różnice między dowolnymi dwiema wersjami:

	  [qrczak ~/prezentacja]$ cvs diff -u -r 1.4 -r 1.6
	  cvs diff: Diffing .
	  Index: cvs1.tex
	  =====================================================
	  RCS file: /home/qrczak/cvsroot/prezentacja/cvs1.tex,v
	  retrieving revision 1.4
	  retrieving revision 1.6
	  diff -u -r1.4 -r1.6
	  --- cvs1.tex    1999/03/10 19:21:35     1.4
	  +++ cvs1.tex    1999/03/10 19:22:05     1.6
	  @@ -117,6 +117,9 @@
	  
	  +Możemy ją wydać kiedykolwiek, kiedy chcemy mieć
	  +pewność, że pracujemy nanajnowszej dostępnej wersji.
	  +
	  W tym przypadku było łatwo: CVSowi udało się połączyć
	  wszystkie poprawki, bo były naniesione w rozłącznych

Kiedy podamy tylko jedną opcję -r komendy diff, zostanie porównana wersja, jaką mamy w lokalnym katalogu. Kiedy nie podamy żadnej opcji -r, z lokalną wersją zostanie porównana tą wersją w repozytorium, z której się lokalna wersja wywodzi.

Opcja -u (unified) określa format diffa. Więcej o tym można poczytać w info diff - cvs diff przyjmuje większość opcji programu GNU diff (samodzielnego programu porównującego pliki).

1.6. Konflikty

Gorzej, kiedy zmiany różnych osób zostały zrobione w tych samych miejscach:

	
	  [qrczak ~/prezentacja]$ cvs update
	  cvs update: Updating .
	  RCS file: /home/qrczak/cvsroot/prezentacja/cvs1.tex,v
	  retrieving revision 1.6
	  retrieving revision 1.7
	  Merging differences between 1.6 and 1.7 into cvs1.tex
	  rcsmerge: warning: conflicts during merge
	  cvs update: conflicts found in cvs1.tex
	  C cvs1.tex
	  [qrczak ~/prezentacja]$ ls -A
	  .#cvs1.tex.1.6  CVS  cvs.tex  cvs1.tex

W pliku .#cvs1.tex.1.6 mamy nasze oryginalne poprawki. W cvs1.tex te zmiany, które udało się, połączyć, są połączone, a te, których się nie udało, są zaznaczone w taki sposób:

	  @section Wysłanie poprawionych wersji
	  
	  <<<<<<< cvs1.tex
	  Kiedy uznamy, że wypada ogłsić repozytorium nasze
	  poprawki, używamy komendy @samp{commit}, w skrócie
	  @samp{ci}:
	  =======
	  Kiedy uznamy, że wypada ogłosić repozytorium nasze
	  poprawki, używamy komendy @samp{commit}:
	  >>>>>>> 1.7

Musimy wyedytować plik, przyjrzeć się bliżej konfliktom i je rozwiązać.

1.7. Dodawanie i usuwanie plików

Samo utworzenie pliku w katalogu roboczym to za mało, żeby CVS włączył go do repozytorium. Pliki dodaje się jawnie, komendą add, na przykład:

	  [qrczak ~/prezentacja]$ cvs add cvs1.tex
	  cvs add: scheduling file `cvs1.tex' for addition
	  cvs add: use 'cvs commit' to add this file permanently

Robimy to w katalogu roboczym, czyli po checkout. Podobnie komenda remove służy do usunięcia pliku (wcześniej trzeba go fizycznie skasować z katalogu roboczego).

Jak z większością innych komend, podanie nazwy katalogu do dodania albo usunięcia oznacza wszystkie pliki w tym katalogu i jego podkatalogach.

Nie ma możliwości zmiany nazwy pliku albo katalogu. Trzeba to zaemulować przez dodanie nowego pliku i usunięcie starego. W ten sposób tracimy ciągłość historii zmian, tzn. stare wersje można pobrać tylko pod starą nazwą, a nowe sprawiają wrażenie niedawno zaczętych. Dlatego dobrze jest rozplanować strukturę katalogów i nazwy plików na samym początku tworzenia projektu.

Do zaimportowania modułu od zera służy komenda import:

	  [qrczak ~/prezentacja]$ cvs import prezentacja qrczak start
	  N prezentacja/cvs1.tex
	  N prezentacja/cvs.tex
	  
	  No conflicts created by this import

Pierwszy argument oznacza katalog w repozytorium, do którego dodajemy pliki. Drugi to tzw. vendortag, czyli identyfikacja źródła modułu. Trzeci to etykieta nadana tej wersji plików. Jako następne argumenty możemy podać nazwy plików (brak oznacza bieżący katalog).

Zaimportowanie tylko wkłada pliki do repozytorium - nie przekształca bieżącego katalogu w katalog roboczy CVSa. Do tego, jak wiemy, służy komenda checkout.

Z kolei export eksportuje fragment repozytorium, podobnie do checkout, ale bez administracyjnych katalogów CVS - jakby eksportuje poza CVS.

1.8. Sprawdzanie statusu plików

Komenda status pozwala dowiedzieć się, jak się mają do siebie lokalna wersja pliku i wersje w repozytorium, i wyświetla inne informacje o pliku (np. numery rewizji i daty zmian). Możliwe statusy:

  • Up-to-date - Identyczna wersja znajduje się w repozytorium.

  • Locally Modified - Plik został wyedytowany i nie było operacji commit.

  • Locally Added - Plik został dodany komendą add i nie było operacji commit.

  • Locally Removed - Plik został usunięty komendą remove i nie było operacji commit.

  • Needs Checkout oraz Needs Patch - Ktoś w międzyczasie wysłał nową wersję do repozytorium. Powinniśmy wydać komendę update, żeby uaktualnić naszą wersję.

  • Needs Merge - Ktoś wysłał nową wersję do repozytorium i my też zmieniliśmy plik. Przygotujmy się na łączenie zmian i możliwe konflikty.

  • File had conflicts on merge - Próbowaliśmy wykonać update, ale powstały konflikty, które musimy rozwiązać.

  • Unknown - CVS nie wie, skąd się wziął ten plik. Jeśli chcemy włączyć ten plik do źródeł projektu, musimy wykonać add.

1.9. Repozytorium

Repozytorium może znajdować się na lokalnym dysku albo na zdalnym komputerze. Adres repozytorium ma postać :sposób_dostępu:ścieżka, np. :local:/var/cvsroot (dysk lokalny; :local: może być pominięte), :pserver:qrczak@pld.org.pl:/cvsroot (zdalny dostęp z autoryzacją przez CVSowy serwer haseł), :server:... i :ext:... (dostęp przez rsh).

Adres używanego repozytorium najwygodniej umieścić w zmiennej $CVSROOT. Można go też podać w opcji -d.

Do inicjalizacji nowego repozytorium służy komenda init.

Wewnątrz repozytorium oprócz katalogów z właściwymi plikami jest katalog CVSROOT zawierający różne administracyjne pliki, np. modules --- przyporządkowanie katalogów nazwom modułów, cvsignore --- maski plików, których nie należy umieszczać w repozytorium, readers i writers -- kto ma jakie prawa dostępu. Te pliki edytuje się tak samo jak zwykłe pliki, tzn. checkout CVSROOT/modules itd. Istnieje komenda admin, interfejs do różnych administracyjnych czynności, np. można nieodwracalnie usunąć pewne rewizje.

1.10. Odgałęzienia

Wyobraźmy sobie, że projekt jest w połowie drogi między ostatnią stabilną wersją a przewidywaną następną nadającą się do szerszego użytku. Nagle znajdujemy błąd w starszej wersji, który chcielibyśmy jak najszybciej poprawić i wypuścić poprawkę. Jednak nowa wersja jest zupełnie rozgrzebana.

Inna sytuacja: część osób eksperymentuje nad zupełnie nowatorską implementacją pewnego elementu. Inne osoby tymczasem pracują nad inną rzeczą i potrzebują do tego pewnie działającego elementu rozwijanego przez pierwszą grupę. Wolą poczekać na koniec eksperymentów i działające ostateczne rozwiązanie niż uważać, żeby przypadkiem nie ,,uaktualnić'' sobie plików na chwilowo niedziałające.

W takich przypadkach możemy utworzyć odgałęzienie (branch), czyli ścieżkę rozwoju niezależną od głównego nurtu. Służy do tego opcja -b nazwa_gałęzi komendy tag albo rtag.

Ogólnie komendy tag i rtag (bez opcji -b) służą do nadawania rewizjom symbolicznych nazw, co ma o tyle duże znaczenie, że numery rewizji są indywiualne dla każdego pliku. tag służy do nadawania etykiety plikom pobranym z repozytorium, a rtag --- modułom w repozytorium, bez konieczności ich pobrania. Z reguły po opcji -r różnych komend może wystąpić numer rewizji albo nazwa etykiety (która musi zaczynać się od litery).

Etykieta rewizji pobranej przez checkout albo update z opcją -r rewizja zawsze jest lepka (sticky), tzn. zmiany w tych plikach utworzą dalszy ciąg gałęzi, z której pochodzą --- pozostając atrybutem tych plików aż do wykonania update -A, co oznacza pozbycie się wszekich lepkich etykiet i tożsamości gałęzi.

Numeracja rewizji plików w gałęzi ma o dwie cyfry więcej niż rewizja z której gałąź została wypuszczona, np. z rewizji 2.7 powstaje gałąź 2.7.2 z rewizjami 2.7.2.1, 2.7.2.3 itd., następna gałąź z tej samej rewizji będzie miała numer 2.7.4 itd.

Można później wcielić do innej wersji zmiany powstałe w gałęzi. Opcja -j rewizja (join) komendy update powoduje zaaplikowanie zmian powstałych w danej gałęzi -- od najbliższego wspólnego przodka bieżącej wersji oraz podanej. Kiedy gałąź dalej rośnie, następnym razem będziemy chcieli włączyć tylko poprawki od poprzedniego takiego kroku, więc podamy dwie opcje -j wyznaczające interesujący nas przedział.

1.11. Informowanie o tym, kto co edytuje

Domyślne zasady pozwalają pracować wielu osobom nad tym samym plikiem bez ich wiedzy o sobie. Dopiero przy commit okaże się, że trzeba połączyć poprawki. Można jednak wcześniej wymusić ściślejszą kontrolę.

Wydanie komendy watch on pliki powoduje, że po pobraniu tych plików trzeba będzie jawnie wydać komendę edit przed ich edycją. watch off przywraca domyślny model.

Komenda edit z kolei ostrzega użytkownika, kiedy wiele osób wykona ją na tym samym pliku. unedit anuluje edit, przywracając pliki z repozytorium. Do całkowitego zakończenia pracy z plikami służy komenda release, której można dodać parametr -d oznaczający skasowanie lokalnej kopii plików.

Również w domyślnym modelu można sobie zażyczyć otrzymywania informacji o wykonaniu określonych operacji na plikach, komendą watch add -a akcja, gdzie akcja to jedno z edit, unedit, commit, all, none (domyślnie all). watch remove przestaje informować.

Sposób informowania jest zapisany w pliku CVSROOT/notify, np. może to być wysłanie poczty.

Komendy watchers i editors wypisują użytkowników, którzy wykonali watch add albo edit (i nie anulowali tego).

Oprócz tego można w plikach CVSROOT/modules i CVSROOT/loginfo podłączyć wykonanie danego programu do commit określonych plików, np. może to być rozesłanie poczty albo wysłanie informacji na lokalną grupę dyskusyjną.

1.12. Słowa kluczowe

Pliki oderwane od CVSa tracą swoją tożsamość -- nie jest nigdzie w jednolity sposób zapisane, jaka to rewizja pliku i skąd pochodzi.

CVS oferuje mechanizm ułatwiający włączanie takich informacji. Napisy postaci $klucz$ albo $klucz:wartość$ umieszczone w plikach są zawsze automatycznie wyposażane w aktualne informacje.

W szczególności Id: (zamknięte dolarami z obu stron) jest rozwijane w zbiór najważniejszych informacji (m.in. nazwa pliku, rewizja, osoba która ostatnio wprowadzała zmiany, data tych zmian), a Log: (zamknięte dolarami z obu stron) powoduje dopisywanie w tym miejscu tego co pokazuje komenda log.

1.13. Pliki binarne

W repozytorium najczęściej składowane są pliki tekstowe. Pliki binarne z reguły są generowane automatyczne, a nie pisane przez człowieka, i nie stanowią części źródeł. Również porównywanie wersji plików binarnych i nakładanie poprawek rzadko ma inny sens niż stwierdzenie ,,takie same'' albo ,,różne'' oraz zastąpienie nową wersją.

Mimo wszystko w CVSie można umieszczać też pliki binarne. Należy wtedy używać opcji -kb, która wyłącza tłumaczenie końców linii z lokalnego standardu na konwencję stosowaną w CVSie (w przypadku Unixa nie ma to akurat znaczenia) oraz zastępowanie słów kluczowych.

Rozdział 2. CVS po polsku

<authorblurb>

Tomasz Kłoczko, Sergiusz Pawłowicz,

</authorblurb>

2.1. Wprowadzenie

Wiedza na temat narzędzi ułatwiających koordynowanie grupowych przedsięwzięć informatycznych, w Polsce jest niemal szczątkowa. Tyle się mówi o pracy grupowej uzywając tu jako przykładów pseudonarzędzi z Win* zapominając, że jednymi z pierwszych, i do dzisiaj najczęściej używanymi narzędziami, są CSSC czy RCS. CVS stanowi o wiele bardziej dojrzały produkt. O ile np. RCS (Revision Control System) operuje na pojedynczych plikach, to CVS na niższej warstwie wykorzystując technologię RCS umożliwia operowanie na katalogach czy też całych projektach.

W tej chwili większość projektów OSS, w których bierze udział czasami nawet niewielka grupa, jest składowanych w CVS. Przykładami mogą być choćby GNOME, mutt czy KDE.

2.2. Jak wygląda praca w CVS?

W jakimś punkcie sieci zorganizowane jest repozytorium dokumentów. Jest to swego rodzaju baza umożliwiająca przechowywanie informacji o wszystkich zmianach czyli o tym kto, kiedy i jakie zamiany wykonał. Aby móc operować na zasobach repozytorium trzeba mieć konto powiązane z hasłem. Zazwyczaj w repozytorium zakłada się też konta typu anonymous, nobody czy cvs, na które hasło jest ogólnie znane i opublikowane, ale jednocześnie poprzez to konto można operować jedynie w trybie ,,tylko do odczytu''.

2.3. Co daje CVS

Podstawowym atutem używania tego typu narzędzi jest minimalizowanie konieczności kontaktowania się między osobą chcącą dokonać zmiany, a resztą zespołu. Nawet jeżeli osoba wykonująca zmianę wprowadzi coś nieprawidłowego czy cokolwiek nieopatrznie skasuje (o tym dalej), fakt ten nie niesie za sobą niemal żadnych konsekwencji, gdyż od czasu do czasu osoba mająca pieczę nad całościa (tzw. release manager) przegląda co było zrobione, i w każdej chwili może zdecydować czy daną zmianę zakceptuje zbierając przy wypuszczaniu kolejnej wersji całych źródeł z czoła zmian, czy też nie. W każdej chwili ktokolwiek inny może nanieść poprawkę usuwającą jakąś niedoróbkę po jej pechowym wprowadzeniu. Cofania zmian raczej się nie praktykuje. Kasowanie zasobu również nie jest niebezpieczne, gdyż nie kasuje go fizycznie, a jedynie przenosi do zbioru rzeczy skasowanych; cofnięcie kasowania można dokonać w każdej chwili przenosząc po prostu plik z opisem zasobu do głównego drzewka.

Warunki, jakie tworzy CVS, są unikatowe. Umożliwiają one pracę grupie ludzi, która nie musi się znać, mieć do siebie nieogranicznonego zaufania. Praktyczną konsekwencją powyższego jest to, że dostęp do zasobów w trybie 'odczyt i zapis' jest autoryzowany w symbolicznej formie i pozwala to na przeprowadzenie autoryzacji tylko raz w momencie pierwszego dostępu do zasobów, co znacznie ułatwia pracę bardziej aktywnym współudziałowcom projektu.

2.4. Jak przebiega typowa sesja pracy z wykorzystaniem CVS?

Zanim zacznie się pracę, pierwszym ruchem jest uzyskanie dostępu w trybie ,,odczytu i zapisu'' do zasobów. Odbywa się to tak, że osoba zgłaszająca się dostarczyć musi zakodowane standardową funkcją crypt() hasło. Może to zrobić każdy za pomocą np. perla:

	  $ perl -e 'print crypt "password", "salt"; print "\n"; ' 

gdzie <password> to hasło jakim osoba potem będzie się posługiwać przy dostępie do repozytorium, a <salt> to dwie dowolne litery. Osobie zarządzającej repozytorium dostarcza się więc parę:

<login>:<crypted_password>

Wymagany jest zwykle również adres poczty elektronicznej współtwórcy OSS, dzięki któremu będzie można się z nim łatwo kontaktować (np. w celu informowania o przerwach w działaniu repozytorium, etc.)

Niezwłocznie po dodaniu użytkownika, może on rozpocząć pracę. Przykład, jakim się tu posłużę, będzie się opierał na zasobach PLD.

Pierwsza sprawa to zalogowanie się:

	  $ cvs -d :cvs -d :pserver:kloczek@cvs.pld.org.pl:/cvsroot login 
	  (Logging in to kloczek@cvs.pld.org.pl) 
	  
	  CVS password: <tu wklepuję własne hasło> 

Po poprawnym podaniu hasła w pliku ~/.cvspass pojawi się wpis dotyczący dostępu do tego konkretnie repozytorium wraz z postacią zakodowaną hasła, które potem automatycznie będzie używane przy kolejnych kontaktach.

Teraz można przystąpić do odczytania zasobów repozytorium. Tu jedna uwaga. Zamiast za każdym razem podawać dla cvs pełną scieżkę -d :pserver:.. mogę ustawić sobie zmienną w środowisku powłoki:

CVSROOT=":pserver:kloczek@cvs.pld.org.pl:/cvsroot"

Teraz bedzie już krócej i pierwsze pobranie zasobu wyglądać będzie tak:

	  $ cvs get SPECS

W tym momencie rozpocznie się ściaganie modułu SPECS z repozytorium na lokalny dysk twardy, do obecnej scieżki, w której znajduje się użytkownik. Czasami, gdy kontakt z repozytorium jest ograniczony jakimś wąskim gardłem, można transmisję kompresować za pomocą gzipa:

	  $ cvs -z9 get SPECS 

Po tym wszystkim w bieżącym katalogu powstanie (w naszym przykładzie) katalog roboczy SPECS ze wszystkimi plikami jakie są w tym module.

Co mogę zrobić z tym co ściągnąłem? Mogę przeglądać aktualne zbiory (to oczywiste), moge przeglądać historię zmian i status poszczególnych plików za pomocą poleceń:

	  $ cd SPECS 

	  $ cvs log <plik>

	  $ cvs status <plik>

jak i historię wszystkich zmian jakie były wykonywane, za pomocą np. skryptu, który przychodzi wraz z CVSem, przez wydanie polecenia:

	  $ rcs2log | less 

Po przejrzeniu i poprawieniu (modyfikuję przykładowo jeden z plików) można dokonać dołączenia mojej zmiany do zasobów repozytorium przez polecenie:

	  $ cvs commit <plik> 

lub krócej:

	  $ cvs ci <plik> 

W tym momencie zostanie wywołany domyślny edytor systemu (określony zwykle w zmiennej powłoki $EDITOR) i będzie można skomentować tę zmianę (komentarz jest potem widoczny np. przy przeglądaniu repozytorium za pomocą rcs2log czy cvs log), a po wyjściu z edytora, zmiana zostanie wysłana do repozytorium. Załóżmy, że jest kilka osób które już coś danego dnia zmodyfikowały. Co wykonać przed rozpoczęciem pracy ? Otóż pierwszą czynnością powinno być uaktualnienie moich własnych zasobów względem repozytorium czyli:

	  $ cd SPECS; cvs -z9 update

Zostaną dociągnięte wszystkie zmiany, a po przejrzeniu loga za pomocą rcs2log mogę rozpocząć własne prace. Co by się stało, gdybym nie wykonał synchronizacji modyfikując jakiś plik, który dzisiaj już zmodyfikowała inna osoba? Nie ma strachu. Przy próbie zrobienia commit zostałby wyświetlony komunikat, że moje własne zasoby nie zostały zsynchronizowane względem repozytorium i że najpierw powinienem to właśnie zrobić. Żeby jednak już nie stracić zmian jakie zrobiłem, moge sobie wygenerować diffa względem repozytorium, którego potem wykorzystam przez:

	  
	  $ cvs diff <plik> > plik.diff 

i wykonać już update czyli:

	  
	  $ cvs update <plik> 

po wyłączeniu własnych zmian:

	  $ patch < plik.diff 

i sprawdzeniu co z tego w efekcie końcowym wyszło - można już zrzucić do repozytorium moją robotę:

	  $ cvs ci <plik> 

Powyższy opis to tylko początek możliwości jakie kryją się w CVS. CVS jest skomplikowany. Osoby używające [x]emacsa mogą skorzystać z kilku funkcji podpiętych pod menu do pracy z repozytorium CVS. Jest także dostępnych wiele innych narzędzi dodatkowych służących do operowania na zasobach CVS.

2.5. Informacje techniczne dotyczące obsługi CVS dla PLD

Listy z prośbami o założenie indywidualnego konta do odczytu i zapisu należy kierować pod adres: <pld-cvs@pld.org.pl>. W krótkim czasie zgłoszenie zostanie potwierdzone.

PLD dysponuje możliwością przeglądania repozytorium przez WWW: http://cvs.pld.org.pl/

2.6. Odpowiedzi na najczęściej zadawane pytania

2.6.1. Gdzie mogę znaleźć obszerny podręcznik CVSa?
2.6.2. Ojej, to mówisz, że mam sobie instalować cvs? ;) To jest pojedyncza binarka (klient) .. paręset KB ;) Właśnie sobie skompilowałem. Można to jakoś domowo potestować?
2.6.3. Jak wyciągnąć listę plików w danym module bez ich ściągania?
2.6.1.

Gdzie mogę znaleźć obszerny podręcznik CVSa?

Na http://www.linuxdoc.org/LDP/LDP-Author-Guide/cvs.html znajdziesz porządny (i długi!) podręcznik CVSa. Niestety tylko po angielsku!

2.6.2.

Ojej, to mówisz, że mam sobie instalować cvs? ;) To jest pojedyncza binarka (klient) .. paręset KB ;) Właśnie sobie skompilowałem. Można to jakoś domowo potestować?

Zapewne chodzi Ci o próby z własnym repozytorium. Tak, można.

		$ mkdir <katalog>

		$ export CVSROOT=":pserver:kloczek@cvs.pld.org.pl:/cvsroot"

		$ cvs init 

		$ cd pl_PL 

		$ cvs add man*/*.* 

		$ cvs ci -m "initial version" man*/*.* 

Tak może wyglądać zainicjowanie własnego repozytorium. Bardziej poprawna inicjacja modułu powinna jeszcze zawierać po wykonaniu cvs init ściągniecie modułu CVSROOT:

		$ cvs get CVSROOT 

i po edycji pliku modules zrzucenie go do modułu CVSROOT. Więcej szczegółów mozna znaleźć w instrukcji o której mowa w pytaniu1.

2.6.3.

Jak wyciągnąć listę plików w danym module bez ich ściągania?

Najprościej przez cvs status | grep File.