Jest to kolejny wpis z serii wpisów z pytaniami rekrutacyjnymi na stanowisko web developera. Listę wszystkich poprzednich wpisów z tej serii znajdziesz poniżej. Zachęcam Cię do zapoznania się jeśli jeszcze nie miałeś/aś okazji:
- Web developer – pytania rekrutacyjne cz. 1
- Web developer – pytania rekrutacyjne cz. 2
- Web developer – pytania rekrutacyjne cz. 3
- Web developer – pytania rekrutacyjne cz. 4
- Web developer – pytania rekrutacyjne cz. 5
- Web developer – pytania rekrutacyjne – React
- Web developer – pytania rekrutacyjne – TypeScript
- Web developer – pytania rekrutacyjne – Docker
- Programista – pytania rekrutacyjne – bazy danych
W tym artykule motywem przewodnim będzie Git, czyli jeden z najpopularniejszych systemów kontroli wersji. Do napisania tego artykułu zainspirowała mnie książka Pro Git autorstwa Scotta Chacona i Bena Strauba, którą polecam zarówno tym osobom, które chcą zacząć przygodę z Gitem, jak i tym znającym już podstawy. Całą listę polecanych przeze mnie książek możesz znaleźć na stronie z polecanymi książkami.
Pytania z Gita pojawiły się już kilkukrotnie w innych artykułach tej serii. Aby zebrać wszystkie pytania w jednym miejscu, pytania te zostaną tu ponownie podane wraz z linkami do odpowiadających im artykułów.
1. Czym jest Git / czym są systemy kontroli wersji? Do czego je wykorzystujemy?
Pytanie to ma na celu zweryfikowanie czy rozmówca ma jakiekolwiek pojęcie o celu i sposobie działania systemów kontroli wersji. Git jest jednym z najpopularniejszych rozproszonych systemów kontroli wersji (DVCS – Distributed Version Control Systems). Rozproszony system kontroli wersji cechuje się tym, że w przeciwieństwie do scentralizowanych systemów kontroli wersji (CVCS – Centralized Version Control Systems), nie jest potrzebny centralny serwer. Git, a także inne DVCS, mogą być używane całkowicie lokalnie, bez żadnego bytu centralnego. Z kolei same systemy kontroli wersji to narzędzia rozwiązujące kilka istotnych problemów:
- Przede wszystkim systemy kontroli wersji umożliwiają to co sama nazwa wskazuje, czyli wersjonowanie projektu. Nie mam tu na myśli jednak wersjonowania rozumianego jako oznaczenie oprogramowania na przykład numerem wersji. Mam tu na myśli możliwość prześledzenia każdej zmiany, która zaistniała w projekcie. Oznacza to również możliwość cofnięcia się do dowolnego poprzedniego stanu projektu.
- System kontroli wersji pomaga dokumentować zmiany w projekcie. W Gicie, podstawowym bytem jest commit, którego elementem składowym jest opis. Na opis może składać się zarówno informacja co zostało zmienione, ale może zawierać też cel tej zmiany. Bardzo zachęcam do zapoznania się z poradnikiem jak pisać dobre opisy commitów, bo wbrew pozorom nie jest to łatwe zadanie.
- Dzięki VCS możliwa jest praca nad kilkoma rzeczami jednocześnie i niezależnie od siebie. Do tego celu został stworzony mechanizm gałęzi (branchy). Gałęzie jednocześnie zwiększają wygodę pracy nad projektem w zespołach. Mechanizm gałęzi pozwala na pracę wielu programistów nad tym samym kodem bez przeszkadzania sobie nawzajem.
2. Jaka jest różnica między Gitem a GitHubem?
Pytanie nieco żartobliwe, ale jego cel jest taki sam jak poprzedniego pytania. Można na nie odpowiedzieć żartobliwie na przykład: „taka jak pomiędzy krzesłem a krzesłem elektrycznym”.
Można także odpowiedzieć całkowicie poważnie. Git, tak jak odpowiedziałem w poprzednim pytaniu jest systemem kontroli wersji, natomiast GitHub jest platformą zajmującą się hostingiem kodu źródłowego wykorzystującą Gita oraz dostarczającą cały zestaw udogodnień i narzędzi do pracy nad projektem.
3. Czym jest „bare repository”?
Przy inicjalizacji repozytorium za pomocą polecenia git init
można skorzystać z flagi --bare
. W konsekwencji takie repozytorium zostanie „nagim” repozytorium, czyli niezawierającym faktycznych kopii plików / kodu źródłowego a jedynie historię zmian. Tego typu repozytioria mogą służyć jako repozytoria przechowywane na serwerze i pełnić rolę przekaźników do udostępniania i pobierania zmian. W konsekwencji pozwala to na stworzenie strutkury jak na rysunku poniżej:
Powyższa infrastruktura pozwala na synchronizację zmian pomiędzy klientami, a jednocześnie serwer przechowuje jedynie historię zmian, a nie fizyczny kod źródłowy.
4. Jak można wyświetlić historię zmian w Gicie?
Podstawowym poleceniem do wyświetlania historii zmian jest polecenie git log
opisane w artykule Web developer – pytania rekrutacyjne cz.2 w pytaniu nr 9. Można do tego celu posłużyć się również poleceniem git shortlog
, które w przejrzystej formie wyświetli listę kontrybutorów wraz z commitami.
5. Jak utowrzyć nową gałąź? Jak zmienić aktywną gałąź?
Pytanie oryginalnie pojawiło się w artykule Web developer – pytania rekrutacyjne cz. 4 w pytaniu nr 6. Odpowiedź brzmi następująco:
git branch nazwa_brancha
– utwórz nową gałąź.git checkout nazwa_brancha
– zmiana aktywnej gałęzi.git checkout -b nazwa_brancha
– utworzenie oraz zmiana aktywnej gałęzi.
6. Czym jest konflikt w Gicie? Kiedy w Gicie może wystąpić konflikt? Jak można go rozwiązać?
Odpowiedź na to pytanie znajduje się w artykule Web developer – pytania rekrutacyjne cz. 5 w pytaniu nr 5.
7. Czym się różni git fetch od git pull?
Polecenie git fetch
jedynie pobiera dane o zmianach ze zdalnego repozytorium. Polecenie git pull
oprócz pobrania zmian ze zddalnego repozytorium podejmuje próbę scalenia ich (merge) z aktywną gałęzią. Podczas scalania może wystąpić konflikt wspomniany w poprzednim pytaniu.
8. Do czego służy polecenie git commit –amend?
Polecenie git commit --amend
pozwala na modyfikację ostatniego commita w repozytorium. Jest to szczególnie przydatne w sytuacji gdy jakiś plik lub zmiana podczas tworzenia commita zostaną pominięte lub w przypadku błędnego commit message.
Warto pamiętać, że nie powinno się korzystać z tego polecenia po wysłaniu commita do repozytorium zdalnego! Polecenie to modyfikuje historię Gita i jego wywołanie może w konsekwencji utrudnić pracę innym osobom pracującym z tym samym repozytorium.
9. Czym jest squash commitów?
Squash commitów jest scaleniem kilku commitów w jeden. Na przykład, w serwisie GitHub takie zachowanie można zdefiniować w momencie scalania pull requestów. W takim przypadku wszystkie commity ze scalanego pull requesta zostaną połączone w jeden, a następnie scalone z gałęzią docelową. W Gicie można taki rezultat uzyskać dzięki poleceniu git rebase
. Podobnie brzmiące pytanie zostało postawione w artykule Web developer – pytania rekrutacyjne cz. 5 – pytanie nr 15.
10. Do czego służy Git LFS?
Git nie jest najlepszy miejscem do przechowywania dużych plików, czy plików binarnych tj. obrazy, filmy czy pliki audio. W tym celu powstało narzędzie o nazwie Git LFS (Large File System). Dzięki temu, w repozytorium nie są przechowywane pliki a jedynie wskaźniki (referencje) do nich. Typy plików, przechowywanych przez Git LFS można zdefiniować w pliku .gitattributes
. Przykładowo, chcąc wykorzystać Git LFS do plików z formatem JPG należy zdefiniować następującą regułę: git lfs track "*.jpg"
.
11. Opisz stany w jakich może znajdować się zmiana w Gicie.
Wyróżniamy trzy stany w jakich może znajdować się zmiana w repozytorium. Pierwszym stanem jest stan modified. W tym stanie są domyślnie wszystkie modyfikacje poczynione od ostatniego commita. Drugim stanem jest stan staged. Aby zmiana znalazła się w tym stanie, należy skorzystać z polecenia git add
i wybrać zmiany. Przy poleceniu git commit
pod uwagę brane są tylko zmiany będące w stanie staged. Ostatnim stanem jest stan commited, czyli stan w którym zmiana została zapisana w repozytorium. Przy commitowaniu możliwe jest pominięcie stanu staged poprzez skorzystanie z flagi -a
przy wywołaniu polecenia git commit
.
12. Jak można skopiować commit na inną gałąź?
Do kopiowania commitów i dodawania ich na inne gałęzie służy polecenie git cherry-pick sha_commita
. Wykonanie tego polecenia spowoduje kopię commita z podaną referencją i dodaniem go do aktywnej gałęzi. Referencję do commita możemy uzyskać za pomocą polecenia git log
, którego dotyczyło jedno z poprzednich pytań.
Podsumowanie
Przygotowując te pytania starałem się wybrać zarówno proste pytania jak i te nieco bardziej zaawansowane. Starałem się również dobrać pytania tak, aby zapytać o zagadnienia, z którymi spotykam się podczas codziennej pracy z Gitem. Jeśli uważasz że jakiegoś pytania tu zabrakło to zachęcam do podzielenia się nim w komentarzu!
Źródła i materiały dodatkowe
- https://git-scm.com/book/pl/v2
- https://scmquest.com/centralized-vs-distributed-version-control-systems
- https://guides.github.com/activities/hello-world
- https://chris.beams.io/posts/git-commit
- https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository
- https://devszczepaniak.pl/web-developer-pytania-rekrutacyjne-cz-2
- https://git-scm.com/docs/git-log
- https://git-scm.com/docs/git-shortlog
- https://devszczepaniak.pl/web-developer-pytania-rekrutacyjne-cz-4
- https://devszczepaniak.pl/web-developer-pytania-rekrutacyjne-cz-5
- https://www.git-tower.com/learn/git/faq/difference-between-git-fetch-git-pull
- https://git-scm.com/book/pl/v2/Podstawy-Gita-Cofanie-zmian
- https://www.atlassian.com/git/tutorials/rewriting-history
- https://git-lfs.github.com
- https://serengetitech.com/en/blog/tech/three-states-of-git-and-three-sections-of-a-git-project
- https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F
- https://www.atlassian.com/git/tutorials/cherry-pick
Zapisz się na mailing
Zapisując się na mój mailing będziesz otrzymywać wartościowe treści powiadomienia o najnowszych wpisach na skrzynkę email.