How does UX transform businesses? The effects of usability testing
It has already become clear that User Experience (UX) is a key factor in shaping how companies build a business. The customer-centric approach has almost completely replaced […]
Kurs Ruby on Rails – Lekcja 1 – GIT
branch
– gałąź, odnoga naszego repozytorium commit
– paczka z naszymi zmianami pull
– pobranie zmian ze zdalnego repozytorium push
– wrzucanie zmian na zdalne repozytorium
Git (Global Information Tracker) jest jednym z darmowych systemów kontroli wersji.
Oprogramowania te służą do śledzenia zmian w kodzie, umożliwiając równoległą współpracę między programistami.
Z każdego kawałka napisanego kodu tworzymy “commit”, który zawiera nasze zmiany, ich opis oraz autora; w ten sposób tworzymy historię zmian. W dowolnym momencie mamy możliwość zobaczenia dokładnych zmian dowolnego pliku oraz, jeśli jest taka potrzeba, cofnięcie się do konkretnego momentu.
Aby jeszcze bardziej uporządkować pracę, powinniśmy korzystać z branchy.
Domyślnie w repozytorium główną branchą jest master
i nie można jej usunąć.
Ale tworząc nowy element aplikacji możemy stworzyć nową, na której będziemy umieszczać nasze commity. Póki nie skończymy całego elementu, nie będzie on robić bałaganu na głównej gałęzi. W tym czasie inni członkowie zespołu pracują na swoich gałęziach. Po skończeniu funkcjonalności, łączymy naszą branch z główną.
$ mkdir kurs-ror
$ cd kurs-ror
$ git init
Polecenie stworzy katalog .git
, w środku którego znajdziemy plik konfiguracyjny oraz całą lokalną zawartość repozytorium.
$ touch init.txt
$ git status
– powie nam, że plik init.txt jest “untracked”, czyli nie będzie umieszczony w commicie oraz, że nie jest śledzony przez repozytorium. Oznacza to, że nie zobaczymy zmian używając $ git diff
.$ git add init.txt
, można też dodać wszystkie zmienione pliki za pomocą $ git add .
.$ git status
powie, że plik init.txt będzie zawarty w naszym commicie i będzie oznaczony jako “staged”.$ git commit -m "opis zmian"
Polecenie stworzy commit, ale w naszym lokalnym repozytorium. Teraz $ git status
nic nie wyświetli, ponieważ nie mamy aktualnie już żadnych zmian.
$ git log
pokazuje wszystkie commity na aktualnej branchy, a więc wyświetli nam nasz pierwszy commit.
Wiadomość commita jest bardzo ważna. Często, zwłaszcza w większych i dłuższych projektach, warto dodać dłuższy opis wprowadzanej zmiany. Skupiamy się wtedy na tym, dlaczego wprowadzamy taką zmianę i tłumaczymy zawiłości.
Kiedy po czasie wrócimy do danego fragmentu kodu, pomoże nam to w szybkim przypomnieniu całej sytuacji. A dla innych członków zespołu, będzie to oszczędnością czasu i nerwów.
Przeciwieństwem polecenia $ git add
jest $ git reset
, które wycofuje pliki ze staged area – czyli tych, które zostaną umieszczone w commicie. Natomiast jeśli chcemy wycofać poprzedni commit, polecenie jest już bardziej skomplikowane. $ git reset --soft HEAD~1
oznacza zdjęcie najnowszego commita i umieszczenie całej jego zawartości jako pliki not staged
. Liczba za HEAD~
wskazuje na ilość commitów, do zdjęcia. Flaga --soft
oznacza, że zmiany chcemy zachować, ale nie w commicie. Flaga --hard
usunie commit wraz z jego zmianami.
Jeśli ten commit znajduje się już w zdalnym repozytorium (punkt 7.) należy zachować szczególną ostrożność, ponieważ tworzy to bardzo dużo komplikacji. Na ten moment, w takich przypadkach możemy uznać, że to polecenie nie istnieje 🙂
Dodajemy linijkę tekstu do wcześniej utworzonego pliku:
$ echo "hello world" > init.txt
$ git status
powie nam tym razem, że zmiany w pliku są not staged
, ale plik jest już śledzony w repozytorium, więc polecenie $ git diff
wyświetli nam nasze zmiany. Dzięki temu możemy na bieżąco kontrolować nasze wprowadzone zmiany i pilnować, by nie umieścić tam czegoś czego nie powinno być.
Do lokalnego repozytorium możemy podłączyć dowolną ilość zdalnych, używając innych nazw. Za pomocą polecenia:
$ git remote -v
Możemy wyświetlić nazwy i adresy wszystkich zdalnych repozytoriów. Aby dodać nowy remote, musimy stworzyć najpierw repozytorium GIT. Jeśli nie mamy konta, to je tworzymy wchodząc na https://github.com/signup. Następnie generujemy klucz SSH wpisując w terminalu:
ssh-keygen -t rsa -b 4096
tworzymy go w domyślnym katalogu oraz nadajemy hasło.
Wygenerują nam się dwa klucze, prywatny oraz publiczny. Kopiujemy zawartość pliku ~/.ssh/id_rsa.pub
i wklejamy go do naszego konta na Githubie: https://github.com/settings/ssh/new. W terminalu dodajemy do konfiguracji GITa informacje o nas:
git config --global user.name >nazwa konta na githubie<
git config --global user.email >adres email<
Następnie tworzymy repozytorium, wchodząc na stronę: https://github.com/new.Podajemy nazwę oraz możemy zaznaczyć, aby było prywatne. Po zapisaniu ustawień wyświetli się nam instrukcja, jak połączyć się z repozytorium, wyświetla się ona tylko gdy jest puste. Klikamy na przycisk Code
oraz wybieramy opcję SSH
i kopiujemy link.
Dodajemy utworzone repozytorium jako origin
:
$ git remote add origin >LINK<
Teraz możemy zrobić push naszego commita na zdalne repozytorium:
$ git push origin master
Po odświeżeniu strony, plik pojawi się w katalogu repozytorium.
Bardzo często mamy rzeczy, które nie powinny lub nie mogą znaleźć się w repozytorium (np. logi). Możemy stworzyć plik .gitignore
, w naszym głównym katalogu, zapisując w nim ścieżki do plików, których nie chcemy umieszczać w repozytorium. W internecie możemy znaleźć już gotowe pliki dla poszczególnych języków programowania ze specyficznymi dla nich ścieżkami. Nie znaczy to oczywiście, że w razie potrzeby nie możemy dodać czegoś swojego. https://github.com/github/gitignore/blob/master/Rails.gitignore
Branche pozwalają nam na uporządkowanie pracy; by stworzyć nową możemy użyć komendy:
$ git branch test_branch
a następnie, aby na nią przejść:
$ git checkout test_branch
Możemy również użyć skrótu i stworzyć ją i od razu na nią przejść:
$ git checkout -b test_branch
Aktualna branch i inne istniejące (lokalnie), możemy sprawdzić za pomocą komendy:
$ git branch
Branch jest tworzona na podstawie tej, na której aktualnie jesteśmy, tzn. będzie zawierać wszystkie jej commity.
Należy pamiętać, że bierzemy jedynie commity lokalne, a więc warto przed stworzeniem nowej branchy pobrać aktualną wersję za pomocą $ git pullorigin >Nazwa branchy<
. (jeśli jesteśmy na głównej branchy to nazwą będzie master
)
Gdy już jesteśmy na naszej nowej gałęzi, tworzymy nowy plik.
$ echo "hello world (again)" > some_file.txt
Analogicznie do operacji, które robiliśmy wcześniej, wrzucamy nowy plik do naszego zdalnego repozytorium za pomocą komend:
$ git add .
$ git commit -m "nowy plik testowy"
$ git push origin test_branch
Możemy teraz zaobserwować, że $ git log
wyświetli nam dwa commity. Pierwszy, który zrobiliśmy na poprzedniej gałęzi i nasz aktualny.
Po przejściu na master
i sprawdzeniu logów zobaczymy już tylko jeden commit, a w katalogu nie będzie naszego nowego pliku.
$ git checkout master
$ git log
Teraz przechodzimy na github
i na stronie naszego repozytorium klikamy w Pull requests
oraz w New pull request
. Robimy tak, by base było master
, a source test_branch
. Czyli zawartość branchy test_branch
będziemy dodawać do master . Wyświetlą się nam wszystkie różnice pomiędzy nimi. W tym momencie możemy zweryfikować, czy jest wszystko, co chcieliśmy dodać oraz czy nie ma rzeczy, których nie powinno być. Jeśli wszystko jest OK, klikamy Create pull request
. Jeśli coś jest nie tak, naprawiamy to lokalnie i tworzymy nowy commit.
Nazwą pull requestu domyślnie jest wiadomość ostatniego commita. Możemy ją dowolnie zmienić, tak aby jak najlepiej opisywała co znajduje się w dodawanych zmianach. Możemy również dodać opis. Następnie klikamy Create pull request
.
Code review polega na sprawdzeniu naszych zmian przez innych członków zespołu. W zakładce Files changed
, klikając na konkretny numer linii, mamy opcję napisania komentarza i zaproponowania lepszych rozwiązań lub oznaczyć błędy, które znajdziemy. Cały ten proces pomaga utrzymać kod w lepszym stanie, z mniejszą ilością błędów, ale również pozwala innym członkom zespołu śledzić zmiany w aplikacji.
Jeśli jesteśmy gotowi dodać już nasze zmiany do głównej gałęzi, w zakładce Conversation
znajduje się przycisk Merge pull request
. Naciśnięcie go sprawi dodanie wszystkich naszych commitów do branchy master
.
Teraz, znajdując się na głównej branchy w terminalu, sprawdzając zmiany
$ git log
nic nowego się nie pojawi, ponieważ musimy najpierw pobrać zawartość z repozytorium.
$ git pull origin master
$ git log
I teraz widzimy, że pojawiły się dwa commity. Jeden, który sami stworzyliśmy z nowym plikiem, a drugi pokazujący, że był to pull request
wyświetlając jego nazwę oraz nazwę branchy.
Najważniejsze w używaniu GIT’a jest utrzymywanie czystej historii zmian oraz kontrola tego, co znajdzie się na głównej branchy. Żeby tego dokonać, powinniśmy:
1. Zawsze pracować na osobnej branchy i tworzyć Pull Requesty do głównej gałęzi sprawdzając, czy nie znajduje się tam coś niepożądanego.
2. Nazwy branchy powinny opisywać, to co będą zawierać, tak samo jak commity i jeśli nie pracujemy sami, to opisy pull requestów.
Dodatkowo dobrą praktyką jest tworzenie wszystkich opisów i nazw po angielsku.
Pracując w repozytorium z innymi, możemy natrafić na konflikty. Jeśli podczas zaciągania zmian z repozytorium, posiadamy lokalnie edytowaną tę samą linijkę, wtedy git nie będzie potrafił nanieść zmian i będziemy zmuszeni sami zaznaczyć, jak ma wyglądać wynik. Analogiczna sytuacja wystąpi podczas istnienia dwóch PullRequestów ingerujących w tą samą linijkę. Gdy pierwszy z nich zostanie dołączony do głównej branchy, drugi będzie mieć konflikt.
Będąc na głównej branchy ($ git checkout master
), która jest aktualna ($ git pull origin master
), przejdźmy na nową gałąź:
$ git checkout -b branch_1
Dodajmy linijkę tekstu do naszego istniejącego pliku some_file.txt
:
$ echo "Change from branch_1" >> some_file.txt
Taką zmianę pushujemy na naszą branch i zakładamy Pull Request. (nie mergujemy go)
$ git add .
$ git commit -m "Added line to some_file"
$ git push origin branch_1
Przełączamy się na główną branch ($ git checkout master
) i tworzymy na jej podstawie drugą branch (nie będzie ona zawierać powyższej zmiany):
$ git checkout -b branch_2
Następnie dodajemy do tego samego pliku inny tekst:
$ echo "Change from branch_2" >> some_file.txt
I analogicznie robimy commit i push.
$ git add .
$ git commit -m "Added conflict line to some_file"
$ git push origin branch_2
Tworzymy Pull Request.
W takim stanie posiadamy dwa Pull Requesty
, które możemy zmergować do głównej branchy. Klikamy Merge
na pierwszym Pull Requeście (na bazie branch_1
).
Teraz wchodząc w drugi Pull Request zobaczymy, że merge jest niemożliwy, ponieważ występuje konflikt w pliku some_file.txt
.
Aby go rozwiązać, musimy pobrać aktualną wersję branchy master
.
$ git checkout master
$ git pull origin master
Następnie, po powrocie na naszą branch, gdzie chcemy rozwiązać konflikt, dołączamy aktualny stan branchy master
.
$ git checkout branch_1
$ git merge master
Dostaniemy komunikat, że po zmergowaniu branchy master, posiadamy konflikt. Nasz plik wygląda w tym momencie w następujący sposób:
hello world (again)
<<<<<<< HEAD
Change from branch_2
=======
Change from branch_1
>>>>>>> master
Pomiędzy znacznikami <<<<<<< HEAD i =======
znajduje się kod z naszej branchy, a od ======
do >>>>>>>
master znajduje się kod z branchy nazwanej w znaczniku, w tym wypadku master.
Aby pozbyć się konfliktu, musimy usunąć te znaczniki, zachowując przy tym pożądany przez nas wynik. Możemy zachować obie zmiany, jedną z nich lub nawet połączyć je w nieoczywisty sposób, np.:
hello world (again)
Change from branch_1 and branch_2
Po rozwiązaniu konfliktu, robimy commit. Natomiast nie podając jego nazwy, utworzy się commit z komunikatem o operacji. W tym wypadku będzie to Merge branch 'master' into branch_2
.
$ git add .
$ git commit
$ git push origin branch_2
(z edytora commitu wychodzimy poprzez wciśnięcie kombinacji klawiszy :wq
)
Teraz nasz PullRequest jest gotowy do zmergowania.
Na stronie repozytorium Github znajduje się zielony przycisk “Code”. Po jego wciśnięciu dostaniemy kilka opcji dostępu. Wybieramy opcję ssh i kopiujemy zawartość.
W terminalu, w miejscu w którym chcemy pobrać repozytorium, używamy komendy:
$ git clone >ssh link repozytorium<
Wszystkie pliki zostaną pobrane do katalogu o nazwie takiej samej jak repozytorium.
Tagi
Istnieje możliwość wersjonowania/tagowania konkretnych stanów repozytorium. Można je podejrzeć klikając na listę branchy i przełączając widok na tags
. W dalszej części kursu będziemy wersjonować każdą lekcję, tak aby po skończeniu kursu, można było wybrać konkretną lekcję. Prace własne będą również udostępniane jako tag, ale też jako pull request, aby można było zobaczyć zmiany. Aby pobrać konkretną wersję do nowego katalogu, możemy użyć polecenia:
git clone >ssh link repozytorium< --branch >nazwa taga<
lub jeśli już posiadamy sklonowane repozytorium, możemy pobrać tag w ten sam sposób co branch:
git checkout >nazwa taga<
CheatSheet
$ git pull origin >branch<
– pobiera zawartość gałęzi ze zdalnego repozytorium na gałąź, na której się aktualnie znajdujemy
$ git branch >branch<
– tworzy nową gałąź
$ git checkout >branch<
– zmienia gałąź
$ git checkout -b >branch<
– tworzy i zmienia gałąź
$ git add
– wszystkie wprowadzone zmiany zostaną przygotowane do commita
$ git commit -m >wiadomosc<
– tworzy commit
$ git push origin >branch<
– umieszcza nasze zmiany na zdalnym repozytorium
$ git merge >branch<
– dołącza podaną lokalną branch do tej, na której się aktualnie znajdujemy
$ git clone >ssh link<
– pobiera repozytorium
Dodatkowo:
$ git checkout
. – wycofa wprowadzone zmiany, które są not staged do stanu z ostatniego commita
$ git fetch origin >branch<
– pobierze branch ze zdalnego repozytorium, by móc się przełączyć na jej lokalną wersję.
Dodając origin/ przed nazwą branchy w dowolnym poleceniu, wymuszamy użycie branchy z remote origin .
1. Pobierz repozytorium z naszym kursem: https://github.com/binarapps/ruby-on-rails-course
2. Stwórz nową branch, której nazwa zaczyna się Twoimi inicjałami
3. Zedytuj plik requirements.txt
, dodając w drugiej linijce “I don’t know it yet”, czwartej linijce “I know GIT”.
4. Domerguj branch git-branch-pr
. (Uwaga: branch znajduje się na zdalnym repozytorium, nie posiadacie jej lokalnie. GIT Wam podpowie co zrobić.)
5. Rozwiąż konflikty wybierając w drugiej linijce tekst pochodzący z branchy git-branch-pr
, a w czwartej ten, który został dodany przez Ciebie.
Repozytorium to będzie używane w dalszej części kursu. Na głównej branchy będziemy aktualizować stan aplikacji oraz umieszczać rozwiązania prac własnych. Możecie dodać sobie drugi remote, który będzie Waszym repozytorium, by przypadku większych problemów, podczas wykonywania instrukcji, dać nam możliwość zajrzenia w Wasz kod.
Przeczytaj również o...
It has already become clear that User Experience (UX) is a key factor in shaping how companies build a business. The customer-centric approach has almost completely replaced […]
What if there was one simple method to find opportunities for improved design, uncover UX problems, and learn about your target users’ behavior and preferences? Would you […]