Git – co to jest?

Wiele znajomych na studiach zadaje dużo pytań na temat Gita. Zdecydowaną większość mogę sklasyfikować jako:

  • czym jest Git?
  • dlaczego jest on tak ważny?

W wielu ofertach pracy, czy stażu również możemy zobaczyć wielki plus w naszą stronę, jeśli posiadamy umiejętność obsługi Gita. W dzisiejszym wpisie postaram się wyjaśnić o co chodzi oraz utworzymy pierwsze repozytorium na najpopularniejszej stronie dla programistów Github (pomijając Stack Overflow).

Git jako system kontroli wersji

Wyobraź sobie sytuację, kiedy pracujesz nad projektem, wszystko działa jak należy, nie ma powodu do obaw. Następnego dnia wracasz do kodu i dopisujesz nowe funkcje, metody i po dopisaniu trzystu, czy tysiąca linijek okazuje się, że nie działa i nie masz kompletnie pojęcia jak przywrócić poprzedni stan projektu. Jedną z opcji jest klikać Ctrl + Z, jednak to będzie bardzo długi proces. W takich sytuacjach idealnie sprawdza się system kontroli wersji. Na taki pomysł wpadł Linus Torvalds (główny architekt jądra GNU Linux) i stworzył Gita – narzędzie, które pozwoli manipulować wersjami Twojego oprogramowania.

Zacznijmy od początku, pracujesz nad projektem i każdą działającą wersję wrzucasz do repozytorium (na ten moment przyjmij, że to nasz „serwer, który pamięta”). W chwili, gdy coś pójdzie nie tak możesz przywrócić tą działającą wersję. W ten sposób zapewniasz swojemu projektowi pewien ład, a sobie wewnętrzny spokój.

Ogólnie rzecz ujmując systemy kontroli wersji umożliwiają:

  • przegląd historii zmian, wraz z informacją kto i kiedy je wprowadził,
  • przywrócenie dowolnej wersji pliku lub nawet całego projektu,
  • pracę zespołową, poprzez wykorzystanie zdalnych repozytoriów

A więc jak zacząć?

Repozytoria

Niezależnie od tego, czy już projekt zaczęliście pisać, czy dopiero rozpoczynacie nad nim pracę możecie utworzyć tzw. repozytorium. Repozytorium możemy podzielić na:

  • lokalne, czyli takie które znajduje się na naszym urządzeniu. Możemy przyjąć, że to katalog w którym znajdują się wszystkie pliki projektu,
  • zdalne, czyli taki katalog, który możemy znaleźć na serwerze (np. na Githubie).

Korzystanie z zdalnego repozytorium pozwoli nam na pracę zespołową. Nasza zespół deweloperski będzie miał dostęp do całego kodu oraz użytkownicy mogą samodzielnie wprowadzać zmiany niezależnie od nas. Warto wiedzieć, że nowe funkcje, które dopisujemy w lokalnym repozytorium nie mają na razie wpływu na zdalne, dopóki tych funkcjonalności nie udostępnimy pozostałym.

Rozpoczynamy pracę

helloworld.py

W moim katalogu na początku znajduję się tylko prosty plik helloworld.py, który drukuje w języku angielskim słynne Witaj Świecie.

print('Hello World')

Zależy nam, żeby zacząć pracę z systemem kontroli wersji oraz obserwować wszystkie zachodzące zmiany w plikach projektu. Należy zacząć od utworzenia takiego repozytorium:

git init

Tworzymy w ten sposób lokalne repozytorium. Wszelkie informacje o zmianach i różnych wersjach plików będą znajdować się katalogu .git. Kropka przed nazwą katalogu bądź pliku w systemie Linux pozwala ukryć go, dlatego skorzystałem z ls -a co umożliwia nam zauważenie, że rzeczywiście taki został utworzony. Na tę chwilę nie ma potrzeby zgłębiać tajników tego folderu.

git init

Gratulacje! Utworzyłeś swoje pierwsze lokalne repozytorium! Zanim dodamy jakiekolwiek pliki do repo należy zrozumieć jak pliki funkcjonują w gicie.

Trzy stany plików w Git

Są to fundamentalne podstawy pracy z systemem kontroli wersji Git, więc naprawdę polecam zrozumienie tego! Są trzy statusy, w jakich może znajdować się plik:

  • zmodyfikowany (modifed) – working directory
    • często możemy się spotkać z określeniem unstaged,
    • bądź też untracked, w przypadku gdy nigdy nie dodaliśmy jeszcze do repozytorium danego pliku
  • śledzony (staged) – staging area
  • zatwierdzony (comitted) – repository
git file states

W momencie, gdy utworzyliśmy repozytorium komendą git init spowodowaliśmy, że plik helloworld.py jest w stanie modified. System wie, że jest plik w którym są wprowadzone zmiany o których nie ma pojęcia. Możemy to sprawdzić przy pomocy:

git status
git status

W zakładce Untracked files znajduje się wspomniany plik. Dzięki świetnym komentarzom wiemy już, że trzeba dodać go do staging area, żeby był śledzony.

git add <nazwa_pliku>
git add

Teraz plik znajduję się w stanie staged. Tylko czeka, aż udostępnimy go lokalnemu repozytorium. Nie zwlekajmy i zróbmy to:

git commit -m 'pierwszy commit' # komentarz do commita
git commit

git commit pozwala na przeniesienie pliku do repozytorium, bądź inaczej, wprowadzonych zmian do repozytorium. Często będziemy mówić „commitujemy” zmiany. Wiąże się to właśnie z udostępnianiem zmian w lokalnym repo. Możemy sprawdzić nasze zmiany przy pomocy logów:

git log # wyświetla wszystkie commity
git log -3 # wyświetla 3 ostatnie commity
git log --oneline # wyświetla każdy commit tylko przy pomocy jednej linii
git log

Jak widzisz obserwujemy, kto wrzucił zmiany do repozytorium oraz datę. Często będziemy również korzystać z drukowania logów w jednej linii, jest to rozwiązanie przejrzyste i pozwala na wyświetlenie dużo commitów. Warto również wspomnieć o dwóch linjkach:

commit 63054353d73c1f15d610119f7471ef21f049b949 (HEAD -> master)

6305435 (HEAD -> master)

Ta „duża liczba” w kodzie heksadecymalnym to ID commita, identyfikator, który pozwala nam zarządzać zmianami. Git pozwala na korzystanie z jego skróconej wersji, dlatego rozwiązanie –oneline jest przejrzystsze. Do tematu ID wrócimy jeszcze, pokaże jak można przywracać zmiany i przełączać się miedzy różnymi wersjami plików.

Nowa linijka kodu

Zrobiłeś swojego pierwszego commita, brawo! Praca nad projektem jednak się nie skończyła i będziesz chciał dopisać kilka nowych rzeczy. W moim przypadku dopiszę nową linijkę. Zauważ, że już Git już wie o wprowadzonych zmianach:

new line to python file

Następnie ponownie dodajemy plik do staging area i wrzucamy commit.

commit new line

Tworzenie zdalnego repozytorium

Cała zabawa z Gitem to nie tylko lokalne repo do zapisywania zmian, to praca zespołowa, tworzenie projektów wspólnie ze znajomymi i dzielenie się wiedzą. Dlatego skorzystajmy z serwisu Github, na którym bardzo wiele programistów tworzy projekty Open Source i pozwalają na dołączenie innych osób i współtworzenie czegoś nowego!

Zakładam, że masz już utworzone konto, jesteś zalogowany i umiesz wejść w zakładkę Create a new repository. Od tego momentu omówię jak udostępnić swój kod.

create repo on github

Dosłownie najważniejszą częścią strony jest nazwa repozytorium. Dlaczego? Otóż przez nazwę będziesz zwracał się do zdalnego repozytorium. Najczęściej będzie to adres formatu: https://github.com/nazwa użytkownika/nazwa repozytorium.

Dlatego proponuję zdecydować się na krótka i treściwą nazwę. Następnie Opis, który jest opcjonalny. Tutaj należy krótko streścić co to za projekt, decyzja należy do nas czym zagospodarujemy to miejsce. Możemy pozostawić je puste.

Kolejnym elementem jest wybór, czy zakładamy publiczne, czy prywatne repozytorium.

  • Public – wszyscy mogą zobaczyć repozytorium na Twoim profilu, gdy ktoś obcy będzie chciał wprowadzić jakieś zmiany będziesz mógł zdecydować czy te zmiany dopuścić,
  • Private – tylko Ty widzisz to repozytorium, o ile nie dodasz innych deweloperów. Co do zmian jest to samo co z publicznym.

Zauważyłem, że wiele problemów robi ostatnia kategoria, czyli README.md, .gitignore oraz LICENSE.md. Są to można by rzec, jedne z ważniejszych danych w repozytorium.

  • README.md – tutaj opisujesz swój projekt, sposób instalacji, jak go uruchomić, przedstawiasz się jako autor i inne ważne elementy. Warto zadbać, żeby ten plik był czytelny. To pozwoli innym programistom zrozumieć, co miałeś na myśli.
  • .gitignore – plik znajdujący się generalnie w lokalnym repozytorium. Mówi systemowi, jakie pliki ignorować. Taki ignorowany plik, czy katalog nie pojawi się po użyciu komendy git status. Najczęściej dodaje się do niego katalogi konfiguracyjne, czyli pliki wykonywalne.
  • LICENSE.md – licencja Twojego projektu.

Klikając Create repository tworzymy je. Następnie ukazuje nam się widok:

Udostępnianie kodu na zdalnym repozytorium

Tak jak wspomniałem wyżej korzystamy z określonego adresu, który jest widoczny tutaj:

git remote add origin https://github.com/Mregussek/helloworld.git

Powyższa komenda mówi – dodaj ten adres zdalnego repozytorium i nazwij go origin. Do wybranego repo będziemy zwracać się korzystając z origin – domyślnego repozytorium na które chcemy udostępniać zmiany. Teraz pozostało wrzucić nasz kod, co możemy zrobić przy pomocy:

git push -u origin master

git push wysyła wprowadzone zmiany na serwer. Tutaj możemy zatrzymać się i wytłumaczyć o co chodzi z flagą -u i co to ten master.

Gałęzie (Branch)

Jak zostało wspomniane wyżej, git pozwala na pracę zespołową. Jak taka współpraca miałaby wyglądać? Do tego celu utworzone gałęzie, które pozwalają na równoległe pisanie oprogramowania. Wyobraź sobie sytuację, kiedy mamy napisany pierwszy działający prototyp aplikacji. Dołącza do zespołu kilka nowych osób i będą zajmowały się jakimiś nowościami. W ten sposób każdy deweloper może utworzyć własną gałąź i na niej może kompletnie niezależnie od pozostałych koderów pracować nad kodem. Idealnie obrazuje to ilustracja poniżej:

Domyślną gałęzią tworzoną przez gita jest master. Pozostałe zamieszczone na obrazku to Release, Develop, Feature 1 i 2. Gdy ktoś ukończy swój moduł, kod który napisał może zostać scalony z pracą innych programistów. Do tego celu wykorzystuje się git merge bądź git rebase, jednak te pojęcia rozwinę w innym wpisie.

Flaga -u

Jest bardzo pomocny parametr, który pozwała na ułatwioną pracę jeśli chodzi o pobieranie wprowadzonych zmian na serwerze. Gdy chcemy zsynchronizować kod znajdujący się na serwerze z danymi w naszym lokalnym repozytorium zajdzie potrzeba pobrania tych plików i scalenia. W takiej sytuacji korzystamy z git pull i dzięki skorzystaniu z flagi -u nie będziemy musieli podawać jakichkolwiek innych argumentów.

Pliki w repozytorium

Dzięki git push mogliśmy udostępnić nasz kod na zdalnym repozytorium. Brakuje tutaj jednego ważnego pliku – README.md. Pozwólmy potencjalnym zainteresowanym użytkownikom zrozumieć nasz projekt, na czym polega, jak go uruchomić, kto jest autorem czy inne istotne elementy powinny się w nim znaleźć. Często do tego korzystam z witryny internetowej Make a Readme:

Podczas opisywania czegokolwiek możemy obok zobaczyć jak prezentuje się przygotowany plik. W lokalnym repozytorium utworzyłem plik README.md, przekleiłem do niego tekst znajdujący się na powyższym zdjęciu i udostępniłem zmiany w zdalnym repo. Rezultatem tej operacji jest:

Podsumowanie

W dzisiejszym wpisie udało nam się zrozumieć potencjał gita, utworzyliśmy pierwsze lokalne i zdalne repozytoria, nauczyliśmy się stanów w jakich mogą znajdować się pliki w repo oraz opanowaliśmy udostępnianie zmian na serwerze. Mam nadzieję, że przedstawiony materiał pozwoli zrozumieć co to system kontroli wersji i jego możliwości. W następnym wpisie skupimy się na cofaniu wprowadzonych zmian w kodzie, nauczymy się tagować commity, dobierać wersje oprogramowania.

Linki referencyjne:

Kurs Youtube

Git – Branches in a Nutshell

What does the -u flag mean in git push -u origin master?

Basic writing and formatting syntax

Zobacz wprowadzenie do języka Python!