Skip to content

Konfiguracja .gitconfig

Git ma opinię narzędzia prostego: pobierz zmiany, utwórz commit, wypchnij branch. Przy większej liczbie repozytoriów szybko okazuje się jednak, że kilka ustawień globalnych potrafi wyeliminować powtarzalne polecenia i ujednolicić codzienną pracę.

Mój plik ~/.gitconfig nie jest rozbudowany. Koncentruje się na czytelnej historii, przewidywalnym zachowaniu nowych branchy, współdzielonych hookach oraz kilku aliasach do operacji wykonywanych regularnie. W tym artykule przejdę przez jego najważniejsze sekcje i wyjaśnię, dlaczego są przydatne.


Pierwsza sekcja określa dane autora zapisywane w commitach:

[user]
    name = Maciej Rachuna
    email = <adres-email>

Git umieszcza te wartości w metadanych każdego nowego commita. Nie jest to mechanizm uwierzytelniania do GitLaba ani GitHuba. Adres e-mail pozwala platformie powiązać commit z kontem użytkownika, ale dostęp do zdalnego repozytorium nadal wymaga osobnej autoryzacji.

Adresu używanego lokalnie nie publikuję w przykładzie. W publicznym repozytorium można zastąpić go adresem noreply, jeżeli platforma hostingowa udostępnia taki wariant.


Domyślne git log zawiera dużo informacji, ale przy szybkim przeglądaniu historii przydaje się krótszy format:

[pretty]
    slim = "%C(red)%h%C(yellow)%d%C(reset) %s %C(green)(%cd) %C(bold blue)<%an>%C(reset)"

[alias]
    lg = log --graph --abbrev-commit --decorate --date=relative --pretty=slim
    lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(white)%s%C(reset) %C(dim white)(%cr) %C(green)<%an>%C(reset)'

Format slim składa się z:

ElementZnaczenie
%hSkrócony hash commita.
%dReferencje wskazujące commit, na przykład branch lub tag.
%sTemat commita.
%cdData commita.
%anAutor commita.

Alias lg używa tego formatu razem z grafem branchy i względną datą, na przykład 2 hours ago. lg1 jest alternatywną wersją z formatem zapisanym bezpośrednio w aliasie.

git lg
git lg1

Oba polecenia sprawdzają się lepiej niż surowe git log, gdy chcę szybko sprawdzić historię zmian i miejsca rozgałęzień.


Kolejne ustawienia określają domyślne zachowanie podstawowych operacji:

[commit]
    gpgSign = false

[push]
    autoSetupRemote = true

[pull]
    rebase = false

[init]
    defaultBranch = main

commit.gpgSign = false wyłącza automatyczne podpisywanie commitów kluczem GPG. Commit nadal zawiera autora, ale nie otrzymuje kryptograficznego podpisu.

push.autoSetupRemote = true upraszcza pierwsze wypchnięcie nowego brancha. Zamiast:

git push --set-upstream origin feature/example

wystarczy:

git push

Git sam ustawi upstream dla bieżącego brancha.

pull.rebase = false oznacza, że git pull nie przepisuje lokalnej historii przez rebase. Jeżeli lokalny i zdalny branch się rozeszły, Git zachowuje model oparty na merge.

init.defaultBranch = main ustawia nazwę pierwszego brancha w nowych repozytoriach tworzonych przez git init.


Najbardziej automatyzujący alias w konfiguracji to:

[alias]
    amend = !git add . && git commit --amend --no-edit --date='now' && git push --force-with-lease

Polecenie:

git amend

wykonuje kolejno trzy operacje:

  1. Dodaje wszystkie zmiany z bieżącego katalogu do staging area.
  2. Nadpisuje ostatni commit bez zmiany jego opisu i aktualizuje datę.
  3. Wysyła poprawiony commit do zdalnego repozytorium.

Warto też pamiętać, że git add . bierze pod uwagę pliki od bieżącego katalogu w dół. Najbardziej przewidywalny efekt daje uruchomienie aliasu z głównego katalogu repozytorium.


Repozytoria umieszczam pod /repo, dlatego globalna konfiguracja odwołuje się do współdzielonych plików z tego katalogu:

[core]
    excludesfile = /repo/.gitignore_global
    hooksPath = /repo/git-hooks

core.excludesfile wskazuje globalny plik ignorowanych ścieżek. To dobre miejsce na pliki związane z lokalnym środowiskiem pracy, które nie powinny trafiać do .gitignore każdego projektu osobno.

Przykładowe wpisy:

.envrc
.env
.devcontainer
.vscode

core.hooksPath przenosi źródło hooków Git z domyślnego .git/hooks do wspólnego katalogu /repo/git-hooks. Jeden zestaw skryptów może dzięki temu działać we wszystkich lokalnych repozytoriach.


Git chroni przed wykonywaniem operacji w repozytoriach należących do innego użytkownika systemowego. W środowiskach kontenerowych właściciel plików widoczny wewnątrz kontenera może różnić się od właściciela procesu, dlatego pojawia się ustawienie:

[safe]
    directory = /repo/*

Pozwala ono pracować z repozytoriami znajdującymi się bezpośrednio pod /repo. Jest to wygodne w Dev Containers, gdzie ten sam workspace jest montowany z hosta do kontenera.


Git domyślnie uruchamia pager, gdy wynik polecenia nie mieści się w terminalu. W mojej konfiguracji pager jest wyłączony dla najczęściej używanych komend:

[pager]
    branch = false
    diff = false
    log = false
    show = false

Dzięki temu git branch, git diff, git log i git show wypisują wynik bezpośrednio do terminala. Jest to wygodne zwłaszcza przy pracy w zintegrowanym terminalu VS Code oraz przy filtrowaniu wyników innymi narzędziami.

Konfiguracja zawiera również aliasy przeznaczone do uruchomienia zewnętrznego narzędzia difft:

[alias]
    dlog = !git -c diff.external=difft log --ext-diff
    dshow = !git -c diff.external=difft show --ext-diff
git dlog
git dshow HEAD