21.12.20215 min

Michał WierbaJava DeveloperSagiton

Przydatne komendy gita

Git to dziś narzędzie, bez którego trudno sobie wyobrazić pracę nad oprogramowaniem. Warto więc wyjaśnić, jak działa tam swoisty odpowiednik schowka.

Przydatne komendy gita

Powiedzmy wprost: git, czyli system kontroli wersji, będący obecnie standardem w branży IT, do intuicyjnych narzędzi nie należy. Fakt, że kiedy zrozumiemy już podstawowe koncepcje i prawa rządzące światem gita, praca z nim staje się szybka i niezwykle efektywna. Niestety krzywą uczenia git ma dość stromą i nawet doświadczonemu użytkownikowi zdarza się czasem jedną źle sformułowaną komendą tak namieszać w naszym repozytorium, że wszechobecne spoty gałęzi gita stają się splotami Czerwia Pustyni, a my czujemy się jak Atrydzi na Diunie - bez nadziei na ratunek ;)

W tej serii artykułów pokażę Wam kilka komend mocy gita, które pozwolą Wam poczuć się jak mistrz Jedi i przywrócić porządek w Galaktyce (repozytorium).  Dowiecie się jak bez ryzyka podróżować po splotach branchy gita, jak wytropić zaginione zmiany i jak szybko odnaleźć commit, który wprowadził zamieszanie w repozytorium. Do dzieła!


Na start

Pierwszą komendą, którą chcę opisać jest git stash, czyli schowek. Bardzo często używam go podczas pracy, ponieważ pozwala na szybkie zapisywanie zmian w podręcznym „schowku”, który nie zmienia struktury repozytorium i zaaplikowanie ich na dowolnym commicie.


Czym jest stash?

Czym zatem jest git stash?

Jest to mechanizm, który umożliwia zapisanie zmian w lokalnym repozytorium i jednoczesne przywrócenie stanu working directory do stanu określonego przez wskaźnik HEAD. Zapisane zmiany trafiają do „stash” czyli „schowka”, skąd będą mogły być później odzyskane. Schowek jest mechanizmem niezależnym od commitów i loga, świetnie nadaje się zatem do przechowywania zmian stanowiących Work-in-progress, gdyż nie jest uwzględniany w historii commitów i nie zostaje wypchnięty do zdalnego repozytorium.

Aby skorzystać ze schowka, wystarczy utworzyć nowy plik, lub dokonać zmian w istniejącym i wywołać polecenie git stash:

Komenda git stash zwróci nam następujące informacje:
1. informacje o zapisaniu working directory,
2. informacje o zapisaniu stanu indexu,
3. nazwę brancha i hash commita, na które wskazuje HEAD w momencie utworzenia wpisu w schowku, czyli potocznie tzw. ,,stasha”. Tutaj uwaga: ,,stash” jest zarówno poleceniem, mechanizmem wewnątrz gita, który służy do zapisywania podręcznych zmian (bez zaburzania historii commitów), jak również potocznym określeniem pojedynczego zapisu, znajdującego się w schowku. Ale do tego, co wymienione powyżej informacje oznaczają jeszcze wrócimy. 

Domyślnie git stash zapisuje zmiany, które zostały wcześniej dodane do indexu. Możemy to zmienić dodając flagę -u lub —include-untracked. Trzeba jeszcze dodać, że schowek działa na zasadzie LIFO (last-in-first-out), co oznacza, że ostatni dodany element będzie pierwszym, który otrzymamy z powrotem. Domyślnym formatem wiadomości  w poleceniu git stash jest „WIP on {branch-name}: {commit-sha-1-hash}​ {commit-message}”, ale możemy dodać własną wiadomość za pomocą flagi -m lub —messsage.  Dobrze jest dodawać takie opisowe wiadomości, ponieważ przy dużej ilości wpisów w ,,stashu”, domyślne wiadomości nie są zbyt pomocne podczas identyfikacji poszczególnych ,,stashy”.

Domyślnie komenda git stash dodaje do schowka tylko zmiany ze śledzonych plików. Jeśli skorzystamy z flagi -u ,to w ,,stashu” znajdą się również zmiany z nieśledzonych plików. Jeśli chcemy dodać do slasha tylko zmodyfikowane pliki, nieznajdujące się w indeksie, to skorzystamy z flagi —keep-index lub -k.


Wyświetlanie listy

Aby sprawdzić, jakie wpisy znajdują się w „stashu”,  trzeba użyć komendy git stash list. Dokładniejszą informację o zmianach zawartych w danym wpisie uzyskamy za pomocą komedy git stash show stash{numer-wpisu}.

Jeśli chcemy zobaczyć jakie zmiany wprowadza dany wpis, skorzystajmy z flagi -p lub —pretty.



Aktywacja zmian

Teraz, kiedy wiemy już jak umieścić nasze zmiany w schowku i zobaczyć, co się w nim znajduje, czas wydobyć nasze zmiany i zaaplikować w naszym working directory. Możemy to zrobić na dwa sposoby.

Po pierwsze możemy skorzystać z komendy git stash apply (podając opcjonalnie numer wpisu ze schowka stash@{numer-stasha}). Wtedy zmiany z naszego schowka zostaną dodane do working directory i jednocześnie będą dalej przechowywane w schowku.

Po drugie możemy skorzystać z git stash pop. Wtedy zmiany zostaną dodane do working directory i jednocześnie ucięte ze schowka.


Czyszczenie stasha

Kiedy stash nie jest już potrzebny, możemy wyczyścić jego zawartość. Służą do tego polecenia clear i drop. Za pomocą drop możemy usunąć wybrany wpis, podając jego numer. Jeśli nie podamy żadnego numeru, usuniemy ostatni wpis. 

Polecenie clear usuwa wszystkie zmiany zapisane w stashu.


Utworzenie nowego brancha ze stasha

Może się zdarzyć, że będziemy chcieli utworzyć nowy branch dla zmian, które mamy zapisane w stashu. Służy do tego polecenie git stash branch <nazwa-nowego-brancha stash_id>. Git utworzy wtedy nowego brancha na commicie, z którego utworzyliśmy stash, usunie zmiany ze stasha i doda je do working directory.


Tworzenie stasha bez zmian w reflogu

Git przechowuje ostatni utworzony stash w folderze .git/refs/stash, pozostałe „stashe” znajdują się w reflogu dla referencji ‚stash’. Czasem może się zdarzyć, że będziemy chcieli utworzyć stash bez zmieniania reflogu. Wtedy możemy skorzystać z polecenia git stash create. Utworzy ono stash i zwróci jego sha-1 hash, bez dodawania go do reflogu stasha.

Później będziemy mogli dodać ten obiekt do reflogu stasha za pomocą polecenia git stash store <sha-1-hash>.


W jaki sposób git zachowuje zmiany w stashu?

Kiedy wywołujemy polecenie git stash, git tworzy obiekt typu commit w folderze .git/refs/stash.  

Ten commit przechowuje stan working directory. 

Kiedy podejrzymy go poleceniem git cat-file -p, zobaczymy, ze ten commit ma dwóch rodziców! Pierwszym jest commit, na którym znajdował się wskaźnik HEAD w momencie wywołania polecania stash. Drugi przechowuje stan indexu w tym momencie.

Ostatni utworzony wpis w stashu jest przechowywany w folderze refs/stash. Starsze schowki znajdują się w reflogu. 


Kiedy zatem używać stasha?

  1. Kiedy pracujemy nad zadaniem i nagle musimy wykonać hot-fixa o najwyższym priorytecie. Nasze obecne zmiany są jeszcze niegotowe, więc nie będziemy ich commitować, dlatego zachowamy je w stashu. Możemy teraz przenieść się na dowolnego brancha, dokonać niezbędnych poprawek, po czym wrócić do przerwanej pracy.
  2. Może zdarzyć się, że w ferworze walki z jakimś wyjątkowo złośliwym bugiem nie zorientujemy się, że pracujemy na niewłaściwym branchu. Manualne kopiowanie zmian nie jest na szczęście konieczne, wystarczy zachować zmiany w stashu i zaaplikować na właściwym branchu.
  3. Kiedy jesteśmy w trakcie pracy nad zmianą i nagle dowiadujemy się, że w zdalnym repozytorium zaszły zmiany, które musimy włączyć do naszej pracy. Git pull odmawia nadpisania naszych zmian - wystarczy schować zmiany w stashu, wykonać git pull, a następnie odzyskać zmiany ze schowka


Mam nadzieję, że ta użyteczna komenda pomoże Wam pokonać lęk przed utraceniem zmian, kiedy przełączacie się między branchami. Być może poprawi Waszą swobodę w pracy z gitem i przybliży Was do gitowego „mistrzostwa” :) Ja osobiście korzystam ze stasha bardzo często, zwłaszcza kiedy otrzymuję dużo „wrzutek”, a jednocześnie muszę pracować nad bieżącymi zadaniami. 

<p>Loading...</p>