System Kontroli Wersji
8 godz. 23 min · Git · Full-stack i Programowanie
Mateusz KuleszaSenior Software Developer, Konsultant, TrenerInne systemy wersjonowania wymagają konfiguracji specjalnych serwerów - a z GIT wystarczy do tego twój komputer. GIT pozwoli Ci zapisywać kolejne wersje twojej pracy lub eksperymentować z różnymi zmianami. Jeśli chcesz tworzyć kopie zapasowe - w kursie zobaczysz jak tworzyć klony twojego projektu oraz jak wysyłać i pobierać aktualne zmiany pomiędzy klonami.Pierwsza sekcja pozwoli Ci zyskać pewność w samodzielnej pracy z GITem nim podejmiesz się pracy w zespole. Dowiesz się jak przygotować zestaw zmian, ignorować pliki tymczasowe, jak tworzyć migawki z opisami zmian, a następnie przeglądać i porównywać zmiany dokonane nawet miesiące temu. W kolejnej części kursu dowiesz się jak wycofywać zmiany, przywracać wcześniejsze wersje i edytować historię zmian. Zobaczysz, że w GIT “nic nie ginie”. Pokażę Ci jak możesz odzyskać pozornie utracone zmiany oraz jak naprawić historię zmian łącząc, dzieląc, a nawet zmieniając kolejność dokonanych wcześniej zmian.
Jesteś w trakcie pracy nad ważnym projektem, i nagle musisz oderwać się od pracy, by wykonać jedną, szybką poprawkę? W GIT możesz błyskawicznie przełączyć się na inną wersje projektu, lub po prostu “odłożyć na później” pliki nad którymi pracujesz i wrócić do nich kiedy tylko tego potrzebujesz. W tej części kursu zobaczysz jak pracować na gałęziach, dodawać etykiety oraz przełączać różne wersje plików. Dowiesz się jak porównywać oraz eksperymentować z plikami bez ryzyka utraty danych. Co najważniejsze - nauczysz się łączyć i dzielić wiele różnych wersji twojej pracy. Zobaczysz, jak praca na gałęziach nie tylko zwiększy Twoją swobodę i elastyczność w codziennej pracy, ale również jak gałęzie pozwalają wielu osobom na równoległą pracę na tych samych plikach bez martwienia się o utratę danych lub niespójne wersje.
W kursie dowiesz się nie tylko jak zapamiętywać zmiany, ale także jak je opisywać i oznaczać, tak, by nawet miesiące później móc łatwo odnaleźć odpowiednią wersję pliku, lub by dowiedzieć się kiedy, kto i dlaczego zmieniał dany plik. Zobaczysz jak dobre praktyki w opisywaniu zmian wspomagają pracę grupową. Dowiesz się jak pobrać lub wysłać zestaw zmian na serwer oraz jak połączyć zmiany swoje, lub zmiany otrzymane od współpracownika. Dodatkowo, zobaczysz jak bezpiecznie rozwiązać problem konfllktujących zmian w plikach lub jak przenieść zmiany z wersji do wersji. W kursie dowiesz się także jak w bardzo prosty sposób korzystać z pozornie najtrudniejszej funkcji GITa, jaką jest polecenie “rebase”. Zobaczysz jak usprawni się Twoja praca, gdy będziesz mógł w jednym kroku zbudować historię zmian. Jeśli źle zapisałeś zmiany, nie podoba Ci się historia zmian, lub po prostu chciałbyś łatwo uniknąć konfliktów - git rebase będzie Twoim nowym ulubionym narzędziem.
…zmieniło ten sam plik, trzeba jakoś te zmiany połączyć. Zobaczysz jak GIT pozwala wysłać zestaw zmian na serwer, pobrać zmiany innych osób i automatycznie dołączyć te zmiany w odpowiednich miejscach. Co jednak jeśli dwie osoby zmienią tę samą linię w pliku? W kursie dowiesz się nie tylko jakie są różne sposoby i strategie łączenia zmian, ale także jak dzięki historii będziesz wiedział dlaczego zmiana w pliku została wprowadzona. Dzięki narzędziu rebase będziesz mógł zaaplikować wszystkie zmiany w odpowiedniej kolejności i w odpowiednim miejscu.
W kursie poznasz także usługę GitHub. GitHub to nie tylko usługa udostępniająca repozytoria dla GIT - umożliwia również tzw. społecznościowe podejście do tworzenia… I to nie tylko kodu. Zobaczysz, że dzięki GitHub praca nad kodem aplikacji czy nową książką może odbywać się zespołowo. Pokażemy Ci jak publikować swoje zmiany oraz jak zgłaszać je innym do przejrzenia i połączenia z ich wersją. Poznasz także sposoby planowania pracy, przydzielania zadań i zarządzania postępem ich wykonania - wszystko na twoim koncie na portalu GitHub. Oprócz poleceń i funkcji GIT w tym kursie pokażemy Ci również, na prostych, praktycznych przykładach, typowe techniki i praktyki pracy z GIT. Podczas kursu symulujemy zespół budujący prostą stronę internetową. Co ważne, nie musisz znać HTML by skorzystać z tej części kursu! Zobaczysz jak wygląda praca z perspektywy jednej osoby, co zrobić gdy musisz przerwać pracę i przełączyć się na inne zadanie oraz jak przygotować Twoją pracę do podzielenia się nią z zespołem. Pokażemy kilka przykładów organizacji pracy. Zobaczysz prace z małym, centralnym repozytorium, a także modele pracy rozproszonej, z której korzystają duże projekty typu open-source. GIT to branżowy standard, który obowiązuje praktycznie we wszystkich firmach zajmujących się tworzeniem aplikacji lub stron internetowych. Sprawia to, że wiedza, którą zdobędziesz po przerobieniu tego kursu, bezpośrednio przełoży się na efektywność Twojej pracy oraz projekty, które tworzysz.
Kurs przygotowany został z myślą o wszystkich, którzy chcą nauczyć się najbardziej popularnego i elastycznego systemu kontroli wersji i wykorzystać go do efektywnej pracy w zespole, jak i na potrzeby indywidualnych projektów. Jest również przeznaczony dla każdego, kto pracuje z kodem źródłowym i chciałby nie tylko tego, by jego zmiany były bezpieczne, ale by jednocześnie mieć swobodę pracy na kilku równoległych wersjach kodu oraz móc swobodnie eksperymentować nie bojąc się o utratę danych. Jeśli chciałbyś dowiedzieć się jak sprawnie korzystać z Githuba oraz zrozumieć, czemu ten system jest tak chętnie stosowany przez programistów na całym świecie - to najlepsza metoda!
W poprzednich lekcjach dowiedziałeś się jak tworzyć nowe gałęzie jak tworzyć odrębne historie zmian na
każdej z tych gałęzi oraz jak dzięki poleceniom git cherry pick przenosić pojedyncze zmiany lub serię
zmian pomiędzy różnymi gałęziami.
W tej lekcji pokażę ci jak zrobić to dużo prościej mianowicie nie przenosząc pojedyncze zmiany ale w
jaki sposób połączyć całe dwie gałęzie to znaczy przenieść wszystkie zmiany z jednej gałęzi od wspólnego
punktu z naszą gałęzią na właśnie naszą gałąź tak żebyśmy mieli wszystkie zmiany z obu gałęzi w bieżącym
miejscu bieżącej gałęzi i w katalogu roboczym tak żeby widzieć te wszystkie zmiany w naszym projekcie
i do łączenia właśnie kilku gałęzi służy polecenie git merge i git merge'a w ten sposób że będąc na jakiejś
gałęzi np. master ja podaję tutaj nazwę commita lub nazwę gałęzi np. powiedzmy nowy nagłówek i takie
polecenie znajdzie wspólny punkt znajdzie punkt w którym miejscu te gałęzie się właśnie rozgałęziły
ja to przerwę na chwilkę i zobaczmy jeszcze historię zobaczymy jak wygląda całe nasze drzewko i jak
widzisz nowy nagłówek odgałęził się od naszego aktualnego brancha master.
Dokładnie w tym miejscu.
Czyli tak się składa że master jest bezpośrednim rodzicem nowego nagłówka czyli jeśli będę chciał ten
commit z nowego nagłówka przenieść tutaj do naszej gałęzi to mógłbyś to bardzo prosto.
Zwróć uwagę że jeśli wykonam faktycznie polecenie git merge i podam tutaj nowy nagłówek czyli jeszcze raz jestem
na gałęzi master do gałęzi master chcę domergeować czyli dołączyć wszystkie zmiany z gałęzi nowy nagłówek
rozpoczynając od wspólnego rodzica.
I tak się składa że wspólnym rodzicem jest właśnie commit na którym jestem więc ta zmiana będzie bardzo
trywialna będzie polegała po prostu na dodaniu wszystkich zmian z nowego nagłówka do mastera.
Spróbujmy.
OK.
I tu zwróć uwagę na bardzo ważną informację.
Mam informacje odkąd dokąd oraz tu informacja fast forward i co znaczą informacja fast forward.
Oznacza to że właśnie jeśli spojrzymy na drzewko nie musieliśmy robić żadnych szczególnych zmian.
Wystarczyło że przenieśliśmy wskaźnik head i wskaźnik master czyli tam gdzie jesteśmy teraz już przesnieśliśmy
go na ten commit czyli zobacz.
Nie musiałem tak jak w poprzedniej lekcji kopiować wszystkich zmian i mieć podwójnie te same zmiany
skoro jedna historia była bezpośrednim rozszerzeniem drugiej historii to nie było sensu tworzyć tych
samych zmian obok.
Wystarczyło po prostu dociągnąć lub przesunąć tą starszą historię do tego samego punktu co nowsza historia.
I to jest właśnie git.
Merge w trybie fast forward czyli po prostu szybko przesuwa do przodu tak żeby zrównać z sobą te dwie gałęzie.
W tym momencie widzisz master i nowy nagłówek wskazują dokładnie ten sam commit.
Jak widzisz to polecenie jest dużo prostsze niż polecenie.
Git cherry pick w tym sensie że sam znajduje punkt od którego zacząć.
Sam wie które commity połączyć jeśli jest taka możliwość to zamiast kopiować przenosić te wszystkie
zmiany pojedynczo po prostu przesuwa nasz wskaźnik do przodu co jest szybsze i co najważniejsze zostawia
bardzo elegancką historię.
I teraz po prostu spojrzę w git log oneline to wygląda to tak jakby po prostu dołożył ten komin z osobnej
gałęzi do naszej gałęzi i tak naprawdę jest bardzo sprytny bo po prostu zamiast przerzucać zmiany
przesuwa nas po tych ścieżkach historii tak żeby zrównać obie wersje ze sobą czyli jeśli mówiąc połącz on po prostu
je zrównuje wskazują na ten sam commit więc efekt jest dokładnie taki sam jakbyśmy skopiowali te zmiany ale
historia jest prostsza to polecenie dużo prostsze i to jest tak zwany prosty merge to jest fast forward.
Chciałbym tu pokazać jednak prawdziwy merge czyli co się dzieje w sytuacji gdy taka prosta zmiana nie jest
możliwa.
Ok.
Czyli jak pamiętasz po każdych tych przesunięciach zmianach w historii ja zawsze mogę cofnąć się do wcześniejszej
wersji jeśli tylko mam jakiś punkt zaczepienia i oczywiście będzie to nasz.
Tak pierwsza wersja czyli z powrotem tutaj do punktu w który byliśmy przed chwilą wrócimy.
Czyli tak wyczyszczę i poleceniem git reset znowu hard bo chce wszystko tu usunąć git reset hard przyłączamy
się do.
pierwsza wersja.
Jak widzisz teraz nasz wskaźnik head czyli tu gdzie jesteśmy akurat teraz wskazuje na dodano style do
strony.
Jeśli zobaczę sobie oneline tutaj no to jesteśmy dokładnie w punkcie z którego wyszliśmy przed poprzednim mergem.
I tu spróbuję wyświetlić jeszcze drzewko.
I mamy tutaj master i head w tym miejscu i wszystkie commity są przed nami czy one jeszcze nie są połączone.
Nasz master jest przed tymi zmianami i tym razem zamiast podłączać tylko ten nagłówek postaram się połączyć
obie rzeczy mianowicie zmiany z tego z tej gałęzi nowy nagłówek oraz zmiany z gałęzi treści ale
jeszcze nim to zrobimy.
Tutaj mam cały czas informację work in progress wiec jeszcze przejdę do tego brancha do tej gałęzi spis
treści i poprawię te dwa commity czyli jak pamiętasz git checkout.
I przełączyć się na gałąź.
Spis treści zobaczę tutaj jak wygląda log i tak mamy dwa commity.
Mamy dwa commity które są work in progress.
Jak pamiętasz z poprzednich lekcji.
Ja mogę takie commity wycofać ja mogę zmodyfikować historię.
I tutaj historia zmieniona w tej gałęzi spis treści zupełnie te zmiany nie wpłyną na inne pozostałe historie
takie jak master czy nowy nagłówek.
Czyli spokojnie będę mógł zrobić sobie git reset.
Tym razem nie hard tylko soft dlatego że chce aby te zmiany z tych dwóch commitów pozostały u mnie w
indeksie.
I będzie to head od head cofnijmy się o dwa head w tym momencie znajduje się właśnie na spisie treści
tu gdzie jesteśmy teraz.
Spis treści i head wskazuje na ten commit więc ja cofam się o dwóch rodziców czyli tutaj ten pierwszy
drugi.
Czyli wrócę do tego commita tutaj.
Sprawdźmy jeszcze raz oneline.
Jak widzisz cofnął nem te dwa commity ale zmiany nie zostały stracone zrobię git status mam tu zarówno indeks jak i podstawy
które zmieniliśmy w tych dwóch commitach z powrotem są tutaj w indeksie.
Mogę tutaj je zmodyfikować i scommitować ponownie tym razem już poprawione i z poprawnymi tutaj nazwami commitów.
Przejdę więc do naszego edytora i tu mamy nasz niedokończony spis treści.
Więc dodam jeszcze jedną pozycję będzie to praca lokalna i praca powiedzmy równoległa na kilku gałęziach
na gałęziach a poza tym jest to praca równoległa.
Nie jest to istotne i przejdę do pliku podstawy on tu jest pusty więc zróbmy tak żeby już nie poświęcać czasu ja
przekopiuje ten sam wzór strony i zmienię tutaj tylko zawartość zmienię treść.
W spisie treści wpiszę po prostu podstawy git OK.
Czyli wprowadziłem zmiany w plikach i tym razem jak podejrzę git status.
Mam dwie wersje obu plików.
Czyli chciałbym teraz zmiany które wprowadziłem także do indeksu ale zróbmy to po kolei żeby znowu utworzyć
commity wycommitować wszystko za jednym razem.
Jak pamiętasz lekcje dotyczące indeksu dodawania usuwania plików i przygotowania do scommitowania przygotujmy tutaj
dwa commity.
Czyli powiedzmy że w pierwszym commicie chciałbym tylko scommitować plik index html więc zrobię git add
i dodam indeks HTML do indeksu.
I w tym momencie powinniśmy mieć indeks już tylko w jednej wersji w wersji którą właśnie zmodyfikowałem
ale tu mam jeszcze podstawy.
Ja nie chcę żeby podstawy trafiły do commita więc także jak robiliśmy to poprzednio git reset head podstawy
HTML zobaczmy i mamy dwa pliki mamy indeks który jest przygotowany do scommitowania i mamy podstawy
HTML nasze w najnowszej wersji jeszcze sprawdzę.
Wszystko się zgadza tu mamy nasze zmiany czyli tu mamy też nasze zmiany czyli w tym momencie jak zrobię
git commit i podam wiadomość spis treści scommitujemy git status pozostawiam tylko podstawy natomiast git.
long już go nie znajdę to może tak zróbmy git log oneline.
Mamy tutaj commit spis treści.
Zostały mi tylko te podstawy czyli git status git add podstawy.
Tym razem git commit podstrona podstawy git sprawdzę jeszcze raz.
Jak wygląda historia.
Wszystko się zgadza.
Czyli w tym momencie mogę powrócić do mastera
git checkout.
Master ok sprawdźmy tutaj historię tutaj tych zmian.
Jeszcze nie ma.
Spróbujmy jeszcze raz drzewko wyświetlić.
Ok i mamy tu jest drzewko w formie krótszej mam tutaj tylko oneline.
Ale to nie szkodzi.
Mamy mastera w tym miejscu mamy nagłówek w tym miejscu i spis treści tutaj mamy wszystko na razie
przed masterem teraz robimy troszkę inaczej mianowicie najpierw robię git merge.
I najpierw zmerge'uje nasz poprawiony spis treści z nowymi commitami.
Podam referencje do tego commita i git merge połączy całą historię.
Jako że widzisz ta historia była zbudowana bezpośrednio na masterze ona też się wywodzi.
Widzisz tego rodzica master to teraz master może być po prostu przesunięty.
Czyli jak widzisz master znajdowało się w tym miejscu.
Ja chciałem go połączyć ze spisem treści więc head nasza wskazówka na bieżące referencje do bieżącego
miejsca jak już widzisz powędrowała do góry.
W dokładnie w to samo miejsce w którym jest spis treści czyli wskaźnik head po prostu przesunął się do
przodu w to miejsce w którym chciałby żeby był mój master.
Pytanie teraz co z nowym nagłówkiem.
Nowy nagłówek był z przodu był przed nami i ja mogłem przesunąć się do przodu.
Mogłem przesunąć tutaj ale wtedy już bym nie mógł włączyć spisu treści.
Jako że przyznałem tutaj heada po tej ścieżce no to teraz ta ścieżka pozostała w tyle i jeśli teraz próbuje
zrobić git merge i spróbuję połączyć nowy nagłówek.
To już nie mogę po postu przesunąć wskaźnika że wskaźnik już jest do przodu on już jest za mną nagłówkiem.
Nie mógłbym cofnąć go jakby z powrotem bo nie miał spisu treść.
Inną opcją która pozostaje gitowi do zrobienia to stworzenie nowego commita jeszcze przed headem w którym
zaaplikujemy jeszcze raz te same zmiany jak w przyszłości ale na nowo i wtedy dopiero będziemy mogli
swobodnie ten head master przesunąć po prostu jeszcze bardziej do przodu.
Dlatego że ta zmiana będzie jeszcze raz zaaplikowana na samym początku.
Mogę po prostu przesunąć do przodu.
Spróbujmy właśnie był tu komunikat automergeing.
I tutaj mamy zatrzymaliśmy się żeby właśnie stworzyć ten dodatkowy commit.
I tutaj git zatrzymuje się żeby nas zapytać o wiadomość.
I tutaj mogę napisać jakie zmiany wprowadzam i tutaj mogę robić ustawić merge branch nowy nagłówek ale
żeby było czyściej ja to mogę po prostu to wyczyścić sobie i mogę napisać pod spodem merge.
Nowy nagłówek ale na górze.
W pierwszej linii zastosować faktycznie jakiś sensowny dokładny komunikat który później powie mi co
się stało w tym commicie czyli zmieniono style nagłówka.
Spróbujmy w ten sposób zapisz.
I tutaj jak widzisz automerging mamy merge dokonany strategią rekursywną.
Czyli jak tutaj widzisz porównuję te dwa pliki i aplikuję te zmiany z obu z nich.
Jak widzisz zmiany w indeks HTML to były dwie zmiany tutaj dodano i usunięto linię natomiast w stylach było
dodane osiem linii.
Czyli te wszystkie zmiany z tego commita który był w tyle pozostał zostały zablokowane jeszcze raz jako
nowy commit z przodu.
Czyli zwróć uwagę tutaj head znajdował się na commicie 5 c.
Spis treści to był tu i teraz na jakby na tym commicie spis treści zostały zaaplikowane.
Ten nowy nagłówek praktyczne porady i żeby połączyć je ze sobą żeby z powrotem wrócić do głównej gałęzi.
Git musiał stworzyć taki po prostu commit który łączy te zmiany i tu mamy nasz komunikat zmieniony styl
nagłówka merge.
Nowy nagłówek i teraz jeśli podejrzę zmianę mamy tutaj zarówno nasz poprawiamy spis treści jaki mamy
nasz nowy nagłówek i mamy jednolitą historię.
Po prostu git log oneline.
Ostatnim commitem jest ten commitem który ponownie aplikacje nowy nagłówek ale tym razem aplikacje go
na już zablokowanych zmianach spis treści.
Mam nadzieję że to jest jasne.
Po prostu myśleliśmy o tym że jeśli dwie osoby jednocześnie zmieniają plik nie możemy ich zaplikować
jednocześnie.
Któraś z tych osób musi jakby swoje zmiany zaaplikować jako pierwsza i druga osoba która chce swoje zmiany
dołożyć musi to zrobić biorąc pod uwagę co już zostało zmienione nie może po prostu napisać wszystkiego
tylko musi po prostu swoje zmiany poukładać w taki sposób żeby pasowały.
I to jest widzisz jak w naszym przypadku stało się bardzo fajnie bo to wszystko stało się automatycznie.
Git on się nie zatrzymywał nie pytał o nic.
Jedyną rzeczą którą on zapytał to była wiadomość tak jak chcesz nazwać tą zmianę to stało się tylko
dlatego że byłem bardzo ostrożny żeby pracując na tych dwóch wersjach nie zmieniać tych samych linii.
Zauważ że w jednym pliku ja modyfikowałem tylko tę linię u góry a w innym branchu w innej gałęzi modyfikowałem
tylko tutaj do tej linii i w ten sposób jak widzisz osoby pracujące na jednym pliku.
Jeśli nie zmieniałem tych samych linii nie ma konfliktów.
Czyli git może automatycznie wprowadzić zmiany jednej osoby wprowadzić zmiany drugiej osoby i połączyć je
razem.
Mimo to warto po każdym takim automatycznym merge'u wyprzedzić swoje pliki uruchomić aplikację i sprawdzić
czy wszystko działa.
Jeśli w aplikacji posiadacie testy automatyczne czy contunous integration np. serwer który automatycznie sprawdza
takie aplikacje czy strony internetowej warto coś takiego mieć bo nawet gdy git automatycznie połączy pliki
no to czasami mimo że zmiany będą dodane jedne i drugie.
I to wszystko działa.
To może to nie mieć sensu na przykład osoba która dodała nagłówek.
I druga osoba dodała nagłówek z perspektywy gita jest to ok ale z naszej perspektywy dwa nagłówki na jednej
stronie to jest troszeczkę za dużo.
Ok.
To było na tyle w kwestii prostego merge'a i prawdziwego merge'a gdzie zmiany łączone są automatycznie z kilku
różnych wersji i tworzony jest nowy komitet żeby właśnie zaaplikować kilka zmian z kilku różnych gałęzi.
W kolejnej lekcji zajmiemy się troszeczkę mniej przyjemną sytuacją kiedy git sam sobie nie poradzi i kiedy
to my będziemy musieli wytłumaczyć pomóc gitowi rozwiązać taki konflikt zdecydować które ze zmian
pozostawić które ze zmian odrzucić tak żeby rozwiązać ten konflikt tak żeby wersja końcowa była spójną
poprawną wersją.
Ale o tym wszystkim już w kolejnej lekcji dziękuję bardzo i do zobaczenia.