Git – garść sztuczek

Na przestrzeni ostatnich paru miesięcy złowiłem parę fajnych sztuczek, które uprzyjemniły mi codzienną pracę z Gitem. Postanowiłem więc się nimi podzielić ;)

Ustawienia Gita według katalogu

Używacie czasem innego adresu mailowego, na przykład do projektów służbowych? Ja i owszem, i czasem przy tworzeniu nowego lokalnego repo zdarzyło mi się zapomnieć klepnąć git config user.email foo@bar.com, by podmienić adres. Jednocześnie nie chciałem zmieniać go globalnie. Okazuje się, że można dołączać inny config warunkowo na podstawie ścieżki. Oto jak to zrobić:

  1. Tworzymy osobny config dla pracy, np. ~/.gitconfig-work o treści:
    [user]
    email = foo@bar.com
    
  2. W ~/.gitconfig dopisujemy:
    [includeIf "gitdir:~/work/"]
      path = .gitconfig-work
    

    Zakładając, że wszystkie repozytoria z pracy trzymamy w ~/work, email zostanie ustawiony na foo@bar.com bez konieczności pamiętania, by go zmienić.

Praca z minifikowanymi plikami

Częstym problemem przy oglądaniu diffów jest ich zaśmiecenie zmianami w minifikowanych/generowanych plikach, które znacznie psują czytelność. Oczywiście optymalnie byłoby po prostu umieścić je w .gitignore i nie trzymać w repo, ale istnieją sytuacje, w których z jakiegoś powodu muszą być one w repo (np. bo wymaga tego workflow, albo ktoś inny już je tam umieścił). Co zrobić, żeby nie wydłubać sobie oczu przy czytaniu diffów? Szukając rozwiązania natrafiłem na plik .gitattributes i jego globalny odpowiednik ~/.config/git/attributes. Wystarczy go utworzyć i uzupełnić o następujące linie:

*.min.js -diff
*.min.css -diff
*.map -diff

Spowoduje to traktowanie wskazanych globów jako pliki binarne i zamiast nieczytelnego diffa dla tych plików dostaniemy tylko komunikat typu "Binary files a/assets/styles/style.min.css and b/assets/styles/style.min.css differ", a git diff nie będzie tak zaśmiecony jak wcześniej. Oczywiście wyświetlenie diffa można nadal wymusić używając git diff --text

Idźmy dalej... A co, jeśli przy merge'owaniu gałęzi chcemy uniknąć konfliktu i po prostu zachować nasze lokalne wersje minifikowanych plików?

  1. Dodajemy nowy merge driver "ours" do naszego ~/.gitconfig:
    [merge "ours"]
        name = "Keep ours merge"
        driver = true
    
  2. Włączamy go we wspomnianym wyżej .gitattributes lub globalnym ~/.config/git/attributes dopisując merge=ours:
    *.min.js -diff merge=ours
    *.min.css -diff merge=ours
    *.map -diff merge=ours
    

    Jak to działa? Linijka driver= w sekcji merge .gitconfig definiuje jaką komendę wykonać dla rozwiązania konfliktu wersji. W tym przypadku uruchamiamy komendę true, która zwraca zerowy kod wyjścia, co Git odczytuje jako rozwiązanie konfliktu, nie ruszając lokalnych plików. Sprytnie, prawda? Oczywiście można w ten sposób również uruchamiać bardziej złożone komendy łączące zmiany z obu gałęzi albo np. użyć wbudowanego merge=union, które doklei zmiany do końca pliku (potencjalnie przydatne np. dla ChangeLogów, choć nie daje żadnych gwarancji co do kolejności).

Na koniec, jako bonus, chciałbym wymienić dwa bardzo fajne narzędzia, z których zacząłem korzystać w ostatnim czasie:

Lazygit

Pierwszym jest lazygit,  całkiem wygodny tekstowy interfejs (TUI) do obsługi Gita. Jeśli szukacie narzędzia, spod którego wykonacie większość podstawowych operacji Gita za pomocą prostych skrótów, to zdecydowanie jest wart uwagi. O ile czasem jest mi nadal szybciej zrobić coś za pomocą vim-fugitive albo komend gita, których używałem od lat i które znam na pamięć, lazygit jest mi bardzo użyteczny w przeglądaniu obecnych zmian i historii commitów. Typowe operacje są dostępne pod jednoliterowymi skrótami (? wyświetla pomoc kontekstową) i mają sensowne defaulty. Okazjonalnie przydaje mi się również możliwość commitowania wybranych linijek (enter w widoku plików, następnie stacja, by dodać/usunąć linijkę), choć częściej używam git add -p, które operuje na całych chunkach.

Git-delta

Dzięki lazygitowi poznałem też git-delta, alternatywny pager dla gita dodający multum opcji, w tym podświetlanie składni dla wielu języków, widok side-by-side, zaznaczanie zmian wewnątrz linii, przeskakiwanie między kolejnymi chunkami łatek za pomocą klawiszy n/p i wiele, wiele więcej. Ale przede wszystkim wygląda to dużo, dużo czytelniej od domyślnego diffa. Po dostosowaniu kolorów i opcji do swoich potrzeb moje diffy nigdy nie wyglądały tak dobrze ;)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *