Close

Zaawansowany dziennik Git

Celem każdego systemu kontroli wersji jest rejestrowanie zmian w kodzie. To daje możliwość cofania się w historii projektu celem sprawdzenia wkładu poszczególnych osób, ustalenia momentu wprowadzenia błędów oraz cofnięcia problematycznych zmian. Jednakże dostęp do całej tej historii jest bezużyteczny, jeśli się nie wie jak się nią posługiwać. Tu właśnie przydaje się polecenie git log.

Na tym etapie podstawowe polecenie git log służące do wyświetlania commitów powinno już być Ci znane. Możesz jednak wpłynąć na jego efekt końcowy za pomocą wielu różnych parametrów.

Zaawansowane funkcje git log można podzielić na dwie kategorie: formatowanie sposobu wyświetlania poszczególnych commitów oraz filtrowanie, które z commitów zostaną uwzględnione w danych wyjściowych. Połączenie tych dwóch funkcji daje Ci możliwość wglądu w historię projektu i znalezienia wszelkich niezbędnych informacji.


Formatowanie danych wyjściowych dziennika


Przede wszystkim przyjrzyjmy się licznym sposobom formatowania danych wyjściowych git log. Większość ma postać flag, które pozwalają określić zakres informacji otrzymywanych za pomocą polecenia git log.

Jeśli nie pasuje Ci domyślny format git log, możesz użyć funkcji aliasowania git config, aby stworzyć skrót do dowolnej z opcji formatowania omówionych poniżej. Informacje o tym, jak ustawić alias, znajdziesz w sekcji Polecenie git config.

Oneline

Flaga --oneline skraca każdy commit do pojedynczego wiersza. Domyślnie wyświetla tylko identyfikator commitu oraz pierwszy wiersz jego komunikatu. Typowy wynik polecenia git log --oneline będzie wyglądał mniej więcej następująco:

0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base

Jest to bardzo przydatne do uzyskania ogólnego obrazu projektu.

Bazy danych
materiały pokrewne

Jak przenieść pełne repozytorium Git

Logo Bitbucket
POZNAJ ROZWIĄZANIE

Poznaj środowisko Git z rozwiązaniem Bitbucket Cloud

Decorating

Czasami warto wiedzieć, z jakimi gałęziami lub tagami związany jest dany commit. Flaga --decorate sprawia, że git log wyświetla wszystkie odniesienia (gałęzie, tagi itp.), które wskazują na dany commit.

Można to połączyć z innymi opcjami konfiguracyjnymi. Przykładowo uruchomienie polecenia git log --oneline --decorate sformatuje historię commitów w następujący sposób:

0e25143 (HEAD, main) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base

Dzięki temu wiesz, że górny commit (oznaczony jako HEAD) został wyewidencjonowany i że jest to również końcówka gałęzi main. Na drugi commit wskazuje kolejna gałąź o nazwie feature, a czwarty commit jest otagowany jako v0.9.

Gałęzie, tagi, oznaczenie HEAD i historia commitów to niemal wszystkie informacje zawarte w repozytorium Git, zatem daje Ci to w miarę pełny obraz jego logicznej struktury.

Diffs

Polecenie git log obejmuje wiele opcji wyświetlania wykazu różnic dla każdego commitu. Do najczęściej używanych należą --stat i -p.

Opcja --stat pozwala wyświetlić liczbę wstawień i usunięć w każdym pliku zmodyfikowanym przez dany commit (zauważ, że edycja wiersza jest przedstawiana jako 1 wstawienie oraz 1 usunięcie). Jest to przydatne, gdy chce się uzyskać krótkie podsumowanie zmian wprowadzonych przez dany commit. Przykładowo następujący commit dodał 67 wierszy w pliku hello.py i usunął z tego pliku 38 wierszy:

commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date:   Fri Jun 25 17:30:28 2014 -0500

    Add a new feature

 hello.py | 105 ++++++++++++++++++++++++-----------------
 1 file changed, 67 insertion(+), 38 deletions(-)

Liczba znaków + i - obok nazwy pliku wskazuje względną liczbę zmian w każdym pliku zmodyfikowanym przez commit. To daje nam jakieś rozeznanie, gdzie można znaleźć zmiany związane z danym commitem.

Jeśli chcesz zobaczyć faktyczne zmiany wprowadzone przez każdy commit, możesz rozszerzyć polecenie git log o opcję -p. To skutkuje wyświetleniem całej poprawki odpowiadającej danemu commitowi:

commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date:   Fri Jun 25 17:31:57 2014 -0500

    Fix a bug in the feature

diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")

W przypadku commitów wprowadzających dużą liczbę zmian wynik może być dość długi i zagmatwany. Zazwyczaj, gdy wyświetlasz pełną poprawkę, szukasz jednej konkretnej zmiany. W tym celu możesz użyć opcji „kilof” (pickaxe).

Shortlog

Polecenie git shortlog jest specjalną wersją git log przeznaczoną do tworzenia ogłoszeń o wydaniach. Grupuje ono każdy commit według autora i wyświetla pierwszy wiersz komunikatu każdego commitu. To prosty sposób na sprawdzenie kto nad czym pracował.

Jeśli na przykład dwoje programistów wykonało 5 commitów w projekcie, wynik git shortlog może wyglądać następująco:

Mary (2):
      Fix a bug in the feature
      Fix a serious security hole in our framework

John (3):
      Add the initial code base
      Add a new feature
      Merge branch 'feature'

Domyślnie git shortlog sortuje dane wyjściowe według nazw autorów, ale możesz też przekazać opcję -n celem sortowania według liczby commitów na autora.

wykresy

Opcja --graph służy do wyświetlenia wykresu w formacie ASCII przedstawiającego strukturę gałęzi w historii commitów. Opcja ta jest powszechnie stosowana w połączeniu z --oneline i --decorate, aby ułatwić określenie, który commit należy do której gałęzi:

git log --graph --oneline --decorate

W przypadku prostego repozytorium z tylko 2 gałęziami efekt będzie następujący:

*   0e25143 (HEAD, main) Merge branch 'feature'
|\  
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/  
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base

Gwiazdka wskazuje, na której gałęzi nastąpił commit, zatem na powyższym wykresie widzimy, że commity 23ad9ad i 16b36c6 znajdują się w gałęzi tematycznej, a pozostałe w gałęzi main.

Choć jest to dobra opcja w przypadku prostych repozytoriów, do mocniej rozgałęzionych projektów lepiej użyć bardziej funkcjonalnego narzędzia wizualizacyjnego, takiego jak gitk czy Sourcetree.

Formatowanie niestandardowe

Dla wszystkich innych potrzeb związanych z formatowaniem git log można użyć opcji --pretty=format:"". To pozwala wyświetlić commity w wybrany przez siebie sposób, używając symboli zastępczych w stylu printf.

Przykładowo znaki %cn, %h i %cd w następującym poleceniu zostają zastąpione odpowiednio nazwą użytkownika osoby zatwierdzającej, skróconym hashem commitu oraz datą zatwierdzenia.

git log --pretty=format:"%cn committed %h on %cd"

Efektem jest następujące formatowanie każdego commitu:

John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500 John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500 Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500 John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500

Pełną listę symboli zastępczych można znaleźć w sekcji Pretty Formats na stronie podręcznika dotyczącej polecenia git log.

Oprócz ograniczania zakresu zwracanych informacji do tych faktycznie potrzebnych opcja --pretty=format:"" jest szczególnie przydatna, gdy próbujesz przekierować dane wyjściowe z git log do innego polecenia.

Filtrowanie historii commitów


Formatowanie sposobu wyświetlania commitów to tylko połowa sukcesu w zakresie obsługi git log Drugą połowę stanowi zrozumienie, jak poruszać się po historii commitów. W dalszej części artykułu przedstawiamy kilka zaawansowanych sposobów znajdowania konkretnych commitów w historii projektu za pomocą git log. Wszystko to można połączyć z dowolnymi opcjami formatowania omówionymi powyżej.

Według ilości

Najbardziej podstawową opcją filtrowania git log jest ograniczenie liczby wyświetlonych commitów. Jeśli interesują Cię tylko ostatnie commity, opcja ta pozwala Ci uniknąć wyświetlania wszystkich commitów naraz.

Możesz ograniczyć dane wyjściowe git log za pomocą opcji -. Przykładowo poniższe polecenie spowoduje wyświetlenie tylko 3 najnowszych commitów.

git log -3

Według daty

Jeśli szukasz commitu z określonego przedziału czasowego, możesz użyć flag --after i --before do przefiltrowania wyników według daty. Obie flagi dopuszczają różne formaty dat. Przykładowo poniższe polecenie spowoduje wyświetlenie wyłącznie commitów, które zostały utworzone po 1 lipca 2014 r. (włącznie):

git log --after="2014-7-1"

Można też użyć odniesień względnych, takich jak "1 week ago" (1 tydzień temu) czy "yesterday" (wczoraj):

git log --after="yesterday"

Aby wyszukać commity utworzone między dwiema datami, możesz podać zarówno datę przed, jak i po (odpowiednio --before i --after). Przykładowo, aby wyświetlić wszystkie commity dodane między 1 lipca a 4 lipca 2014 r., należy użyć polecenia:

git log --after="2014-7-1" --before="2014-7-4"

W przypadku commitów wprowadzających dużą liczbę zmian wynik może być dość długi i zagmatwany. Zazwyczaj, gdy wyświetlasz pełną poprawkę, szukasz jednej konkretnej zmiany. W tym celu możesz użyć opcji „kilof” (pickaxe).

Według autora

Jeśli szukasz wyłącznie commitów utworzonych przez konkretnego użytkownika, użyj flagi --author. Można tu użyć wyrażenia regularnego, co spowoduje wyświetlenie wszystkich commitów, których autor pasuje do danego wzorca. Jeśli wiesz dokładnie, kogo szukasz, możesz użyć zwykłego ciągu znaków zamiast wyrażenia regularnego:

git log --author="John"

Wyświetlone zostaną wszystkie commity, których nazwa autora zawiera ciąg John. Nazwa autora nie musi być dokładnie dopasowana — musi tylko zawierać określoną frazę.

Możesz także użyć wyrażeń regularnych do tworzenia bardziej złożonych wyszukiwań. Przykładowo poniższe polecenie wyszukuje commity autorstwa Mary lub Johna.

git log --author="John\|Mary"

Pamiętaj, że do nazwy autora dołączany jest również jego adres e-mail, który też może stanowić podstawę wyszukiwania.

Jeśli Twój przepływ pracy odróżnia osoby zatwierdzające od autorów, flaga --committer pozwala również je uwzględnić.

Według komunikatu

Aby filtrować commity według komunikatu commitu, użyj flagi --grep. Działanie jest podobne, jak w przypadku flagi --author omówionej powyżej. Jedyna różnica polega na tym, że przeszukiwane są komunikaty commitów zamiast autorów.

Przykładowo, jeżeli zespół umieszcza w każdym commicie powiązane numery zgłoszeń, możesz użyć następującego polecenia, aby wyszukać wszystkie commity związane z danym zgłoszeniem:

git log --grep="JRA-224:"

Można również przekazać do git log parametr -i powodujący ignorowanie wielkości znaków przy dopasowywaniu do wzorca.

Według pliku

Nieraz interesują nas wyłącznie zmiany, które zaszły w konkretnym pliku. Aby wyświetlić historię związaną z danym plikiem, wystarczy podać jego ścieżkę. Przykładowo poniższe polecenie zwraca wszystkie commity, które miały wpływ na plik foo.py lub bar.py:

git log -- foo.py bar.py

Parametr -- służy do poinformowania git log, że kolejne argumenty są ścieżkami plików, a nie nazwami gałęzi. Jeżeli w danym wypadku pomylenie z gałęzią nie jest możliwe, znaki -- można pominąć.

Według treści

Można też wyszukiwać commity, które wprowadzają określony wiersz do kodu źródłowego lub go usuwają. Nosi to nazwę pickaxe (kilof) i przyjmuje postać -S"". Jeśli na przykład chcesz sprawdzić, kiedy ciąg Hello, World! został dodany do dowolnego pliku w projekcie, użyj następującego polecenia:

git log -S"Hello, World!"

Jeśli chcesz wyszukiwać za pomocą wyrażenia regularnego zamiast ciągu znaków, możesz użyć flagi -G"".

Rozwiązanie to stanowi bardzo wydajne narzędzie do debugowania, ponieważ umożliwia zlokalizowanie wszystkich commitów, które mają wpływ na dany wiersz kodu. Możemy nawet sprawdzić, kiedy dany wiersz został skopiowany lub przeniesiony do innego pliku.

Według zakresu

Możesz przekazać zakres commitów do polecenia git log, aby wyświetlić tylko te, które się w nim zawierają. Zakres określa się za pomocą następującego formatu, gdzie i są odniesieniami do commitów.

git log ..

To polecenie jest szczególnie przydatne, gdy jako parametrów używamy odniesień do gałęzi. To prosty sposób na przedstawienie różnic między dwiema gałęziami. Rozważmy następujące polecenie:

git log main..feature

Zakres main..feature zawiera wszystkie commity, które znajdują się w gałęzi feature, ale nie w gałęzi main. Innymi słowy: przedstawia rozwój gałęzi feature od momentu oddzielenia od gałęzi main. Można to zwizualizować w następujący sposób:

Wykrywanie podziału w historii za pomocą zakresów

Należy zauważyć, że jeśli zmienimy kolejność zakresu (feature.. main), otrzymamy wszystkie commity, które są w gałęzi main, ale nie w gałęzi feature. Jeśli git log wykazuje commity dla obu wersji, oznacza to, że nastąpiło rozdzielenie historii.

Filtrowanie commitów scalenia

Domyślnie git log w danych wyjściowych uwzględnia commity scalenia. Jeśli jednak w Twoim zespole obowiązuje zasada „zawsze scalaj” (czyli scalania zmian nadrzędnych z gałęziami tematycznymi zamiast zmieniania bazy gałęzi tematycznej na gałąź nadrzędną), w historii projektu będzie widnieć wiele nieistotnych commitów scalenia.

Można zapobiec wyświetlaniu tych commitów przez git log poprzez przekazanie flagi --no-merges:

git log --no-merges

Z drugiej strony jeśli interesują Cię wyłącznie commity scalenia, można użyć flagi --merges:

git log --merges

To powoduje wyświetlenie tych commitów, które mają co najmniej dwa elementy nadrzędne.

Podsumowanie


I oto potrafisz już korzystać z zaawansowanych parametrów git log do formatowania danych wyjściowych i wskazywania, które commity chcesz wyświetlić. Dzięki temu możesz wydobyć z historii projektu dokładnie to, czego potrzebujesz.

Te nowe umiejętności stanowią ważną część zestawu narzędzi Git, ale należy pamiętać, że z git log często korzysta się w połączeniu z innymi poleceniami. Gdy już znajdziesz commit, którego szukasz, zazwyczaj przekazujesz go do git checkout, git revert lub innego narzędzia do obsługi historii commitów. Pamiętaj zatem, aby stale poszerzać wiedzę na temat zaawansowanych funkcji Git.


Udostępnij ten artykuł
Następny temat

Zalecane lektury

Dodaj te zasoby do zakładek, aby dowiedzieć się więcej na temat rodzajów zespołów DevOps lub otrzymywać aktualności na temat metodyki DevOps w Atlassian.

Ludzie współpracujący przy ścianie pełnej narzędzi

Blog Bitbucket

Ilustracja DevOps

Ścieżka szkoleniowa DevOps

Demonstracje funkcji z ekspertami Atlassian

Zobacz, jak Bitbucket Cloud współpracuje z Atlassian Open DevOps

Zapisz się do newslettera DevOps

Thank you for signing up