Świąteczne porządki z gitem
Zabawy z aliasami i gitem ciąg dalszy. Celem dzisiejszego ćwiczenia jest stworzenie kilku przydanych aliasów, które pozwalają posprzątać lokalne repozytorium z nieprzydatnych rzeczy.
Co to są aliasy?
Podobnie jak w bashu, aliasy w gicie służą do „skracania” długich poleceń. Najsłynniejszym zbiorem aliasów dla gita jest to repozytorium. Więcej wiedzieć nam nie trzeba.
Co i dlaczego chcemy sprzątać?
W skrócie chcemy usunąć wszystkie „martwe” gałęzie z lokalnego repozytorium. Przez pojęcie „martwej” rozumiem gałąź której nie ma w żadnym repozytorium zdalnym (remote). Chcę też stworzyć alias, który „posprząta” przy powrocie na główną gałąź. Motywacja do takiego sprzątania jest dość prosta. Chcę ograniczyć wielkość lokalnego repozytorium. W dodatku mój sposób pracy z gitem opiera się o pracę na jednej gałęzi, mergu i usunięciu jej ze zdalnego repo. Jeżeli z jakiegoś powodu potrzebuję wrócić do tej gałęzi, to tworzę ją od nowa. Dzięki temu unikam problemów związanych z synchronizacją pomiędzy gałęziami. Gałąź, na której pracuję, nie ma żadnych commitów, które dogrywają do niej jakąś zewnętrzna zawartość z innych gałęzi. Dopiero na koniec robię rebase z gałęzią, od której się odbiłem i rozwiązuję potencjalne konflikty.
Dodatkowo chcę trochę zmniejszyć ilość naciśnięć przycisków i mieć jakieś śmieszne polecenia.
git exterminatus
To już pierwszy cel mamy wypełniony. Nasz alias będzie nazywał się exterminatus
. Chcemy teraz znaleźć wszystkie martwe gałęzie. Posłużą nam do tego
polecenia git pull --prune
i git branch --vv
. Zanim jednak użyjemy tych poleceń, to krótkie przygotowanie. W jakimś repozytorium odbij gałąź
z master
. Następnie zrób jakieś zmiany, wyślij do repo zdalnego i tam zmerguj. Następnie w zdalnym repo usuń zmergowaną gałąź. Następnie wróć na
gałąź master
i zrób prosty git pull
:
Listing 1. Stan wyjściowy
koziolek@koziolek-desktop3 ~/workspace/git-configuration-aliases (aliases) $ git co master
Przełączono na gałąź „master”
Twoja gałąź jest na bieżąco z „origin/master”.
koziolek@koziolek-desktop3 ~/workspace/git-configuration-aliases (master) $ git pull
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Rozpakowywanie obiektów: 100% (1/1), 886 bajtów | 886.00 KiB/s, gotowe.
Z github.com:Koziolek/git-configuration
09f005a..5f1e29b master -> origin/master
Aktualizowanie 09f005a..5f1e29b
Fast-forward
bash/bash_rc | 6 ++++++
git/aliases | 1 +
git/git_config | 4 ++++
3 files changed, 11 insertions(+)
Teraz wykonaj po kolei git branch --vv
, git pull --prune
i jeszcze raz git branch --vv
Listing 2. Stan po zmianach
koziolek@koziolek-desktop3 ~/workspace/git-configuration-aliases (master) $ git branch -vv
aliases 7e69d99 [origin/aliases] add new aliases
+ feature/-split 208f795 (/home/koziolek/workspace/git-configuration) [origin/feature/-split] local store
* master 5f1e29b [origin/master] Merge pull request #6 from Koziolek/aliases
koziolek@koziolek-desktop3 ~/workspace/git-configuration-aliases (master) $ git pull --prune
Z github.com:Koziolek/git-configuration
- [usunięto] (brak) -> origin/aliases
Już aktualne.
koziolek@koziolek-desktop3 ~/workspace/git-configuration-aliases (master) $ git branch -vv
aliases 7e69d99 [origin/aliases: nie ma] add new aliases
+ feature/-split 208f795 (/home/koziolek/workspace/git-configuration) [origin/feature/-split] local store
* master 5f1e29b [origin/master] Merge pull request #6 from Koziolek/aliases
Jak widać ja pracuję z gałęzią aliases
. Gałąź ta po operacjach na zdalnym repozytorium nadal istnieje lokalnie. Wykonanie git pull --prune
usunęło
tylko informacje o zdalnej gałęzi. Widać to po drugim wykonaniu git branch -vv
, gdy przy nazwie zdalnej gałęzi pojawia się komunikat nie ma
.
Wykorzystamy to teraz do napisania naszego aliasu. Będzie to alias - funkcja, dzięki czemu będzie można wykonać kilka poleceń w sensowny sposób.
Zdefiniuję ją od razu w pliku konfiguracyjnym gita:
Listing 3. Alias exterminatus
alias.exterminatus=! f() { git branch -vv | grep ': nie ma]' | awk '{print $1}' | xargs git branch -D;}; f
I teraz ciekawostka, to zadziała jedynie, gdy mamy ustawiony język polski w terminalu. Git używa translacji do wyświetlania komunikatów, więc musimy wymusić „jedyny słuszny” język:
Listing 4. Dodajemy konfigurację języka
alias.exterminatus=! f() { LANG=en_GB git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D;}; f
Uruchommy zatem naszą nową zabawkę i zobaczmy co się stanie
Listing 5. Czas na exterminatus
koziolek@koziolek-desktop3 ~/workspace/git-configuration/bash (master) $ git branch -vv
aliases 7e69d99 [origin/aliases: nie ma] add new aliases
feature/-split 208f795 [origin/feature/-split] local store
* master 5f1e29b [origin/master] Merge pull request #6 from Koziolek/aliases
koziolek@koziolek-desktop3 ~/workspace/git-configuration/bash (master) $ git exterminatus
Usunięto gałąź aliases (wskazywała 7e69d99).
koziolek@koziolek-desktop3 ~/workspace/git-configuration/bash (master) $ git branch -vv
feature/-split 208f795 [origin/feature/-split] local store
* master 5f1e29b [origin/master] Merge pull request #6 from Koziolek/aliases
Działa i armaci. Podobny efekt możemy uzyskamy uruchamiając git remote prune
dla każdego zdalnego repozytorium, czyli w pętli. Jednak polecenie to
działa potwornie wolno (wykonuje zapytanie po sieci). W naszym przypadku pracujemy lokalnie i zakładamy niejawnie, że repozytorium już jest aktualne.
git home
Kolejny alias, który chcę wam pokazać, to powrót do „domu”. Gałęzi głównej. To proste polecenie wykorzysta rev-parse
i trochę awk
:
Listing 6. Go home git you are trunk
home = "! BRANCH_NAME=$(git rev-parse --abbrev-ref origin/HEAD | awk '{ split($0, arr, \"/\"); print arr[length(arr)]; }'); git checkout $BRANCH_NAME;"
I na koniec możemy połączyć te dwa aliasy w jeden:
Listing 7. Sprzątamy w domu
clean-home = "! git home && git exterminatus"
Wesołego kernela!