System kontroli wersji, system zarządzania kodem źródłowym (ang. version/revision control system) VCS albo RCS Source control or (source) code management (SCM) Teoria Co to jest? Po co nam taki system kontroli wersji czy system zarządzania kodem źródłowym? Co nam daje użycie takiego narzędzia? To jest takie narzędzie dla programistów i nie tylko ułatwiające zarządzanie kodem źródłowym (plikami i/lub ich zawartością) lub innymi zasobami... Co nam to daje? Śledzenie rozwoju naszego projektu od początku do stanu aktualnego. Możliwość powrotu do każdej poprzedniej wersji (revert) jeśli była ona zatwierdzona (commit). Jak z projektem pójdziemy w ślepą uliczkę to zawsze jest możliwość powrotu. Jeśli mam więcej niż jeden komputer (miejsce pracy) to dzięki RCS mogę z łatwością pracować na każdym z moich miejsc pracy? Zawsze aktualna wersja mojej pracy (mam jakiś serwer i tam przechowuję aktualną wersję). Wykorzystanie serwera zapewnia nam zawsze aktualną kopię bezpieczeństwa tego co zrobiliśmy. Jeśli chcemy pisać program w kilka osób to można używać poczty e-mail i przesyłać pliki źródłowe czy całe paczki ale znacznie lepiej użyć RCS'a, co bardzo ułatwi wszystkim pracę. Szczególnie ważne w firmach tworzących oprogramowanie. Co jeszcze?... Scentralizowany a rozproszony system kontroli wersji
Zalety rozproszonego scm: Nie boisz się o stratę danych bo wiele ludzi ma uaktualnione (merge) twoje zmiany i to na pewno nie zginie,. Nie trzeba sprawdzać kto ma dostęp do głównego repozytorium i czy coś zepsuje czy nie, bo i tak każdy ma własne repozytorium (nie ma tu kwestii polityki, bierze się od tego kto ma najlepszy kod) Jak 5 osób pracuje nad tą samą częścią projektu, jakąś eksperymentalną, to powinni mieć oni własne drzewo projektu, a główne drzewo idzie swoim torem. Sposób tworzenia oprogramowania jest w ogóle rozproszony, to jest całkowicie inny świat, inny sposób myślenia o tworzeniu oprogramowania, ktoś sobie coś zaprogramuje i jak to się innym (większości) spodoba to ta gałąź jest dalej rozwijana a reszta się dołącza lub nie, mogą sobie stworzyć własną wersję/galąź lub nie, pełna swoboda bo każdy ma własne repozytorium. Fajne - (network of trust) nie muszę pilnować praw dostępu do serwera centralnego bo każdy ma aktualny stan i ja pozwalam na zmianę mojego repozytorium tylko tym, do których mam zaufanie. Ważne jest: How fast can you merge Dwa sposoby działania: Wysyłamy paczki do nadzorującego gałąź główną Każdy ma dostęp i robimy bzr push. Wybieramy opcję 2 czyli bzr push, gdzie każdy ma dostęp do głównej gałęzi projektu.
Praktyka Ćwiczenie 1 hello Piszemy sobie program Hello World. (Repozytorium jednoosobowe, samodzielny projekt) mkdir hello cd hello touch main.cpp vim/nano/kwrite/... main.cpp // piszemy program g++ -o -Wall -pedantic main main.cpp // kompilujemy program bzr init // Tworzenie własnego repozytorium, patrzymy co jest w kadalogu.bzr Tworzymy sobie jeden czy dwa pliki źródłowe (mkdir hello; cd hello; touch main.cpp) Edytujemy i kompilujemy (vim/nano/kwrite/... main.cpp; g++ -o -Wall -pedantic main main). Tworzenie własnego repozytorium (bzr init), patrzymy co jest w kadalogu.bzr Sprawdzamy jaki jest stan naszego repozytorium (bzr status, bzr st) Dodajemy pliki, które mają podlegać kontroli (bzr add),. Ustalamy, które pliki chcemy ignorować (bzr ignore) np. plik wykonywalny. Jak się pomyliliśmy czy zmieniliśmy zdanie to możemy wycofać kontrolę wersji dla jakiegoś pliku (bzr remove). Podglądamy jak wyglądają nasze zmiany dokonane w repozytorium w stosunku do ostatniej zatwierdzonej wersji (bzr diff). Zatwierdzamy dokonane zmiany (jeśli kod się kompiluje i nasze zmiany tworzą logiczną całość) (bzr commit -m "asdf...", bzr ci) Podglądamy jak wygląda nasze repozytorium (bzr log). Dodajemy funkcję, która policzy nam sumę liczb naturalnych mniejszych od 1000 podzielnych przez 7. Sprawdzamy: bzr status i bzr diff, bzr log. Kompilujemy, uruchamiamy. Znowu sprawdzamy bzr status, bzr diff, bzr log. Jak wszystko działa to robimy commit. I sprawdzamy jeszcze raz: bzr status, bzr diff, bzr log --line. Dodajemy obsługę parametrów uruchamiania programu: pierwszy parametr to górna granica sumy liczb naturalnych drugi to wartość przez jaką dane liczby mają być podzielne Sprawdzamy: bzr status i bzr diff, bzr log. Kompilujemy, uruchamiamy. Znowu sprawdzamy bzr status, bzr diff, bzr log. Jak wszystko działa to robimy commit. I sprawdzamy jeszcze raz: bzr status, bzr diff, bzr log --line. Cofamy się do wybranej wersji: bzr revert -r 2 I sprawdzamy: bzr status, bzr diff, bzr log --line, bzr log -r 2. Eksportujemy wybraną wersję: bzr export hello.zip albo bzr export../hello/tar.gz albo bzr export../inny_katalog
Ćwiczenie 2 szp_info Info o każdym uczniu - jeden wspólny plik źródłowy (praca wieloosobowa na jednym pliku!!!!) (pull i push) Tworzymy jeden wspólny projekt ale nie robimy tego w tym samym czasie. Scenariusz pierwszy - prosty Rob, Kam, Mar,... Robert WSZYSCY Marek Kamil -- ------ -------------- -- -------- -------------- -------> i b p a p a i - inicjalizacja głównego repozytorium (bzr init, bzr add ignore remove, bzr ci, bzr push) b - tworzenie własnej gałęzi głównego repozytorium (bzr branch) p - pobieranie aktualnej wersji a - aktualizacja zmian we wspólnym repozytorium Kolejność czynności tworzenia tego projektu: 1 - Robert Robert robi main i info o sobie. Robert robi inicjalizuje repozytorium (bzr init). Robert dodaje pliki do repozytorium (bzr add, bzr ignore). Robert zatwierdza zmiany (bzr ci). Robert tworzy repozytorium na wspólnym serwerze (bzr push): bzr push --create-prefix sftp://szp1@sieve.icis.pcz.pl/~/szp_info 2 - WSZYSCY Wszyscy poza Robertem robią sobie swoją własność wspólnego projektu (bzr branch): bzr branch sftp://szp1@sieve.icis.pcz.pl/~/szp_info Można sobie pooglądać jak nasz kod wygląda, czy się kompiluje, czy działa (bzr log, bzr st). 3 - Marek Marek aktualizuje sobie swoje repozytorium z tym co mamy aktualnie w repozytorium źródłowym (tym z którego mamy naszą wersję/galąź). bzr pull sftp://szp1@sieve.icis.pcz.pl/~/szp_info Marek dodaje swoją funkcję do pliku (wprowadza swoje zmiany do pliku źródłowego). Marek zatwierdza wprowadzone przez siebie zmiany (bzr ci). Marek aktualizuje dokonane przez siebie zmiany na repozytorium centralnym (bzr push). bzr push sftp://robert@sieve.icis.pcz.pl/~/szp_info WSZYSCY mogą sobie teraz repozytorium zaktualizować: bzr pull sftp://szp1@sieve.icis.pcz.pl/~/szp_info /// bzr merge sftp://robert@sieve.icis.pcz.pl/~/szp_info // trzeba jeszcze potem robic commit 4 Wojtek robi to samo co marek tylko dodaje info o sobie... Można jeszcze JEDNOCZEŚNIE popracować nad plikiem Makefile i spróbować robić bzr merge...
Ćwiczenie 3 bzr_doc (praca zespołowa na wielu plikach) Każda osoba ma osobny plik nagłówkowy od nazwy jakiegoś polecenia z systemu bazaar np.: W każdym z tych plików mamy funkcję o nazwie: nazwa_polecenia_doc(), np. init_doc() albo status_doc() Nazwa identyczna jak cała nazwa polecenia w bzr, diff, status, log, add, push,... bzrinit.h bzrstatus.h bzrdiff.h bzrlog.h bzrbranch.h bzradd.h, bzrignore.h bzrpush.h bzrpull.h Makefile main.cpp Jak taki projekt robić? Najpierw jedna osoba robi main i Makefile. Kompiluje, robi commit i wysyla na serwer. Każdy sobie robi pull z serwera. Każdy dodaje swój własny plik nagłówkowy i kompiluje i robi własny commit i teraz najważniejsze!!!! Osoba robi merge z serwera czyli łączy swoją zawartość z tym co było na serwerze i ma u siebie już połączone. Robi na tym połączonym commit i robi push na serwer. I na serwerze jest aktualna wersja, powinna być :) I tak samo robią wszyscy, w teorii powinno działać, ale praktyka bywa wymagająca.