git - system kontroli wersji

System kontroli wersji (inaczej wersjonowania) jest niezbędny w pracy każdego dewelopera. Zresztą nie tylko, bo wykorzystać go można niemal na każdym kroku - począwszy od wersjonowania pracy dyplomowej, a kończąc na kopiach zapasowych listy zakupów (czemu nie? Winking). Ale powiedzmy, że na kodowaniu poprzestanę, choć należy pamiętać, że nie jest to jedyne co te systemy mogą dla nas zrobić.

Powody korzystania z narzędzi do wersjonowania kodu (czyż to nie nadużycie? bo przecież nie tylko o kod tu chodzi...) są dwa (podstawowe):
  • zamrożenie pewnego stanu pliku (np. kodu źródłowego) i umożliwienie powrotu do niego
  • wspólna praca zespołu deweloperskiego na tych samych plikach i wsparcie do łączenia zmian (często automatyczna, w spornych momentach wykonywana ręcznie).
Ale to nie koniec Happy Bazując na zaletach i możliwościach, które te systemy dostarczają powszechne stało się także:
  • weryfikacja zmian pomiędzy poszczególnymi wersjami (lub wobec naszej, "brudnej" wersji)
  • weryfikacja, kto i kiedy dokonał jakiejś zmiany
  • weryfikacja, kto jest odpowiedzialny za daną linijkę w kodzie Happy
  • podział prac na kilka wątków umieszczanych w tzw. gałęziach (ang. branch), a potem łączenie zmian w głównym wątkiem (nazywanym z ang. head).


Najpopularniejsze systemy to SVN, który mocno wyparł powszechnie kiedyś używanego CVS'a. Wspierane są przez chyba wszystkie narzędzia deweloperskie. Ich popularność wzięła się po części z faktu, że są dostępne bez opłat, także do zastosowań komercyjnnych.
Obok żyją sobie mniej lub bardziej wyspecjalizowane narzędzia (płatne), jednak nie osiągają one tej popularności co wspomniane powyżej SVN oraz CVS. Jak to mówi telewizyjna reklama -
skoro nie widać różnicy, to po co przepłacać?

Sam powyższych systemów używam na co dzień, ale za każdym razem wkurzają mnie swoimi założeniami:
  • Dlaczego w każdym katalogu, który ma być wersjonowany (wewnątrz roota) muszę mieć katalog kontrony (cvs, .svn)?
  • Dlaczego nie mogę sobie po prostu przenieść katalogu w inne miejsce bez korzystania z narzędzia (które dokona odpowiednich zmian w tych katalogach kontrolnych, bez których to zaczną się dziać dziwne rzeczy).
  • Dlaczego chcąc pozbawić całego drzewa przynależności do repozytorium muszę wykonać coś w stylu:
    for f in `find . -name CVS`; do rm -rf $f; done
  • Dlaczego jak zmieni się adres repozytorium (np. korzystaliśmy z IP zamiast nazwy lub uległa ona zmianie) to jest to problem (w CVS'ie konieczność zmiany pliku w każdym katalogu kontrolnym, w SVN'ie podobnie, choć jest opcja relokacji, która jednak - z doświadczenia - czasem nie działa tak jak byśmy się spodziewali).

I takie tam podobne, życiowe roztargnienia. Większość z nich związana jest właśnie z tym rozproszeniem danych o przechowywanych w repozytoriach plików. Postanowiłem zatem poszukać czegoś innego. Okazało się, że nie musiałem daleko szukać... Szybko natrafiłem na system
GIT, który - jak się okazało - jest rewelacyjny. Nie tylko rozwiązuje wszystkie moje rozterki, to jeszcze dodaje kilka cech, które naprawdę trudno przecenić. Aż dziw, że nie spotkałem się z nim wcześniej Happy

O samym systemie warto sobie troszkę poczytać. Kilka linków umieściłem na końcu postu (bo i tak się stał przydługi), ale w telegraficznym skrócie:
  • JEDEN katalog (.git) umieszczony w korzeniu projektu zawierający wszystkie informacje o danych z repozytorium.
  • Swoboda przenoszenia plików wewnątrz wersjonowanego drzewa plików - bo istotne jest położenie pliku, a nie to gdzie był kiedyś.
  • Nie potrzebumy żadnego serwera, całość odbywa się na naszym filesystemie (ściślej nasz wersjonowany katalog jest naszym repozytorium).
  • Jest to system rozproszony, gdzie każdy posiada identyczną kopię, co skutkuje ważnymi zaletami, m.in.:
    • odporność na awarię serwera (nawet jak padnie to mamy całą historię, a nie tylko ostatnio ściągnięty stan),
    • błyskawiczną kontrolę co się działo, kto i za co jest odpowiedzialny (bo wszystko jest u nas na komputerze),
    • dostępność do repozytorium (w tym także komitowanie, updejtowanie, itp itd) bez dostępu do sieci (np. w domu czy na wakacjach - szczególnie ważne dla niezależnych lub pracocholików), a potem możliwość wysłania zmian na serwer.
  • Rozdzielenie operacji komitowania od wysyłania na serwer. Zalet jest cała masa, m.in.:
    • szybkość - cała operacja wykonywana jest lokalnie, zatem błyskawicznie,
    • brak konieczności posiadania jakiejkolwiek sieci,
    • możliwość "ściągnięcia" takiej zakomitowanej wersji (gdzie źródłem będzie nasza kopia repo, a nie serwer) i weryfikacja czy działa, bez konieczności narażenia reszty projektu na jakiś drobne niedopatrzenie,
    • zmniejsza się potrzeba wykorzystywania rozgałęzień kodu i późniejszych złączeń (z czym często są problemy), bo komity swoją drogą, a zmiany wysyłane na serwer swoją,
    • możliwość podzielenia swojej pracy na mniejsze kawałki, które sobie komitujemy na naszej kopii, a wysyłamy całosć zmian na serwer dopiero jak skończymy.

I to by było na tyle - mam nadzieję, że Cię to zainteresowało. Warto dać mu szansę. Osobiście wykorzystuję go i testuję w trzech projektach, i jak na razie jestem zadowolny Happy
Postaram się też trochę bardziej to przybliżyć w najbliższej przyszłości.

A na razie, kilka linków:
blog comments powered by Disqus