Jak używać kontroli wersji

… a jak nie?

Prawdopodobnie każdy, kto przynajmniej raz próbował na poważnie programować, zetknął się z systemami kontroli wersji. W firmach deweloperskich czy działach IT korporacji(no może trochę mniej), cvs czy svn jest wręcz podstawowym narzędziem (przynajmniej powinien być). Niestety, często nie jest to dobrze wykorzystywane narzędzie. Często svn kończy jako takie łatwiejsze w obsłudze narzędzie do tworzenia kolejnych kopii folderów, a nawet w pewnych sytuacjach zaczyna tworzyć więcej utrudnień niż rozwiązuje ich rozwiązuje.

Omawiane problemy nie dotyczą „niskopoziomowego” wykorzystania svn-a, czyli umiejętności zrobienia repozytorium i pobrania czy zapisania danych. O ile repozytoria są przeważnie dobrze założone,  praktycznie każdy umie wykonać commit czy utworzyć i aktualizować lokalną kopię, to ogólna koncepcja  zastosowania kontroli wersji w swojej pracy leży.Czyli – wiemy jak użyć młotka do wbicia gwoździa, ale po co te gwoździe, w co je wbić,  jak dużo i gdzie  to już nie bardzo.

Zakładam, że czytający posiadają podstawową wiedzę w zakresie użycia svna. Nie będę zajmował się tym jak zrobić commit czy checkout, jak stworzyć repozytorium itd., lecz przejdę do koncepcji zastosowania systemów kontroli wersji.

Co to kontrola wersji?

Zacznijmy od tego czym właściwie jest kontrola wersji. Przed użyciem jakiekolwiek narzędzia warto się zastanowić po co i do czego ma służyć.  Powód „bo jest modne i koledzy też to mają” nie jest wystarczający. Oczywiście na to pytanie, każdy powinien sobie odpowiedzieć sam, jednak wśród najczęstszych przyczyn użycia narzędzi do wersjonowania kodu można wymienić:

  • wspólną, jednoczesną pracę wielu osób nad tym samym plikiem/zbiorem plików
  • możliwość przywrócenia dowolnego stanu wcześniejszego
  • wskazanie na osobę odpowiedzialną za wprowadzoną zmianę
  • prowadzenie wielu ścieżek rozwoju kodu czy dokumentu

Najważniejsze problemy

Anemicznym repozytoriom mówimy nie

W zasadzie część ciężko nazwać popełnieniem błędu – w zasadzie jest to NIE użycie możliwości jakie daje narzędzie.  Najczęściej wygląda to tak: powstaje repozytorium, do repozytorium jest wrzucony początkowy kod i tyle. Repozytorium nie ma żadnej struktury, nie ma żadnych zasad zapisu do niego, kod ląduje w głównym katalogu, jedyne wykorzystywane funkcje to commit i checkout. Dalszy rozwój idzie sobie tak po prostu, kod jest ściągany i wprowadzany do repozytorium wg. uznania użytkownika.

Czyli tak – co prawda mamy system tworzenia kopii (wersji), wersje są poprawnie tworzone, można ustalić kto jest odpowiedzialny za jaki kawałek kodu (dobrze, nie zawsze ale to dalej*), ale nic więcej:

  • nie można wziąć kodu z pnia repozytorium i być pewnym jego stanu – skoro każdy tam wrzuca i nie ma żadnych zasad tych działań, to może się znaleźć kod który nie daje się nawet uruchomić
  • użytkownicy mają problem z rozpoczęciem dużych prac, typu zmiana struktury projektu, bo albo zaprzestaną wersjonowania swojej pracy albo utrudnią pracę innym
  • tak naprawdę wiele osób nie może jednocześnie pracować, przynajmniej nie w zespołach większych niż 3 osoby – kod jest r

* Wersja ekstremalna – jest repozytorium, są commity, ale commity są robione przez jednego użytkownika. Nie dlatego, że jest to jednoosobowy projekt. Dlatego,  że np. nikt o tym nie pomyślał i z lenistwa utworzono jednego usera dla repozytorium, lub też z powodu organizacji sieci, serwerów itp, tylko jeden użytkownik może się zalogować do danego komputera z repozytorium.

Free as a bird

Czyli każdy robi co chce (z repozytorium oczywiście). Nie ma ustalonych zasad wykorzystania narzędzia,  każdy użytkownik wymyśla więc własne i wg. nich pracuje. W efekcie, tworząc nową kopię z repozytorium, nie można określić w jakim jest stanie, np. czy zawiera najnowszą wersję pracy wszystkich, czy też jest echem zamierzchłej przeszłości, bo każdy komituje najwyżej co 2 tygodnie, czy w ogóle pobrany kod da radę uruchomić, bo przecież nie ustalono że w repozytorium ma się znaleźć tylko działający kod.

Kosz na śmieci

Problem częściowo związany z poprzednim – jeżeli nie ma określonych zasad korzystania, to nie jest też określone co powinno się znaleźć w repozytorium.  Czyli trafiają tam wszelkie możliwe śmieci jakie znajdą się w katalogu kopii lokalnej – pliki tymczasowe edytora, lokalne konfiguracje IDE, dane sesji testowych. Z drugiej strony, zjawisko związane z pojęciem „zarządzanie konfiguracją”, a właściwie z brakiem takiego zarządzania –  do repozytorium nie trafiają rzeczy które są istotne, wręcz konieczne, do uruchomienia kodu – np. informacje o wykorzystywanych bibliotekach.

Kontrola wersji, kontrolą wersji, ale ja wiem lepiej

Ponownie sytuacja związana z zarządzaniem konfiguracją, a właściwie brakiem takowej. Objawy najczęściej przyjmują postać:

  • ” to ja tu szybko poprawię na serwerze” – czyli programista zamiast wprowadzić zmianę w lokalnej kopii, zrobić commit, utworzyć pakiet instalacyjny i go uruchomić, poprawia kod bezpośrednio w już zainstalowanym pakiecie
  • „przecież to mała zmiana, to po co zmieniać wydanie” – trochę łagodniejszy objaw – poprawka co prawda trafia do repozytorium, ale nie jest to odnotowywane w zmianie wersji czy wydania

Problem można podsumować krótko – dokonywanie zmian w kodzie poza systemem kontroli wersji.

A po co mi te wszystkie bajery

Narzędzia do zarządzania repozytorium dostarczają sporą liczbę możliwości ułatwiających życie. Wiele z nich jest tak prostych użyciu, że aż szkoda ich nie stosować. Jednym z takich ułatwień jest po porostu log. Miejsce w którym można wpisać dowolną informację, a w szczególności krótkie podsumowanie zmian które są wprowadzone w danym commicie.

Co zrobić

Koncepcja zastosowania i użytkowania repozytorium

Przede wszystkim należy zacząć od zastanowienia się pod co nam to całe repozytorium, do czego ma służyć, jaką wartości ma nam dostarczyć. Na tej podstawie możemy określić

  • strukturę repozytorium – bo dobre repozytorium ma przemyślaną organizację katalogów, głównego pnia, gałęzi rozwojowych itd
  • zasady wykorzystania repozytorium – czyli procedury postępowania z repozytorium, reguły wg. których działamy, ograniczenia których nie można przekraczać
  • zarządzanie konfiguracją – określenie tego nad czym pracujemy, jak będziemy to coś zmieniali i jak będziemy postępowali na styku przygotowywany produkt a otoczenie w jakim działa

Używaj prawidłowo narzędzi i możliwości dostarczanych przez system

…lub też „1.0-SNAPSHOT is no more”.  Systemy zarządzania wersjami poza „zwykłym” odkładaniem kolejnych wersji zapewnia także zbiór innych narzędzi, które mają pomóc w prowadzeniu dewelopmentu.

Świetnym przykładem jest tutaj wstawiany z automatu w plikach pom.xml 1.0-SNAPSHOT jako oznaczenie wersji. Maven przy generowaniu pliku umieszcza taki zapis bo ktoś tak przyjął i nie ma tu nic złego – cokolwiek innego nie różniło by się jakościowo od tego rozwiązania, jednak założeniem jest, że to oznaczenie wersji powinno odzwierciedlać faktyczną wersję oprogramowania. Rzadko jednak można spotkać się z faktyczną aktualizacją tej zmiennej. W efekcie, zespoły pracujące wersją 0.0.1 oprogramowania w pom.xml mają dumnie wpisane 1.0. A wystarczy wykorzystać taką niewielką funkcję svna jak podstawianie taga ($Revision$) w plikach, lub bardziej zaawansowany sposób przy pomocy hook script.

Nie mówiąc o bardziej podstawowych funkcjach, takich jak narzędzia wspierające kopiowanie, przenoszenie, usuwanie plików z kopii roboczej lub repozytorium z zachowaniem śledzenia wersji.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *