Concurrent Versions System (w skrócie CVS) jest narzędziem wspomagającym grupową pracę nad danymi komputerowymi, w szczególności plikami tekstowymi. Jest powszechnie stosowany w projektach OpenSource.
Żeby grupa ludzi mogła wspólnie pracować nad jakimś projektem w tradycyjny sposób, istniałaby potrzeba przesyłania wprowadzonych przez każdą osobę zmian, do jednej wybranej osoby, która miałaby za zadanie "sklejać" to wszystko w całość. Nietrudno wyobrazić sobie jak bardzo czasochłonną i żmudną byłoby to czynnością. Dlatego też powstał ten system. Ma za zadanie to usprawnić i zautomatyzować.
Wszystkie pliki projektu trzymane są w jednym miejscu, w tak zwanym repozytorium. Każdy pobiera sobie te pliki na swój dysk, a następnie po wprowadzeniu poprawek odsyła je. Wiele osób może w tym samym czasie pracować nad jednym plikiem, a po przesłaniu ich z powrotem system CVS zajmie się łączeniem wszelkich naniesionych zmian w jeden plik wynikowy. Kolejną zaletą tego systemu jest pamiętanie poprzednich wersji. Nic więc nie stoi na przeszkodzie by w każdej chwili cofnąć wprowadzone zmiany. Pozwala to kontrolować jakość i poprawność zmian oraz ewentualnie przywracać stan sprzed ich wprowadzenia w przypadku błędów.
Jest bardzo zalecane, aby każdy z członków grupy umiał i korzystał z CVS.
Aby móc korzystać z systemu CVS musisz posiadać w nim konto. Dzięki temu nikt niepowołany nie może modyfikować naszych zbiorów.
Jak zdobyć konto?
Konta w naszym systemie CVS zakłada koordynator. Należy do niego przesłać list zawierający proponowaną nazwę konta oraz hasło. Najlepiej, by hasło było przesyłane w postaci zaszyfrowanej. By zaszyfrować hasło, można użyć polecenia:
perl -e 'printf(crypt("aaaaaaaa","bb")."\n")'
Ciąg znaków aaaaaaaa należy zastąpić proponowanym hasłem, a bb dowolnymi dwoma literami lub cyframi. Przykładowy przebieg szyfrowania prezentuję poniżej:
(fenio@domek)~$perl -e 'printf(crypt("rowerek","55")."\n")'
5539KZmftZRaU
(fenio@domek)~$
To, co zwróci nam polecenie Perla, to właśnie zaszyfrowane hasło, które należy przesłać do koordynatora. W tym wypadku jest to ciąg znaków 5539KZmftZRaU. Tak właśnie wygląda zaszyfrowane słowo rowerek.
Uprzedzam przed zbytnio skomplikowanymi hasłami. Zdarza się czasem, że pomimo poprawnie zaszyfrowanego hasła - ono nie działa. Nie wiem czemu tak się dzieje, ale podejrzewam, że funkcja szyfrująca nie lubi się z ,,dziwnymi'' znaczkami. Dlatego zalecam unikać haseł typu HmnQ;/qrv,as a w zamian stosować jakieś prostsze typu fragles12 czy s4setka. Pozwoli to zaoszczędzić niepotrzebnych problemów.
Jeśli nie posiadasz dostępu do programu Perl, nie przejmuj się.
Możesz również przesłać niezaszyfrowane hasło. Jedyna różnica to fakt, iż
będzie je znał koordynator, ale jest to osoba raczej godna zaufania ;)
Zaszyfrowane hasła składają się z 13 znaków. Sprawdź czy Twoje również ma tyle.
Mając wybrany login (nazwę konta) oraz hasło, należy je przesłać na adres
fenio@debian.org. W
opisanym powyżej przypadku treść wiadomości mogłaby wyglądać następująco:
Proszę o założenie konta w CVS. Oto proponowane dane:
login: fenio
hasło: 5539KZmftZRaU
Tak przygotowany list wysyłamy. Po jakimś czasie spodziewać się można wiadomości zwrotnej z informacją o założeniu (bądź nie) konta. Może się zdarzyć, że dana nazwa konta jest już wykorzystana, wtedy koordynator o tym poinformuje i będzie trzeba wybrać nazwę ponownie oraz powtórzyć procedurę.
Uwaga: W żadnym wypadku nie należy przesyłać hasła na adres listy dyskusyjnej.
Dalsze postępowanie zależy od tego jakiego systemu operacyjnego, a co za tym idzie oprogramowania, używasz. Dlatego też, ten podrozdział został podzielony na dwie części. Pierwsza z nich opisuje sposób korzystania z CVS pod systemem Linux, a druga pod systemem Windows. Opuść podrozdział, który Cię nie dotyczy.
Zakładam, iż używasz dystrybucji Debian GNU/Linux. W końcu bierzesz udział w projekcie tłumaczącym dokumentację do tej właśnie dystrybucji. Część poleceń może nie zadziałać w innych dystrybucjach, szczególnie te, dotyczące instalacji oprogramowania.
Będziemy potrzebować programu umożliwiającego korzystanie z CVS. Do instalacji
oprogramowania posłużymy się narzędziem apt-get. Będąc
zalogowanym jako administrator (root), wprowadź w linii poleceń:
apt-get install cvs
Możliwe, że masz już zainstalowane odpowiednie pakiety. Wtedy na ekranie ujrzysz:
(root@domek)~$apt-get install cvs
Reading Package Lists... Done
Building Dependency Tree... Done
Sorry, cvs is already the newest version.
0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
(root@domek)~$
W takim przypadku resztę tego podrozdziału możesz opuścić. W przeciwnym wypadku zastosuj się do poniższych wskazówek.
Po chwili, potrzebnej na pobranie pakietu z sieci i jego rozpakowaniu, powinno pojawić się okno konfiguracyjne.
Debconf zapyta Cię gdzie umieszczone są Twoje repozytoria.
Obojętne co odpowiesz na to pytanie, gdyż ta opcja jest wykorzystywana tylko w
przypadku udostępniania, a Ty jedynie będziesz korzystać z innego repozytorium.
Najbezpieczniej po prostu wcisnąć w tym miejscu [ENTER].
Następne pytanie dotyczy obsługi mechanizmu pserver. Sytuacja jest podobna do powyższej. Funkcja ta ma znaczenie przy tworzeniu repozytorium, więc Ciebie nie dotyczy. Znowu naciskamy [ENTER], a przy pytaniu "Should the CVS pserver be enabled?" odpowiadamy [NO]. To wszystko. Potrzebne oprogramowanie jest zainstalowane.
Pierwszą czynnością jaką musimy wykonać to pobranie plików z głównego
repozytorium. Przedtem jednak lepiej utworzyć na to specjalny katalog (na
przykład pddp). By tego dokonać wprowadź mkdir pddp.
Następnie przejdź do tego katalogu (cd pddp). By się zalogować w
systemie CVS będziesz potrzebować nazwy konta oraz hasła. Wprowadź następujące
polecenie:
cvs -d :pserver:nazwa_konta@debian.linux.org.pl:/home/cvs login
Oczywiście zmień nazwa_konta na nazwę zatwierdzoną przez koordynatora. Następnie CVS poprosi o podanie hasła. Wprowadź je (w formie niezaszyfrowanej) i naciśnij [ENTER]. Jeśli wszystko pójdzie bezbłędnie, nie powinny pokazać się żadne komunikaty, a jedynie znowu znak zachęty powłoki. Oto przykład jak prawidłowo powinno wyglądać logowanie:
(fenio@domek)~/pddp$cvs -d :pserver:fenio@debian.linux.org.pl:/home/cvs login
Logging in to :pserver:fenio@debian.linux.org.pl:2401/home/cvs
CVS password:
(fenio@domek)~/pddp$
W przykładzie nazwą konta jest fenio. Należy zastąpić ją swoją nazwą. Teraz pobierzmy pliki. Zważ na to, że całe repozytorium to ponad 50MB! Będąc w tym samym katalogu wprowadź polecenie:
cvs -d :pserver:nazwa_konta@debian.linux.org.pl:/home/cvs checkout ./
Zamień nazwa_konta na swoją nazwę tak jak w poprzednim poleceniu. Poniżej przykład jak może wyglądać efekt tego polecenia:
(fenio@domek)~/pddp$cvs -d :pserver:fenio@debian.linux.org.pl:/home/cvs checkout ./
cvs server: Updating .
cvs server: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg
cvs server: Updating pddp
U pddp/slownik.txt
U pddp/zasady.txt
cvs server: Updating pddp/pomoc
U pddp/pomoc/cvs.sgml
U pddp/pomoc/generuj
U pddp/pomoc/lista.sgml
U pddp/pomoc/pomoc.sgml
U pddp/pomoc/wstep.sgml
cvs server: Updating pddp/skrypty
U pddp/skrypty/generuj
U pddp/skrypty/pddp_check.pl
U pddp/skrypty/slownik
(fenio@domek)~/pddp$
Lista pobranych plików z pewnością będzie dłuższa (w momencie pisania tych słów
- wrzesień 2004 - repozytorium zajmuje ponad 120MB). Dla zobrazowania zasady
działania wystarczy nam jednak wycinek tej listy. W tym momencie w katalogu
~/pddp utworzonych zostało kilka podkatalogów
(CVSROOT, pddp itd.). W nich znajdują się różne
pliki, począwszy od dokumentów, które tłumaczymy, poprzez różnego rodzaju
skrypty wspomagające naszą pracę, na słowniku projektu kończąc. Reasumując
stworzyliśmy lokalną kopię repozytorium.
Polecenie cvs można jeszcze wzbogacić o opcję -zx, gdzie x to dowolna cyfra. Opcja ta ustala stopień kompresji podczas przesyłania plików. 1 oznacza najsłabszą, ale zarazem najszybszą kompresję, a 9 najsilniejszą, ale najbardziej czasochłonną. Cyfry pomiędzy 1 a 9, ustalają odpowiednio coraz większy stopień kompresji. Tak wyglądałoby polecenie z 6 stopniem kompresji:
cvs -z6 -d :pserver:fenio@debian.linux.org.pl:/home/cvs checkout ./
W powyższym przykładzie po opcji checkout umieściłem ./, co oznacza główny katalog repozytorium. Częściej stosowane są jednak nazwy konkretnych katalogów. Polecenie mogłoby wyglądać na przykład tak:
cvs -d :pserver:fenio@debian.linux.org.pl:/home/cvs checkout pddp
Wtedy pobrany zostałby tylko jeden katalog o nazwie pddp. Główne
katalogi repozytorium zwane są również modułami. Jednakże dla potrzeb naszego
projektu najlepiej pobrać wszystkie katalogi, tak jak zostało to pokazane.
Przed przystąpieniem do edycji jakiegoś pliku zawsze należy wykonać aktualizację lokalnej kopii.
Zakładam, że nadal jesteś w katalogu ~/pddp. By zaktualizować
lokalną kopię repozytorium wystarczy wprowadzić polecenie:
cvs update.
Więcej szczegółów i przykład jak może wyglądać wynik takiego polecenia, znajduje się w dalszej części tego rozdziału. Na razie wystarczy Ci jedynie znajomość tego polecenia.
Po zmodyfikowaniu jakiegoś pliku, należy przesłać poprawki z powrotem do
repozytorium. Zakładam, że nadal znajdujesz się w głównym katalogu swojej
lokalnej kopii repozytorium, czyli postępując według moich wskazówek, bieżącym
katalogiem powinien być ~/pddp.
Przesłania pliku do głównego repozytorium można dokonać na dwa sposoby.
Wprowadź następujące polecenie:
cvs commit -m "opis wprowadzonych zmian" ścieżka/plik
Załóżmy, że zmodyfikowany plik to cvs.sgml znajdujący się w
podkatalogu pddp/pomoc/. To przykład zastosowania takiego
polecenia. Jest on z życia wzięty (ten dokument powstaje właśnie w
repozytorium CVS).
(fenio@domek)~/pddp$cvs commit -m "opis przesyłanych zmian" pddp/pomoc/cvs.sgml
Checking in pddp/pomoc/cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.6; previous revision: 1.5
done
(fenio@domek)~/pddp$
System poinformował nas, że przesłał plik do repozytorium oraz, że po nałożeniu naszych zmian przyporządkował plikowi nowy, kolejny numer wersji (w tym przypadku 1.6). Oczywiście jeśli znajdujemy się w tym samym katalogu co plik, który chcemy przesłać, to ścieżkę dostępu można pominąć.
Wprowadź następujące polecenie:
cvs commit
Przy takim poleceniu CVS sam przeszuka lokalną kopię repozytorium w
poszukiwaniu zmodyfikowanych plików. Oto kolejny przykład z życia wzięty. Po
modyfikacji pliku cvs.sgml przesyłam poprawki innym sposobem.
Wynik powyższego polecenia może wyglądać tak:
(fenio@domek)~/pddp$cvs commit
cvs commit: Examining .
cvs commit: Examining CVSROOT
cvs commit: Examining pddp
cvs commit: Examining pddp/pomoc
cvs commit: Examining pddp/skrypty
cvs commit: Examining verbose
cvs commit: Examining verbose/debian_install
cvs commit: Examining verbose/debian_kernel
[ ..:: CZĘŚĆ INTERAKTYWNA ::.. ]
Checking in pddp/pomoc/cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.7; previous revision: 1.6
done
(fenio@domek)~/pddp$
Widać, że zmiany zostały przesłane, a CVS znowu zwiększył numer wersji tego pliku (teraz wynosi 1.7). No tak, ale ktoś mógłby spytać gdzie tu ta cała interaktywność lub gdzie wprowadzić opis dokonanych zmian. Otóż podczas wykonywania tego polecenia, w miejscu oznaczonym przeze mnie w powyższym przykładzie jako [ ..:: CZĘŚĆ INTERAKTYWNA ::.. ] zostaje uruchomiony edytor tekstu z taką zawartością:
CVS: ----------------------------------------------------------------------
CVS: Enter Log. Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS: pddp/pomoc/cvs.sgml
CVS: ----------------------------------------------------------------------
Program informuje nas jakie pliki zostały zmienione. Prosi również o wprowadzenie komentarza opisującego dokonane zmiany. Należy tego dokonać w pierwszej, pustej linii. Reszta linii, rozpoczynających się od CVS: zostanie usunięta przed przesłaniem automatycznie, o czym również jesteśmy informowani. Tak może wyglądać zawartość tuż przed przesłaniem:
opis przesyłania plików interaktywnie
CVS: ----------------------------------------------------------------------
CVS: Enter Log. Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS: pddp/pomoc/cvs.sgml
CVS: ----------------------------------------------------------------------
Jak widać zmieniła się tylko pierwsza linia. Pojawił się komentarz. Jeśli uważamy, że wszystko jest gotowe do przesłania, to należy wyjść z edytora, zapisując zmiany.
Należy tutaj jeszcze wspomnieć coś więcej o edytorze. Skąd CVS wie jakiego
edytora użyć do wprowadzenia komentarza? Tę informację pobiera ze zmiennej
środowiskowej $EDITOR lub $CVSEDITOR. Najpierw sprawdza zmienną $CVSEDITOR, a
jeśli jest pusta to sprawdza zmienną $EDITOR. Domyślnie zmienna $CVSEDITOR nie
jest ustawiona w systemie, a zmienna $EDITOR najczęściej wskazuje na edytor
vi lub vim. I taki też edytor zostanie uruchomiony.
Nie wszystkim musi to odpowiadać, a wtedy należy zmienić zawartość
którejkolwiek ze zmiennych.
Dokonuje się tego poleceniem export ZMIENNA=/sciezka/do/edytora. Jednakże po wylogowaniu się i ponownym zalogowaniu zmienna tak ustawiona będzie miała z powrotem starą wartość. Aby ustawić tę zmienną na stałe trzeba powyższe polecenie umieścić w jednym z plików konfiguracyjnych, które są przetwarzane podczas logowania.
Oto przykładowe polecenie, które sprawi, że zmienna $EDITOR będzie po zalogowaniu wskazywała na edytor z programu Midnight Commander (/usr/bin/mcedit):
echo "export EDITOR=/usr/bin/mcedit" >> ~/.bash_profile
W przykładzie zakładam, że używasz powłoki Bash, ponieważ taka jest standardowo ustawiana w systemie Debian. Jeśli używasz innej to zapewne poradzisz sobie z samodzielnym ustawieniem odpowiedniej zmiennej.
Może się zdarzyć, że podczas gdy my nanosiliśmy poprawki na jakiś plik, w tym samym momencie robił to ktoś inny. Co więcej, załóżmy, że ta druga osoba przesłała już swoje zmiany do repozytorium. Co to oznacza?
Jak łatwo się domyśleć teraz nasze poprawki nie odnoszą się już do najnowszej wersji dokumentu. Co się stanie gdy spróbujemy przesłać nasze poprawki do repozytorium?
Załóżmy, że wcześniej pobraliśmy z repozytorium plik cvs.sgml w
wersji 1.17. Dokonaliśmy własnych poprawek i teraz chcemy je przesłać.
Zgodnie z wcześniejszym podrozdziałem wprowadzamy:
cvs commit -m "opis zmiany" pddp/pomoc/cvs.sgml
Oto efekt takiego polecenia:
(fenio@domek)~/pddp$cvs commit -m "konflikty" pddp/pomoc/cvs.sgml
cvs server: Up-to-date check failed for `pddp/pomoc/cvs.sgml'
cvs [server aborted]: correct above errors first!
(fenio@domek)~/pddp$
Jak widać przesłanie nie powiodło się. CVS poinformował nas, że nasze modyfikacje nie odnoszą się do najświeższej wersji z repozytorium. Prosi o poprawienie tego. Sposób poprawienia zależy jednak od tego czy nasze zmiany znajdują się w tej samej części pliku czy nie. Poniżej opisuję obie sytuacje:
W takim przypadku system CVS powinien poradzić sobie z połączeniem naszych zmian ze zmianami poprzednika i utworzeniem jednego pliku wynikowego. By to zrobić wprowadź polecenie:
cvs update
Tak może to wyglądać w rzeczywistości:
(fenio@domek)~/pddp$cvs update
cvs server: Updating .
cvs server: Updating CVSROOT
cvs server: Updating pddp
cvs server: Updating pddp/pomoc
RCS file: /home/cvs/pddp/pomoc/cvs.sgml,v
retrieving revision 1.17
retrieving revision 1.18
Merging differences between 1.17 and 1.18 into cvs.sgml
M pddp/pomoc/cvs.sgml
cvs server: Updating pddp/skrypty
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
cvs server: Updating verbose/debian_kernel
(fenio@domek)~/pddp$
CVS przegląda całą lokalną kopię repozytorium i porównuje ją z główną kopią
znajdującą się na serwerze. Pobiera informacje o zmianach w pliku
cvs.sgml i stara się połączyć je z naszą zmienioną wersją.
Informuje o tym w linii "Merging...". Operacja zakończyła się
sukcesem. Dodatkowo CVS zapisuje ukryty plik oryginału sprzed połączenia
zmian. W naszym przypadku plik ten otrzymał nazwę
.#cvs.sgml.1.17, więc jak widać w nazwie jest zapisana wersja.
Plik ten jest zapisywany na wypadek, gdybyśmy chcieli sami sprawdzić czy CVS
poprawnie połączył zmiany. Jeśli nie chcemy tego robić można usunąć ten plik
poleceniem rm -f .#cvs.sgml.1.17. Teraz pozostaje nam przesłanie
pliku z połączonymi zmianami do repozytorium. Robimy to dokładnie tak jak
przedtem wpisując:
cvs commit -m "opis zmiany" pddp/pomoc/cvs.sgml
A oto wynik takiego polecenia:
(fenio@domek)~/pddp$cvs commit -m "poprawiony konflikt"
pddp/pomoc/cvs.sgml
Checking in pddp/pomoc/cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.19; previous revision: 1.18
done
(fenio@domek)~/pddp$
Tym razem nasze poprawki zostały przesłane i naniesione bez przeszkód.
Tutaj sytuacja trochę się komplikuje. Program komputerowy choćby nie wiem jak sprawnie napisany pozostanie programem. Nie posiada inteligencji i sam nie jest w stanie stwierdzić, które poprawki są prawidłowe. Czy te wprowadzone przez nas czy przez poprzednią osobę.
Aby przedstawić zasadę rozwiązywania problemów przy nakładających się na siebie zmianach posłużę się specjalnym przykładowym zdaniem, które będzie znajdować się w tym pliku i które będziemy modyfikować. Będzie to jedna linijka tak by łatwo można było wytłumaczyć na czym polega rozwiązywanie takich konfliktów. Oto nasze zdanie:
Ala ma kota.
Załóżmy, że pobraliśmy plik z repozytorium w wersji 1.23. Teraz stwierdziliśmy, że przykładowe zdanie należy zmodyfikować. Według nas ma ono brzmieć:
Ala ma małego kotka.
Ale niestety okazało się, że ktoś inny stwierdził, że to zdanie należy zmienić na:
Ala Kowalska nie ma kota.
Co więcej, przesłał już swoją poprawkę do repozytorium i w tym momencie istnieje tam już wersja 1.24 z jego modyfikacją tego zdania. Ewidentnie mamy tu konflikt.
Co się stanie jak spróbujemy przesłać nasze poprawki ?
Oczywiście zostaną odrzucone z prośbą o aktualizację naszej kopii repozytorium (tak jak w przykładzie gdzie poprawki się nie nakładały). Nieświadomi tego, że zmiany znajdujące się w głównym repozytorium konfliktują z naszymi (bo przecież nie możemy tego wiedzieć), przystępujemy do aktualizacji naszej kopii repozytorium.
Tak wyglądałby wynik takiej aktualizacji:
(fenio@domek)~/pddp$cvs update
cvs server: Updating .
cvs server: Updating CVSROOT
cvs server: Updating pddp
cvs server: Updating pddp/pomoc
RCS file: /home/cvs/pddp/pomoc/cvs.sgml,v
retrieving revision 1.23
retrieving revision 1.24
Merging differences between 1.23 and 1.24 into cvs.sgml
rcsmerge: warning: conflicts during merge
cvs server: conflicts found in pddp/pomoc/cvs.sgml
C pddp/pomoc/cvs.sgml
cvs server: Updating pddp/skrypty
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
cvs server: Updating verbose/debian_kernel
(fenio@domek)~/pddp$
Jak widać podczas aktualizacji mamy ostrzeżenie o konflikcie. Świadczy o tym linia:
rcsmerge: warning: conflicts during merge
Dodatkowo zostaje utworzony ukryty plik z zawartością sprzed aktualizacji. W
tym przypadku nosi nazwę .#cvs.sgml.1.23. Jego zastosowanie
opisałem w poprzednim podrozdziale.
No dobrze, ale jak rozwiązać problem nakładających się zmian? Zmiany te wbrew pozorom zostały połączone, a jedynie miejsca konfliktowe są specjalnie oznaczone w pliku, który modyfikowaliśmy. W naszym przypadku miejsce konfliktu wygląda tak:
<<<<<<< cvs.sgml
Ala ma małego kotka.
======
Ala Kowalska nie ma kota.
>>>>>>> 1.24
System pokazuje nam obie wersje tego zdania. Zarówno naszą jak i poprzednika. Ty musisz zdecydować, która wersja jest poprawna. Ewentualnie jak połączyć obie wersje w całość, która w tym przypadku mogłaby wyglądać następująco:
Ala Kowalska ma lub nie ma małego kotka.
To jak zostaną połączone zmiany zależy od Ciebie. Gdy się już zdecydujesz, zmodyfikuj oznaczone miejsce. Zostaw tylko jedną wersję zdania i usuń linie zawierające <<<<<<< cvs.sgml, ======= oraz >>>>>>> 1.24. Musisz je usunąć! Inaczej będziesz otrzymywać ostrzeżenia, o nadal istniejących konfliktach.
Teraz możesz przesłać poprawioną wersję z powrotem do repozytorium. Wprowadź poniższe polecenie:
cvs commit -m "poprawka" pddp/pomoc/cvs.sgml
A oto jak wyglądać może jego wynik:
(fenio@domek)~/pddp$cvs commit -m "poprawka" pddp/pomoc/cvs.sgml
Checking in pddp/pomoc/cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.25; previous revision: 1.24
done
(fenio@domek)~/pddp$
Tym razem nasze poprawki zostały przesłane i naniesione bez przeszkód.
W większości wypadków koordynator troszczy się o dodawanie nowych plików do repozytorium. Może jednak zaistnieć potrzeba zrobienia tego samemu.
Należy to jednak wcześniej oznajmić na liście dyskusyjnej, podając nazwę pliku i miejsce jego lokalizacji. Następnie należy poczekać na komentarz bardziej zaawansowanego użytkownika.
Obostrzenia takie występują ze względu na to, iż CVS prowadzi historię wszelkich operacji. Dodanie pliku jest bardzo proste, ale jego usunięcie już niekoniecznie. Dlatego każda taka modyfikacja powinna być przemyślana i skonsultowana z resztą grupy. A już najlepiej po prostu sygnalizować potrzebę nowego pliku i czekać, aż założy go koordynator lub ktoś bardziej zaawansowany.
Aby jednak instrukcja, którą czytasz była pełniejszym opisem systemu CVS, wypada objaśnić sposób dodawania pliku.
Zakładam, że nadal znajdujesz się w katalogu głównym swojej lokalnej kopii
repozytorium, czyli ~/pddp.
Przyjmijmy, że w katalogu pddp/pomoc/ chcesz utworzyć plik o
nazwie edytor.sgml. Najpierw trzeba utworzyć go w lokalnej kopii
repozytorium. Można to zrobić poleceniem touch
pddp/pomoc/edytor.sgml. O tak założonym pliku należy poinformować
system CVS. Robimy to poleceniem cvs add pddp/pomoc/edytor.sgml.
Oto przykład wykonania takiego polecenia:
(fenio@domek)~/pddp$cvs add pddp/pomoc/edytor.sgml
cvs server: scheduling file `pddp/pomoc/edytor.sgml' for addition
cvs server: use 'cvs commit' to add this file permanently
(fenio@domek)~/pddp$
CVS poinformował nas, że plik ten został umieszczony w kolejce oczekującej na dodanie do głównego repozytorium. W tym momencie plik nie został jeszcze przesłany! W drugiej linii mamy informację, że należy użyć polecenia cvs commit by go przesłać.
Postępujemy więc według tej wskazówki. Ta część wygląda tak samo jak przy przesyłaniu poprawek zmienianych plików. Pamiętamy, że polecenie cvs commit jest interaktywnym sposobem na przesłanie pliku i powoduje uruchomienie się edytora w którym należy wprowadzić informację o przesyłanym pliku. Jeśli chcemy tego dokonać nieinteraktywnie, a ja przedstawię wynik właśnie takiej metody, stosujemy polecenie cvs commit -m "nowy plik" pddp/pomoc/edytor.sgml. Oto wynik takiego polecenia:
(fenio@domek)~/pddp$cvs commit -m "nowy plik" pddp/pomoc/edytor.sgml
RCS file: /home/cvs/pddp/pomoc/edytor.sgml,v
done
Checking in pddp/pomoc/edytor.sgml;
/home/cvs/pddp/pomoc/edytor.sgml,v <-- edytor.sgml
initial revision: 1.1
done
(fenio@domek)~/pddp$
Jak widać, niewiele różni się to od zwykłego przesyłania zmienionych plików. Otrzymujemy jedynie dodatkowe informacje o tym, że jest to pierwsza wersja tego pliku.
To również funkcja z której nie będziesz raczej korzystać. Ale tak jak poprzednio objaśnię ją, dla pełniejszego opisu systemu CVS.
Znowu przyjmuję, że znajdujesz się w katalogu ~/pddp. Załóżmy, że
chcesz usunąć plik, który przed chwilą dodaliśmy, a więc plik o nazwie
edytor.sgml z podkatalogu pddp/pomoc/. Aby to zrobić
musisz najpierw fizycznie usunąć plik, ze swojej lokalnej kopii repozytorium.
Wprowadź polecenie rm -f pddp/pomoc/edytor.sgml. Następnie należy
poinformować o tej zmianie system CVS. Służy do tego polecenie cvs
remove pddp/pomoc/edytor.sgml. Tak może wyglądać wynik tego polecenia:
(fenio@domek)~/pddp$cvs remove pddp/pomoc/edytor.sgml
cvs server: scheduling `pddp/pomoc/edytor.sgml' for removal
cvs server: use 'cvs commit' to remove this file permanently
(fenio@domek)~/pddp$
Tym razem zostaliśmy poinformowani, że plik edytor.sgml został
umieszczony w kolejce do usunięcia. W drugiej linii znowu mamy informację, o
tym, że żeby go całkowicie usunąć z głównego repozytorium należy wprowadzić
polecenie cvs commit. Tak jak wspominałem przy dodawaniu pliku,
jest to interaktywny sposób przesyłania informacji do repozytorium CVS. My
skorzystamy z metody nieinteraktywnej i wprowadzimy polecenie cvs commit
-m "usuwam plik" pddp/pomoc/edytor.sgml. A tak wygląda jego
efekt:
(fenio@domek)~/pddp$cvs commit -m "usuwam plik" pddp/pomoc/edytor.sgml
Removing pddp/pomoc/edytor.sgml;
/home/cvs/pddp/pomoc/edytor.sgml,v <-- edytor.sgml
new revision: delete; previous revision: 1.1
done
(fenio@domek)~/pddp$
Otrzymujemy informację o usunięciu pliku.
Ta możliwość również nie powinna Ci być potrzebna. Takimi rzeczami zajmuje się koordynator. Poza tym CVS nie przewiduje takiej operacji. Należy plik usunąć i dodać ze zmienioną nazwą. Poszczególne czynności są opisane w poprzednich podrozdziałach.
Nawet nie próbuj!
O ile w przypadku plików, pomyłki da się w miarę prosto "odkręcić", to z katalogami wygląda to o wiele gorzej.
Dlatego też w naszym repozytorium obowiązuje bezwzględny zakaz tworzenia katalogów. Potrzebę istnienia jakiegoś katalogu należy zgłosić na liście dyskusyjnej. Zostanie to przedyskutowane i wtedy koordynator założy odpowiedni katalog w dobrze przemyślanej lokalizacji, tak by nie okazało się w przyszłości, że trzeba zmienić jego nazwę lub umiejscowienie.
Jedynie dla celów informacyjnych (a nuż ktoś chce stworzyć własne repozytorium) napiszę, że katalogi dodaje się analogicznie do plików. Usuwanie niestety wymaga ingerencji w "środku" bazy danych całego repozytorium i jest operacją bardzo niezalecaną.
Wystąpił już wcześniej podrozdział o podobnej nazwie. Obiecałem w nim, że później znajdziesz więcej informacji na ten temat. Właśnie nadszedł czas spełnienia obietnicy.
Wiele razy korzystaliśmy z polecenia cvs update, które służy do synchronizacji naszej kopii lokalnej z głównym repozytorium. Teraz bliżej przyjrzymy się temu, co zwraca takie polecenie, a może to wyglądać tak:
(fenio@serwer)~/pddp$cvs update
? pddp/informacja
cvs server: Updating .
cvs server: Updating CVSROOT
cvs server: Updating pddp
cvs server: Updating pddp/pomoc
P pddp/pomoc/cvs.sgml
U pddp/pomoc/edytor.sgml
C pddp/pomoc/wstep.sgml
M pddp/pomoc/pomoc.sgml
cvs server: Updating pddp/skrypty
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
R verbose/debian_install/intro.sgml
cvs server: Updating verbose/debian_kernel
A verbose/debian_kernel/sound.sgml
(fenio@serwer)~/pddp$
Jak widać przy plikach pojawiają się tajemnicze znaki, takie jak ?, P, U, C, M, R oraz A. Warto wiedzieć co one oznaczają, ponieważ są to istotne dla nas informacje.
Znaczenia poszczególnych znaków są następujące:
Jeśli ilość wyświetlanych przez CVS informacji wydaje nam się za duża, można sprawić by program był mniej ,,gadatliwy''. W tym celu należy do poleceń dodawać opcję -q.
I jeszcze jedna dodatkowa informacja. Jeśli do repozytorium zostały dodane jakieś katalogi (z plikami) to zwykłe polecenie cvs update nie ,,zauważy'' ich i tym samym nie pobierze. W takich przypadkach należy wprowadzić polecenie cvs update -d.
Dzięki temu, że CVS trzyma w swojej bazie informacje o każdej wersji pliku, możliwe jest obejrzenie różnic pomiędzy dowolnymi wersjami. Oto przykład polecenia, które to realizuje:
(fenio@domek)~/pddp$cvs diff -r1.16 -r1.15 pddp/pomoc/lista.sgml
Index: pddp/pomoc/lista.sgml
===================================================================
RCS file: /home/cvs/pddp/pomoc/lista.sgml,v
retrieving revision 1.16
retrieving revision 1.15
diff -r1.16 -r1.15
12c12
< rozsyłana do skrzynek pocztowych wszystkich, którzy są na liście zapisani.
---
> rozsyłana na skrzynki pocztowe wszystkich, którzy są na liście zapisani.
(fenio@domek)~/pddp$
Za pomocą polecenia cvs diff wyświetliliśmy różnice pomiędzy
wersjami 1.16 i 1.15 pliku lista.sgml znajdującego się w
podkatalogu pddp/pomoc/. Jak widać wersje podajemy po opcjach
-r. W powyższym przykładzie widać, że pomiędzy tymi wersjami
nastąpiła zmiana jedynie jednego zdania. Najpierw wyświetlony jest tekst,
który znajduje się w wersji 1.16, a później ten z wersji 1.15. Obie wersje
rozdzielone są znakami ---.
Niektóre polecenia cvs posiadają swoje zamienniki lub skróty.
Dzięki temu można zmniejszyć długość wpisywanych poleceń. Na przykład zamiast
wpisywać cvs commit, wystarczy wpisać cvs ci.
Poniżej lista przedstawiająca zamienniki dla poleceń wykorzystanych w tym
dokumencie:
Opisałem tylko część możliwości programu cvs, ale przy pracy w
naszym projekcie wystarczy to w zupełności. Więcej informacji możesz uzyskać w
podręczniku systemowym (man cvs) lub na stronie domowej projektu
CVS, której adres to www.cvshome.org. Koniecznie
przeczytaj informacje ogólne o pracy z systemem CVS znajdujące się w części Informacje dodatkowe.
W następnych podrozdziałach opiszę sposób instalacji oraz korzystania z CVS pod systemem Windows 98 SE Pl, bo tylko taki mam pod ręką. Jeśli posiadasz inną wersję, musisz dokonać odpowiednich korekt samemu.
Będziemy potrzebować programu pozwalającego na korzystanie z systemu CVS.
Najlepszy jaki udało mi się znaleźć to WinCvs. Aktualna, stabilna
wersja to 1.2. Można ją pobrać z tego adresu: http://cesnet.dl.sourceforge.net/sourceforge/cvsgui/WinCvs120.zip
(~3,5MB) lub z oficjalnej strony http://www.wincvs.org.
Po pobraniu, rozpakowujemy archiwum na przykład korzystając z programu
Winzip (http://www.winzip.com).
Po rozpakowaniu klikamy na plik Setup.exe. Rozpoczyna się
właściwa instalacja.
Następnie klikamy cały czas na przycisk "Next", aż naszym oczom ukaże się monit z prośbą o ponowne uruchomienie komputera. Klikamy "Finish" i czekamy aż system ponownie się załaduje. Gdy to nastąpi oprogramowanie jest zainstalowane i gotowe do użycia.
Na początku utwórz gdzieś na swoim dysku folder, do którego chcesz pobrać
pliki. Może to być na przykład C:\PDDP. By utworzyć taki folder,
kliknij dwukrotnie "Mój komputer" następnie "C:". Teraz
gdzieś obok dostępnych ikonek kliknij prawym przyciskiem myszy i wybierz
"Nowy -> Folder". Wprowadź nazwę PDDP i naciśnij
Enter.
Teraz uruchom program WinCvs. By to zrobić klikamy:
"Start -> Programy -> Gnu -> WinCvs 1.2 -> WinCvs"
Po uruchomieniu pojawi się okno z różnymi poradami. Odznaczamy "Show Tips on StartUp" i klikamy "Close". Naszym oczom ukaże się okno o nazwie "WinCvs Preferences". W części oznaczonej jako "Enter the CVSROOT :" wprowadzamy:
:pserver:nazwa_konta@debian.linux.org.pl:/home/cvs
"nazwa_konta" zastępujemy przyznaną przez koordynatora nazwą. Następnie zmieniamy ustawienie "Authentication" tak by wskazywało na "passwd" file on the cvs server. Teraz przechodzimy na zakładkę "Globals" i odznaczamy opcję "Checkout read-only". Nic więcej nie zmieniamy i naciskamy OK.
Przyjrzyjmy się teraz jak wygląda główne okno programu. Górna część to tak jak
w większości programów różne menu oraz ikonki. W środkowej części mamy coś na
wzór Eksploratora Windows. Tutaj będziemy przeglądać pobrane
pliki oraz wykonywać większość operacji. Dolna część do okno komunikatów. To
istotne miejsce, gdyż tam CVS będzie informował nas o przebiegu swoich
operacji.
Zmienimy teraz jeszcze jedna opcję. Z menu "View" wybierz
"Browse Location -> Change...", a następnie wskaż katalog
C:\PDDP i kliknij OK.
Przejdźmy do pobierania plików z repozytorium. Zważ na to, że całe repozytorium to ponad 50MB! By to zrobić należy się najpierw zalogować. By to zrobić, klikamy menu "Admin -> Login...".
System poprosi nas o hasło (to które zatwierdził koordynator). Wprowadzamy je (w formie niezaszyfrowanej) i naciskamy Enter.
W dolnej części programu znajduje się okno komunikatów. Jeśli wszystko pójdzie w porządku, to ujrzymy:
*****CVS exited normally with code 0*****
Każdy inny komunikat oznacza, że coś poszło nie tak jak trzeba. Szczególnie chodzi o to by cyfra była równa 0.
Teraz pobierzmy pliki. Z menu "Create" wybierz "Checkout module...", a następnie w części "Enter the module name and path on the server :" wprowadzamy:
./
i klikamy OK. W oknie komunikatów powinny pojawić się wpisy tego typu:
cvs checkout -P ./ (in directory C:\PDDP)
cvs server: Updating .
cvs server: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg
cvs server: Updating pddp
U pddp/slownik.txt
U pddp/zasady.txt
cvs server: Updating pddp/pomoc
U pddp/pomoc/cvs.sgml
U pddp/pomoc/edytor.sgml
U pddp/pomoc/generuj
U pddp/pomoc/lista.sgml
U pddp/pomoc/pomoc.sgml
U pddp/pomoc/wstep.sgml
cvs server: Updating pddp/skrypty
U pddp/skrypty/generuj
U pddp/skrypty/pddp_check.pl
U pddp/skrypty/slownik
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
U verbose/debian_install/config.sgml
U verbose/debian_install/cycle.sgml
U verbose/debian_install/debian_install.sgml
U verbose/debian_install/generuj
U verbose/debian_install/introduction.sgml
U verbose/debian_install/main.sgml
U verbose/debian_install/preface.sgml
U verbose/debian_install/synaptic.sgml
U verbose/debian_install/xfree.sgml
cvs server: Updating verbose/debian_kernel
U verbose/debian_kernel/building.sgml
U verbose/debian_kernel/compiling.sgml
U verbose/debian_kernel/config.sgml
U verbose/debian_kernel/debian_kernel.sgml
U verbose/debian_kernel/ext3.sgml
U verbose/debian_kernel/generuj
U verbose/debian_kernel/intro.sgml
U verbose/debian_kernel/preface.sgml
U verbose/debian_kernel/sound.sgml
*****CVS exited normally with code 0*****
Lista pobranych plików z pewnością będzie dłuższa (w momencie pisania tych słów
- wrzesień 2004 - repozytorium zajmuje ponad 120MB). Dla zobrazowania zasady
działania wystarczy nam jednak wycinek tej listy. W tym momencie w katalogu
C:\PDDP utworzonych zostało kilka podkatalogów
(CVSROOT, pddp itd.). W nich znajdują się różne
pliki, począwszy od dokumentów, które tłumaczymy, poprzez różnego rodzaju
skrypty wspomagające naszą pracę, na słowniku projektu kończąc. Reasumując
stworzyliśmy lokalną kopię repozytorium.
W powyższym przykładzie w części "Enter the module name and path on the server :" umieściłem ./ co oznacza główny katalog repozytorium. Częściej stosowane są jednak nazwy konkretnych katalogów. Wtedy należy wpisać na przykład:
pddp
Pobrany zostałby tylko jeden katalog o nazwie pddp. Główne
katalogi repozytorium zwane są również modułami. Jednakże dla potrzeb naszego
projektu najlepiej pobrać wszystkie katalogi, tak jak zostało to pokazane.
Wszelkie operacje wykonywane przez CVS mogą korzystać z kompresji by zmniejszyć zapotrzebowanie na przepustowość łącza. Jest to szczególnie przydatne dla osób korzystających z modemów. Aby włączyć kompresję należy wybrać "Preferences..." z menu "Admin", a następnie na zakładce "Globals" zaznaczyć "Use TCP/IP compression". Dodatkowo można ustawić poziom tej kompresji. Im większa liczba tym kompresja jest bardziej wydajna, ale wolniejsza.
Zanim przystąpisz do edytowania jakiegoś pliku, musisz zainstalować i
skonfigurować jakiś inny niż domyślny edytor. Windowsowy Notatnik
nie nadaje się do edycji plików naszego projektu, ponieważ nie obsługuje
odpowiedniego kodowania. W części Edytory/Windows opisałem w jaki sposób
pobrać, zainstalować i skonfigurować edytor MiniPad.
Gdy masz już zainstalowany program MiniPad, trzeba ustawić
WinCvs by z niego korzystał. W tym celu z menu "Admin"
wybierz "Preferences...", następnie przejdź na zakładkę
"WinCvs". W części "Default viewer used to open files :"
wprowadź C:\MINIPAD\MINIPAD.EXE. Następnie zaznacz opcję
"Use on double click" i kliknij OK.
To wszystko. Od tej chwili WinCvs będzie korzystał z nowego
edytora.
Przed przystąpieniem do edycji jakiegoś pliku zawsze należy wykonać aktualizację lokalnej kopii. Pomocne mogą być również informacje dodatkowe.
By zaktualizować lokalną kopię repozytorium wystarczy kliknąć prawym
przyciskiem myszy na katalogu PDDP i wybrać "Update
selection...". Pojawi się okno o nazwie "Update settings". Nie
zmieniamy niczego i naciskamy "OK".
Więcej szczegółów i przykład jak może wyglądać wynik takiej operacji, znajduje się w dalszej części tego rozdziału. Na razie wystarczy Ci jedynie znajomość tej funkcji.
Po zmodyfikowaniu jakiegoś pliku, należy przesłać poprawki z powrotem do repozytorium.
By to zrobić kliknij prawym przyciskiem myszy na zmodyfikowanym pliku i wybierz "Commit selection...". Pojawi się okno o nazwie "Commit settings". W części "Enter the log message" należy wprowadzić opis dokonanych zmian. Następnie klikamy przycisk OK. W oknie komunikatów (dolna część) powinno pokazać się coś podobnego do poniższego przykładu:
cvs commit -m "przesyłam poprawki" cvs.sgml (in directory C:\PDDP\pddp\pomoc)
Checking in cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.40; previous revision: 1.39
done
*****CVS exited normally with code 0*****
System poinformował nas, że przesłał plik do repozytorium oraz, że po nałożeniu naszych zmian przyporządkował plikowi nowy, kolejny numer wersji (w tym przypadku 1.40).
Może się zdarzyć, że podczas gdy my nanosiliśmy poprawki na jakiś plik, w tym samym momencie robił to ktoś inny. Co więcej, załóżmy, że ta druga osoba przesłała już swoje zmiany do repozytorium. Co to oznacza?
Jak łatwo się domyśleć teraz nasze poprawki nie odnoszą się już do najnowszej wersji dokumentu. Co się stanie gdy spróbujemy przesłać nasze poprawki do repozytorium ?
Załóżmy, że wcześniej pobraliśmy z repozytorium plik cvs.sgml w
wersji 1.45. Dokonaliśmy własnych poprawek i teraz chcemy je przesłać.
Zgodnie z wcześniejszym podrozdziałem klikamy prawym przyciskiem myszy na tym
pliku i wybieramy "Commit selection...". Następnie wprowadzamy opis
dokonanych zmian i naciskamy OK.
W oknie komunikatów pojawi się coś takiego:
cvs commit -m konflikt cvs.sgml (in directory C:\PDDP\pddp\pomoc)
cvs server: Up-to-date check failed for `cvs.sgml'
cvs [server aborted]: correct above errors first!
*****CVS exited normally with code 1*****
Jak widać przesłanie nie powiodło się. CVS poinformował nas, że nasze modyfikacje nie odnoszą się do najświeższej wersji z repozytorium. Prosi o poprawienie tego. Sposób poprawienia zależy jednak od tego czy nasze zmiany znajdują się w tej samej części pliku czy nie. Poniżej opisuję obie sytuacje:
W takim przypadku system CVS powinien poradzić sobie z połączeniem naszych
zmian ze zmianami poprzednika i utworzeniem jednego pliku wynikowego. Powinien
to zrobić podczas aktualizacji lokalnej kopii repozytorium. Spróbujmy zatem.
Klikamy prawym przyciskiem myszy na katalogu PDDP i wybieramy
"Update selection...". W oknie "Update settings" nic nie
zmieniamy i naciskamy OK. Komunikaty powinny wyglądać mniej więcej tak:
cvs update -P (in directory C:\PDDP\)
cvs server: Updating .
cvs server: Updating CVSROOT
cvs server: Updating pddp
cvs server: Updating pddp/pomoc
RCS file: /home/cvs/pddp/pomoc/cvs.sgml,v
retrieving revision 1.45
retrieving revision 1.46
Merging differences between 1.45 and 1.46 into cvs.sgml
M pddp/pomoc/cvs.sgml
cvs server: Updating pddp/skrypty
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
cvs server: Updating verbose/debian_kernel
*****CVS exited normally with code 0*****
CVS przegląda całą lokalną kopię repozytorium i porównuje ją z główną
znajdującą się na serwerze. Pobiera informacje o zmianach w pliku
cvs.sgml i stara się połączyć je z naszą zmienioną wersją.
Informuje o tym w linii "Merging...". Operacja zakończyła się
sukcesem.
Dodatkowo CVS zapisuje plik oryginału z przed połączenia zmian. W naszym
przypadku plik ten otrzymał nazwę .#cvs.sgml.1.45, więc jak widać
w nazwie jest zapisana wersja. Plik ten jest zapisywany na wypadek gdybyśmy
chcieli sami sprawdzić czy CVS poprawnie połączył zmiany. Jeśli nie chcemy
tego robić można ten plik usunąć. Trzeba tego dokonać z poza programu
WinCvs. Można wykorzystać na przykład Eksploratora
Windows.
Teraz pozostaje nam przesłanie pliku z połączonymi zmianami do repozytorium. Robimy to dokładnie tak jak przedtem klikając na pliku prawym przyciskiem myszy i wybierając "Commit selections...". W oknie "Commit settings" wprowadzamy komentarz i klikamy OK.
A oto wynik w oknie komunikatów:
cvs commit -m "poprawiony konflikt" cvs.sgml (in directory C:\PDDP\pddp\pomoc)
Checking in cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.47; previous revision: 1.46
done
*****CVS exited normally with code 0*****
Tym razem nasze poprawki zostały przesłane i naniesione bez przeszkód.
Tutaj sytuacja trochę się komplikuje. Program komputerowy choćby nie wiem jak sprawnie napisany pozostanie programem. Nie posiada inteligencji i sam nie jest w stanie stwierdzić, które poprawki są prawidłowe. Czy te wprowadzone przez nas czy przez poprzednią osobę.
Aby przedstawić zasadę rozwiązywania problemów przy nakładających się na siebie zmianach posłużę się specjalnym przykładowym zdaniem, które będzie znajdować się w tym pliku i które będziemy modyfikować. Będzie to jedna linijka tak by łatwo można było wytłumaczyć na czym polega rozwiązywanie takich konfliktów. Oto nasze zdanie:
Ala ma kota.
Załóżmy, że pobraliśmy plik z repozytorium w wersji 1.47. Teraz stwierdziliśmy, że przykładowe zdanie należy zmodyfikować. Według nas ma ono brzmieć:
Ala ma małego kotka.
Ale niestety okazało się, że ktoś inny stwierdził, że to zdanie należy zmienić na:
Ala Kowalska nie ma kota.
Co więcej przesłał już swoją poprawkę do repozytorium i w tym momencie istnieje tam już wersja 1.48 z jego modyfikacją tego zdania. Ewidentnie mamy tu konflikt.
Co się stanie jak spróbujemy przesłać nasze poprawki ?
Oczywiście zostaną odrzucone z prośbą o aktualizację naszej kopii repozytorium (tak jak w przykładzie gdzie poprawki się nie nakładały). Nieświadomi, tego, że zmiany znajdujące się w głównym repozytorium konfliktują z naszymi (bo przecież nie możemy tego wiedzieć), przystępujemy do aktualizacji naszej kopii repozytorium.
Tak wyglądałby wynik takiej aktualizacji:
cvs update -P (in directory C:\PDDP\)
cvs server: Updating .
cvs server: Updating CVSROOT
cvs server: Updating pddp
cvs server: Updating pddp/pomoc
RCS file: /home/cvs/pddp/pomoc/cvs.sgml,v
retrieving revision 1.47
retrieving revision 1.48
Merging differences between 1.47 and 1.48 into cvs.sgml
rcsmerge: warning: conflicts during merge
cvs server: conflicts found in pddp/pomoc/cvs.sgml
C pddp/pomoc/cvs.sgml
cvs server: Updating pddp/skrypty
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
cvs server: Updating verbose/debian_kernel
*****CVS exited normally with code 0*****
Jak widać podczas aktualizacji mamy ostrzeżenie o konflikcie. Świadczy o tym linia:
rcsmerge: warning: conflicts during merge
Dodatkowo zostaje utworzony ukryty plik z zawartością z przed aktualizacji. W
tym przypadku nosi nazwę .#cvs.sgml.1.47. Jego zastosowanie
opisałem w poprzednim podrozdziale.
No dobrze, ale jak rozwiązać problem nakładających się zmian? Zmiany te wbrew pozorom zostały połączone, a jedynie miejsca konfliktowe są specjalnie oznaczone w pliku, który modyfikowaliśmy. W naszym przypadku miejsce konfliktu wygląda tak:
<<<<<<< cvs.sgml
Ala ma małego kotka.
======
Ala Kowalska nie ma kota.
>>>>>>> 1.24
System pokazuje nam obie wersje tego zdania. Zarówno naszą jak i poprzednika. Ty musisz zdecydować, która wersja jest poprawna. Ewentualnie jak połączyć obie wersje w całość, która w tym przypadku mogłaby wyglądać następująco:
Ala Kowalska ma lub nie ma małego kotka.
To jak zostaną połączone zmiany zależy od Ciebie. Gdy się już zdecydujesz, zmodyfikuj oznaczone miejsce. Zostaw tylko jedną wersję zdania i usuń linie zawierające <<<<<<< cvs.sgml, ======= oraz >>>>>>> 1.24. Musisz je usunąć! Inaczej będziesz otrzymywać ostrzeżenia, o nadal istniejących konfliktach.
Teraz możesz przesłać poprawioną wersję z powrotem do repozytorium. Robimy to dokładnie tak samo jak wcześniej. Kliknij na pliku prawym przyciskiem myszy i wybierz "Commit selection...". W oknie "Commit settings" wprowadź komentarz i naciśnij OK.
A oto jak może wyglądać informacja w oknie komunikatów:
cvs commit -m "konflikt rozwiązany" cvs.sgml (in directory C:\PDDP\pddp\pomoc)
Checking in cvs.sgml;
/home/cvs/pddp/pomoc/cvs.sgml,v <-- cvs.sgml
new revision: 1.49; previous revision: 1.48
done
*****CVS exited normally with code 0*****
Tym razem nasze poprawki zostały przesłane i naniesione bez przeszkód.
W większości wypadków koordynator troszczy się o dodawanie nowych plików do repozytorium. Może jednakże zaistnieć potrzeba zrobienia tego samemu.
Należy to jednak wcześniej oznajmić na liście dyskusyjnej, podając nazwę pliku i miejsce jego lokalizacji. Następnie należy poczekać na komentarz bardziej zaawansowanego użytkownika.
Obostrzenia takie występują ze względu na to, iż CVS prowadzi historię wszelkich operacji. Dodanie pliku jest bardzo proste, ale jego usunięcie już niekoniecznie. Dlatego każda taka modyfikacja powinna być przemyślana i skonsultowana z resztą grupy. A już najlepiej po prostu sygnalizować potrzebę nowego pliku i czekać, aż założy go koordynator lub ktoś bardziej zaawansowany.
Aby jednak instrukcja, którą czytasz była pełniejszym opisem systemu CVS, wypada objaśnić sposób dodawania pliku.
Załóżmy, że chcesz dodać plik o nazwie edytor.sgml w podkatalogu
pddp/pomoc/. Najpierw musisz utworzyć taki plik za pomocą
jakiegoś zewnętrznego programu. Nie można tego zrobić w WinCvs.
Gdy odpowiedni plik znajduje się już w podkatalogu zaznacz go i z menu
"Modify" wybierz "Add selection".
W oknie komunikatów ujrzysz:
cvs add edytor.sgml (in directory C:\PDDP\pddp\pomoc)
cvs server: scheduling file `pddp/pomoc/edytor.sgml' for addition
cvs server: use 'cvs commit' to add this file permanently
*****CVS exited normally with code 0*****
CVS poinformował nas, że plik ten został umieszczony w kolejce oczekującej na dodanie do głównego repozytorium. W tym momencie plik nie został jeszcze przesłany! W trzeciej linii jesteśmy powiadamiani, że należy o fakcie utworzenia pliku przesłać informację do repozytorium.
Postępujemy więc według tej wskazówki. Ta część wygląda tak samo jak przy przesyłaniu poprawek zmienianych plików. Klikamy prawym przyciskiem myszy na pliku i wybieramy "Commit selection...". W oknie "Commit settings" wprowadzamy komentarz i klikamy OK. W oknie komunikatów ujrzymy:
cvs commit -m "nowy plik" (in directory C:\PDDP\pddp\pomoc)
RCS file: /home/cvs/pddp/pomoc/edytor.sgml,v
done
Checking in pddp/pomoc/edytor.sgml;
/home/cvs/pddp/pomoc/edytor.sgml,v <-- edytor.sgml
initial revision: 1.1
done
Jak widać niewiele różni się to od zwykłego przesyłania zmienionych plików. Otrzymujemy jedynie dodatkowe informacje o tym, że jest to pierwsza wersja tego pliku.
To również funkcja z której nie będziesz raczej korzystać. Ale tak jak poprzednio objaśnię ją, dla pełniejszego opisu systemu CVS.
Załóżmy, że chcesz usunąć plik, który przed chwilą dodaliśmy, a więc plik o
nazwie edytor.sgml z podkatalogu pddp/pomoc/.
By usunąć plik z menu "Modify" wybierz "Remove selection". W oknie komunikatów ujrzysz:
'edytor.sgml' has been moved successfully to the recycle bin...
cvs remove edytor.sgml (in directory C:\PDDP\pddp\pomoc)
cvs server: scheduling `edytor.sgml' for removal
cvs server: use 'cvs commit' to remove this file permanently
*****CVS exited normally with code 0*****
Tym razem zostaliśmy poinformowani, że plik edytor.sgml został
umieszczony w kolejce do usunięcia. W drugiej linii znowu mamy informację, o
tym, że żeby go całkowicie usunąć z głównego repozytorium należy powiadomić o
tym system CVS. Robimy to klikając prawym przyciskiem na pliku i wybierając
"Commit selection...". W oknie "Commit settings"
wprowadzamy komentarz i naciskamy OK. W oknie komunikatów ujrzymy:
cvs commit -m "usuwam plik" edytor.sgml (in directory C:\PDDP\pddp\pomoc)
Removing edytor.sgml;
/home/cvs/pddp/pomoc/edytor.sgml,v <-- edytor.sgml
new revision: delete; previous revision: 1.7
done
*****CVS exited normally with code 0*****
Otrzymujemy informację o usunięciu pliku. Teraz pozostaje jeszcze fizyczne
usunięcie go z naszej lokalnej kopii repozytorium. Trzeba to zrobić z poza
programu WinCvs. Można wykorzystać na przykład Eksploratora
Windows. Musisz usunąć ten plik! W przeciwnym wypadku
będziesz otrzymywać komunikaty o nieznanym pliku.
Ta możliwość również nie powinna Ci być potrzebna. Takimi rzeczami zajmuje się koordynator. Poza tym CVS nie przewiduje takiej operacji. Należy plik usunąć i dodać ze zmienioną nazwą. Poszczególne czynności są opisane w poprzednich podrozdziałach.
Nawet nie próbuj!
O ile w przypadku plików, pomyłki da się w miarę prosto "odkręcić", to z katalogami wygląda to o wiele gorzej.
Dlatego też w naszym repozytorium obowiązuje bezwzględny zakaz tworzenia katalogów. Potrzebę istnienia jakiegoś katalogu należy zgłosić na liście dyskusyjnej. Zostanie to przedyskutowane i wtedy koordynator założy odpowiedni katalog w dobrze przemyślanej lokalizacji, tak by nie okazało się w przyszłości, że trzeba zmienić jego nazwę lub umiejscowienie.
Jedynie dla celów informacyjnych (a nuż ktoś chce stworzyć własne repozytorium) napiszę, że katalogi dodaje się analogicznie do plików. Usuwanie niestety wymaga ingerencji w "środku" bazy danych całego repozytorium i jest operacją bardzo niezalecaną.
Wystąpił już wcześniej podrozdział o podobnej nazwie. Obiecałem w nim, że później znajdziesz więcej informacji na ten temat. Właśnie nadszedł czas spełnienia obietnicy.
Wiele razy korzystaliśmy z funkcji "Update selection...", które służy do synchronizacji naszej kopii lokalnej z głównym repozytorium. Teraz bliżej przyjrzymy się temu co zwraca takie polecenie, a może to wyglądać tak:
cvs update -P (in directory C:\PDDP\)
? pddp/informacja
cvs server: Updating .
cvs server: Updating CVSROOT
cvs server: Updating pddp
cvs server: Updating pddp/pomoc
P pddp/pomoc/cvs.sgml
U pddp/pomoc/edytor.sgml
C pddp/pomoc/wstep.sgml
M pddp/pomoc/pomoc.sgml
cvs server: Updating pddp/skrypty
cvs server: Updating verbose
cvs server: Updating verbose/debian_install
R verbose/debian_install/intro.sgml
cvs server: Updating verbose/debian_kernel
A verbose/debian_kernel/sound.sgml
*****CVS exited normally with code 0*****
Jak widać przy plikach pojawiają się tajemnicze znaki, takie jak ?, P, U, C, M, R oraz A. Warto wiedzieć co one oznaczają, ponieważ są to istotne dla nas informacje.
Znaczenia poszczególnych znaków są następujące:
Jeśli ilość wyświetlanych przez WinCVS informacji wydaje nam się za duża, można sprawić by program był mniej ,,gadatliwy''. W tym celu należy wybrać "Preferences..." z menu "Admin", a następnie na zakładce "Globals" zaznaczyć opcję "Quiet mode (less messages)".
I jeszcze jedna dodatkowa informacja. Jeśli do repozytorium zostały dodane jakieś katalogi (z plikami) to zwykła funkcja "Update selection..." nie ,,zauważy'' ich i tym samym nie pobierze. W takich przypadkach należy po wybraniu funkcji "Update selection..." zaznaczyć dodatkową opcję "Create missing directories that exist in the repository". W wyjątkowych sytuacjach, tj. gdyby nadal nie udało się pobrać nowych katalogów, można zaznaczyć jeszcze opcję "Reset any sticky date/tag/'-k' option".
Dzięki temu, że CVS trzyma w swojej bazie informacje o każdej
wersji pliku, możliwe jest obejrzenie różnic pomiędzy dowolnymi wersjami.
Spróbujmy wyświetlić różnice pomiędzy wersją 1.16 oraz 1.15 pliku
lista.sgml z podkatalogu pddp/pomoc/. W tym celu
klikamy na pliku i wybieramy "Diff selection". W oknie "Diff
settings" zaznaczamy "Compare two revisions/tags/branches/dates
:" i wprowadzamy w pierwszym okienku 1.16, a w drugim
1.15. Oto wynik takiej funkcji:
cvs diff -r 1.16 -r 1.15 lista.sgml (in directory C:\PDDP\pddp\pomoc)
Index: lista.sgml
===================================================================
RCS file: /home/cvs/pddp/pomoc/lista.sgml,v
retrieving revision 1.16
retrieving revision 1.15
diff -r1.16 -r1.15
12c12
< rozsyłana do skrzynek pocztowych wszystkich, którzy są na liście zapisani.
---
> rozsyłana na skrzynki pocztowe wszystkich, którzy są na liście zapisani.
*****CVS exited normally with code 1*****
W powyższym przykładzie widać, że pomiędzy tymi wersjami nastąpiła zmiana jedynie jednego zdania. Najpierw wyświetlony jest tekst, który znajduje się w wersji 1.16, a później ten z wersji 1.15. Obie wersje rozdzielone są znakami ---.
Niektóre funkcje WinCvs posiadają skróty klawiaturowe. Na
przykład zamiast klikać prawym przyciskiem myszy i wybierać "Commit
selection..." wystarczy wcisnąć kombinację "CTRL+M". Poniżej
lista przedstawiająca skróty dla funkcji wykorzystanych w tym dokumencie:
Opisałem tylko część możliwości programu WinCvs, ale przy pracy w
naszym projekcie wystarczy to w zupełności. Więcej informacji możesz uzyskać w
pomocy do programu lub na stronie domowej projektu CVS, której adres to
www.cvshome.org. Koniecznie
przeczytaj informacje ogólne o pracy z systemem CVS znajdujące się w części
Informacje dodatkowe.
To już prawie wszystko co powinieneś wiedzieć o korzystaniu z systemu CVS. Poniżej jeszcze tylko kilka uwag odnośnie pracy.
Synchronizuj swoją lokalną kopię z głównym repozytorium jak najczęściej. Przystępując do pracy nad plikiem najpierw go zaktualizuj. Gdy skończysz pracę, prześlij poprawki jak najszybciej. Gdy zamierzasz edytować dużą część pliku przesyłaj poprawki w trakcie pracy (na przykład po skończeniu poszczególnych rozdziałów). To wszystko pozwoli zminimalizować ryzyko wystąpienia konfliktów.
Jak już wspomniałem CVS używa numerów wersji by móc rozróżniać zmiany w plikach. Jako, że te numery wersji nie dla wszystkich wydają się oczywiste to poniżej małe objaśnienie.
Załóżmy, że mamy numerki 1.2 i 1.12. Który z nich jest większy? Mogłoby się wydawać, że 1.2 gdyż liczba po kropce jest większa niż w drugim numerze. Nic bardziej mylnego. Porównujemy całe liczby występujące po znaku kropki, więc w tym wypadku 2 oraz 12. Oczywiste jest, że 12 jest większe, a tym samym 1.12 jest wersją powstałą później, a więc bardziej zaawansowaną niż wersja 1.2.
Powiadom, poprzez listę dyskusyjną, innych grupowiczów o tym co edytujesz. Nie musisz tego oczywiście robić w przypadku poprawiania małych błędów. Na przykład literówek. Ale przy przystępowaniu do tłumaczenia dużego pliku lub jego części jest to bardzo wskazane. Nikt nie będzie wtedy grzebał w tym samym miejscu i są mniejsze szanse na konflikty.
Jeśli masz jakiś problem, to nie próbuj samemu kombinować i wykorzystywać
bardziej zaawansowane i co gorsza nieznane Ci funkcje CVS.
Pamiętaj, że masz nieograniczony dostęp do repozytorium i możesz niechcący
dokonać poważnych szkód. W razie problemów pytaj więc na liście dyskusyjnej, a
z pewnością ktoś Ci pomoże.
Często na liście pojawia się stwierdzenie typu "commit". Jeśli ktoś stwierdza, że zrobił "commit" to oznacza ono po prostu, że ktoś przesłał swoje poprawki do CVS. Analogicznie jeśli ktoś prosi o "commit", to oznacza, że prosi o przesłanie poprawek.
Mogą również pojawić się "koślawe spolszczenia" tego określenia. Na przykład "commitnąłem", "kommitnąłem", "kommitłem" czy coś w tym rodzaju.
Istnieje możliwość przeglądania repozytorium poprzez strony WWW.
Jeden z interfejsów dostępny jest pod adresem http://debian.linux.org.pl/cgi-bin/viewcvs.cgi
Na głównej stronie widać wszystkie katalogi. Możesz się po nich poruszać tak j
ak po drzewie katalogów w swoim systemie operacyjnym.
Klikając na jakiś plik, otrzymasz informacje o poszczególnych wersjach wraz z komentarzami. Najbardziej przydatną funkcją jest przeglądanie zmian dokonanych pomiędzy poszczególnymi wersjami. System prezentuje je w bardzo przystępnej (pokolorowanej) formie. By wyświetlić takie informacje należy na dole strony opisującej jakiś plik, wprowadzić numery wersji, a następnie kliknąć "Get Diffs".
Klikając "Display revisions graphically" otrzymasz graficzne drzewo prezentujące kolejne zmiany.
Zawartość każdego katalogu możesz pobrać klikając "Download tarball". System automatycznie wygeneruje najnowsze archiwum.
Drugim dostępnym interfejsem jest CVS Monitor. Można go znaleźć
pod adresem http://debian.linux.org.pl/cgi-bin/cvsmonitor/cvsmonitor.pl.
Oferuje podobną funkcjonalność do ViewCVS, a dodatkowo różne
statystyki, informacje o ostatnio przesłanych zmianach itp.
PDDP - Jak pomóc?
v0.64 11 kwiecień 2006fenio@debian.org