System GIT- i będzie git!


IT, IT-DLA-ZIELONYCH / poniedziałek, 7 października, 2019

Wiemy już, gdzie programiści trzymają kod, teraz pora przyjrzeć się codzienności i poznać strukturę Gita.

W ostatnim artykule wspominałam, że skoro nad kodem pracuje kilka osób, potrzebne jest również jedno wspólne miejsce do jego przechowywania- repozytorium (aka repo).

Oczywiście repozytorium to mogłoby być trzymane lokalnie, np. na komputerze jednego z programistów, jak jednak wówczas pozostałe osoby mogłyby z niego korzystać? To tak, jakbyśmy chcieli Google Docs trzymać lokalnie zamiast w chmurze!

Bardzo pomocne jest więc umieszczenie repozytorium na serwerze, dzięki czemu każdy z programistów będzie mógł się z nim połączyć i skopiować je lokalnie u siebie.

Zauważcie, że umieszczając nasze repozytorium na serwerze, będziemy mogli mówić o jego dwóch wersjach- tej lokalnej i tej dostępnej zdalnie.

Zmiany

W trakcie pracy programiści synchronizują zmiany wprowadzane lokalnie z tymi, które znajdują się na serwerze. I tutaj docieramy do sedna- zmiany, zmiany w czym?! Oczywiście w kodzie.

Programiści piszą kod i to on jest w centrum tych synchronizacji. Naturalnie nie wszystko piszemy samodzielnie. Niejednokrotnie nie chcemy wyważać otwartych drzwi i korzystamy z różnego rodzaju bibliotek. Powtarzalne elementy kodu bywają również generowane. Niezależnie natomiast od tego, w jaki sposób ów kod został dodany, usunięty, zmieniony, wszystko to powoduje, że wersja lokalna kodu programisty różni się od tej na serwerze.

Commit

Wprowadzając w kodzie kolejne zmiany chcemy również zapisać je w repozytorium. Właśnie do tego celu służą nam commit’y, czyli zapisane migawki, snaphoty, aktualny stan plików aplikacji. Dzięki temu jesteśmy w stanie cofnąć się do konkretnego commita z przeszłości i w ten sposób przywrócić stan, jaki w tamtym momencie miała aplikacja. Nie ma reguły, zmian w ilu plikach może dotyczyć jeden commit. Co istotne, powinny być one robione w miarę często i dotyczyć w miarę możliwości jednej tematyki, którą podsumowujemy w tytule commit’a.

Wiemy już jak zapisujemy zmiany w repozytorium. Zanim przejdziemy do omówienia, w jaki sposób ów zmiany są w systemie kontroli wersji dokumentowane i jak uzgadniamy wersję lokalną bazy kodowej z wersją na serwerze, zacznijmy od branch’y.

Branch

Wyobraźcie sobie zespół 7-osobowy, w którym każdy z developerów pracuje nad innym zadaniem. Każdy z nich przygotowuje swoje zadanie na lokalnym komputerze. Pracuje nad nim czasami przez kilka dni, aż w końcu po prostu wysyła je na serwer, bez większej refleksji nadpisując zmiany kolegów i koleżanek.

Aby zrealizować powyższy scenariusz w Git-cie, musielibyśmy pracować na jednym branchu. Branch’u, a więc pojedynczej wersji aplikacji, gałęzi, na której kolejne stany aplikacji (commit’y) układane są chronologicznie i liniowo, od tych najstarszych po najnowsze.

Opisane rozwiązanie miałoby jednak liczne wady- programiści albo musieliby czekać z wysłaniem zmian na serwer do momentu ukończenia zadania i otrzymania stabilnej wersji (ryzykując jednocześnie, że ich komputer ulegnie uszkodzeniu i stracą swoją pracę) albo dodawaliby każdy commit natychmiastowo totalnie uniemożliwiając normalną pracę innym (wersja na serwerze byłaby zlepkiem wszystkiego i niczego z wielu różnych bajek). Nie wspominając już o tym, że rozwiązanie danego zadania chcemy testować zanim dołączymy je (zmergujemy) z całą resztą. Dzięki temu testerzy są w stanie w porę wyłapać błędy w dostarczonej wersji.

Jak więc rozwiązuje to Git?

Git pozwala nam na utworzenie większej liczby branch’y. Zazwyczaj w repozytorium jeden branch oznaczony jest jako główny (np. master, develop). Jest to nasza główna wersja aplikacji, do której każde zadanie po uprzednich testach i tzw. review kodu jest dołączane. Sam fakt dołączenia zadania do mastera często cieszy developerów, ponieważ liczba kroków i prób, jakim musi zostać poddane takie zadanie, wcale nie jest mała. Jest to jednak temat na osobny artykuł.

Wróćmy do branch’y. Każdy z branch’y utworzonych na serwerze może posiadać nieskończenie wiele kopii lokalnych– może zostać „wycheckowany” przez wiele osób. To tak jak z pobieraniem obrazka z Internetu. Tam zamieszczona jest na serwerze jego oryginalna postać, natomiast każda uprawniona osoba może go pobrać lokalnie do siebie i co więcej, zmodyfikować, dorysować coś od siebie.

Jednocześnie, aby każdy developer mógł pracować na swojej kopii głównego brancha (master’a) i tam dobudowywać swoje rozwiązanie, istnieje możliwość utworzenia nowych branch’y od mastera, a więc w danym momencie jego kopii. Dzięki temu developer może pobrać lokalnie branch’a przypisanego do jego zadania i wysyłać swoje zmiany na serwer również na tego samego branch’a. Nie ryzykuje tym samym utraty swojej pracy w przypadku awarii/kradzieży laptopa. Zauważcie, że jednocześnie nie dotyka przedwcześnie mastera i testerzy mogą na spokojnie przetestować jego rozwiązanie, ZANIM zostanie ono połączone i główną wersją.

Na poniższym obrazku możecie zobaczyć takiego głównego branch’a pokroju wspomnianego powyżej mastera i odchodzące od niego kopie bazy kodowej. Przy czym jak widzimy, obydwa branch’e (obydwie kopie) zostały utworzone w tym samym momencie.

Zastanawia Was, w jaki sposób w takim razie zmiany dodane w ramach branch’a, na którym pracował dany programista, mają szansę znaleźć się na masterze? Przez ich połączenie, a więc mergowanie. Mergowaniu jednak przyjrzymy się szerzej w kolejnym artykule.

Na dziś to już wszystko- od tego momentu commit’y i branch’e nie będą Wam już straszne! Jeśli interesuje Was sama koncepcja systemu kontroli wersji, koniecznie przeczytajcie gdzie programiści trzymają kod. Do zobaczenia w kolejnym odcinku!

Dodaj komentarz

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