Dziwne symbole w gicie. Wyjaśnienie co oznaczają znaki @, ^ i ~

Opublikowane przez Tomasz Prasołek w dniu

Git jest bardzo elastyczny, można przeglądać historię projektu z poziomu konsoli i mamy możliwość dobrania się do każdego commita. Zaraz dowiesz się jak to zrobić.

W tym poście zajmiemy się symbolami @ (małpa), ^ (potęga), ~ (tylda). Co one oznaczają i jak ich używać?

Małpa – @

To bardzo proste, znak małpy oznacza HEAD. Co to jest HEAD pisałem we wpisie: Podstawowe pojęcia związane z GITem. Chcąc zobaczyć szczegóły ostatniego commita możemy wpisać:

git show HEAD

albo

git show @

Dwa powyższe polecenia są jednoznaczne.

To tyle w temacie małpy 🙂 Będziemy jej używać w kolejnych przykładach.

Przejdziemy teraz do tematu trochę bardziej zakręconego. Do wyjaśnienia ^ i ~ muszę mieć testowe repozytorium.

Przykładowe repozytorium

Przygotowałem testowe repozytorium:

git log graph
  • Pierwsze 3 commity zostały zrobione na branchu master (patrz od dołu 🙂 )
  • Kolejne 3 (od czwartego do szóstego) zostały zrobione na branchu feature_branch i zmerdżowane do master. Merge był typu fast-forward, bo na master nie było żadnych zmian.
  • Siódmy commit został zrobiony na master.
  • Ósmy commit został zrobiony na branchu feature_branch_2
  • Dziewiąty w kolejności commit to tzw. merge commit
  • Dziesiąty commit, które jest błędnie nazwany “Dziewiąty commit” 🙂 został już zrobiony na masterze.

Do powyższego zrzutu ekranu będziesz jeszcze kilka razy wracał 🙂 Najlepiej będzie jeśli uruchomisz go w nowej zakładce w przeglądarce, aby łatwo Ci było na niego się przełączyć.

Potęga – ^

Znak ten postawiony obok commita oznacza jego rodzica. Jak już wiemy, aby zobaczyć najnowszy commit można wpisać:

$ git show --oneline @
17de991 (HEAD -> master) Dziewiąty commit

A żeby zobaczyć rodzica najnowszego commita trzeba wpisać:

$ git show --oneline @^
538a0f5 Merge branch 'feature_branch_2'

I wszystko się zgadza 🙂 Zapis @^ (lub HEAD^) jest równoznaczny z zapisem @^1 (HEAD^1), czyli pokaż pierwszego rodzica. Jak już pewnie wiesz commit może mieć dwoje rodziców jeśli jest to merge commit. Czyli jeśli wpiszemy @^2 to dostaniemy błąd:

$ git show --oneline @^2
fatal: ambiguous argument '@^2': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Bo najnowszy commit ma tylko jednego rodzica. Jednak po wpisaniu:

$ git show --oneline 538a0f5^2
f1a8f60 (feature_branch_2) Ósmy commit - na feature branch

Dostajemy informację, że rodzicem 538a0f5, czyli merge commita jest to “Ósmy commit – na feature branch”.

Tylda – ~

Znak ten postawiony obok commita oznacza jego przodka. Czyli wpisując:

$ git show --oneline @~
538a0f5 Merge branch 'feature_branch_2'

Dowiedzieliśmy się, że przodkiem najnowszego commita jest merge commit. Zapis @~ jest równoznaczy co @~1, czyli pokaż pierszego przodka.

Widać stąd, że @^ jest równoznaczne co @~, wskazują na ten sam commit. Jednak na tym podobieństwa się kończą 🙂 .

Czyli jeśli chcemy zobaczyć praprzodka najnowszego commita musimy wpisać:

$ git show --oneline @~2
b9bd44e Siódmy commit - na master

Pokazało nam commit z mastera, bo domyślnie pokazuje pierwszego rodzica danego commita.

Jeśli natomiast chcielibyśmy zobaczyć drugiego rodzica przodka najnowszego commita (mam nadzieję, że jeszcze to rozumiesz 🙂 ), czyli drugiego rodzica naszego merge commita, to w poprzednim akapicie wpisaliśmy coś takiego:

$ git show --oneline 538a0f5^2
f1a8f60 (feature_branch_2) Ósmy commit - na feature branch

Znaleźliśmy commita i wpisaliśmy początek jego hasha. Znając co oznacza tylda można to samo osiągnąć wpisując takie połączenie symboli:

$ git show --oneline @~1^2
f1a8f60 (feature_branch_2) Ósmy commit - na feature branch

Zastosowanie praktyczne

Ze znaku @ i ~ korzystam regularnie.

git show @

Gdy chcę zobaczyć zmiany zrobione w najnowszym commicie.

git rebase -i HEAD~3

Gdy chcę coś pozmieniać coś w ostatnich commitach używam trybu rebase interactive.

Ze znaku ^ nigdy nie korzystałem. Czasami jak muszę przejrzeć commity przed merge commitem, to wtedy zawsze sięgam po aplikację z GUI – gitk lub SourceTree. Przeważnie do przejrzenia jest nie jeden commit, a kilka.

Podsumowanie

  • @ – HEAD – najnowszy commit
  • ^ – rodzic commita
  • ~ – przodek commita

Dla ułatwienia jeszcze przygotowałem rysunek 🙂

git log graph

Używając tych symboli można dobrać się do każdego commita w historii naszego projektu 🙂

Zdjęcie wykorzystane we wpisie pochodzi z portalu unsplash.com i zostało zrobione przez: unsplash-logoHarald Arlander


Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *