Dnes se podíváme na to, jak si zjednodušit a urychlit práci s git
em. Konkrétně ukáži některé své aliasy, které v git
u používám.
Aktualizace 19.7.2015: Novější verzi tohoto příspěvku lze nalézt na mém anglickém blogu.
Úvod
U většina aplikací si lze nastavit klávesové zkratky, které, pokud si na ně zvyknete, vám mohou drasticky ušetřit čas. Systém správy verzí git není žádnou výjimkou. Oproti klasickým aplikacím u něj ale nenastavujete klávesové zkratky jako takové, nýbrž tzv. aliasy. Funguje to tak, že si pro určité příkazy nadefinujete jejich zkrácenou formu. Např. místo toho, abyste zrušili poslední commit pomocí
git reset --soft HEAD^
tak si lze nadefinovat alias, že vám bude stačit napsat
git undo
No a právě o takovýchto aliasech bude následující příspěvek.
Alias na samotný git
Co v první řadě doporučuji, tak je si v shellu nastavit alias na samotný příkaz git
. Např. v bashi to lze udělat takto:
alias g='git'
Ušetříte tak dva znaky při psaní příkazů pro git
, protože místo git push
napíšete jen g push
. Sice se to nezdá, ale pokud napíšete denně slovo git
1000x, tak si ušetříte psaní 2000 znaků.
Co dále doporučuji, tak je si zapnout automatické doplňování. V bash
i se to udělá např. přidáním následujících řádků do ~/.bashrc
:
# If available, source the Git completion file. if [ -f ~/.git-completion.bash ]; then . ~/.git-completion.bash fi
Je samozřejmě potřeba mít tento soubor stažený. Alternativně si můžete do systému nainstalovat balíček, který to vyřeší za vás (pokud takový ve vaší distribuci existuje). Pokud jste si udělali onen alias na git
zmíněný výše, tak je ještě třeba následující kus kódu, který vám umožní používat doplňování i s použitím g
místo git
:
# Autocomplete for 'g' (git) as well. complete -o default -o nospace -F _git g
Funguje to pak tak, že když dáte např. g checkout <TAB>
, tak se vám zobrazí seznam větví, které si můžete checkoutnout.
Aliasy v git
u
Aliasy pro samotný git
si lze nastavit v souboru .gitconfig
(návod). Níže projdu některé aliasy, které používám. Určitě si zapněte barvičky, abyste měli přehlednější výstup.
a = add aa = add -u ai = add -i ap = add -p
Přidávání souborů do indexu (staging area). Příkaz git aa
přidá do indexu vše, co je změněno a trackováno. Mrkněte do manuálu pro vysvětlení dalších použitých parametrů (obzvlášť parametr -p
je užitečný, protože vám umožní do indexu přidat jen části změn v souborech).
amend = commit --verbose --amend amendr = commit --verbose --amend --reset-author
Příkazy pro úpravu posledního commitu. Používejte pouze, pokud jste commit nezveřejnili, protože se při něm používá rebase
měnící historii. První příkaz vezme změny v indexu a promítne je do posledního commitu. Hodí se, pokud jste si po commitu uvědomíte, že jste na něco zapomněli. Druhý příkaz udělá totéž, ale navíc aktualizuje čas vytvoření commitu.
authors = "!git log --pretty=format:%aN | sort | uniq -c | sort -rn"
Vypíše seznam autorů v repozitáři, seřazený sestupně podle počtu commitů.
bl = blame
Pouze zkratka pro zobrazení informace, kdo a kdy udělal poslední změny na daných místech v souboru.
br = branch -vv bra = branch -a -vv
Parametr -vv
vede k detailnějším informacím (zobrazí např. poslední commit na dané větvi a to, kterou větev na serveru vaše větev trackuje). Druhý příkaz vám zobrazí všechny větve (i ty, které nemáte checkoutnuté).
c = commit --verbose ca = commit --verbose --all
Parametr --verbose
vám v editoru, kde píšete commit zprávu, zobrazí seznam změn, které do daného commitu patří. To se hodí pro poslední kontrolu, zda jste na něco nezapomněli či zda necommitujete něco, co nemáte.
clear = reset --hard
Zruší všechny necommitnuté změny od posledního commitu. Hodí se, pokud jste od posledního commitu udělali úpravy, které chcete zahodit. Pro další možná doplnění tohoto příkazu mrkněte zde.
co = checkout cp = cherry-pick
Pouze zkratky pro tyto dva příkazy.
d = diff da = diff HEAD ds = diff --staged
První příkaz je pouze zkratka, která vám zobrazí seznam změn v souborech, které trackuje git, ale které nemáte v indexu. Druhý příkaz vám zobrazí diff všech změn, tedy i těch, které máte v indexu ("a" jako "all"). Poslední příkaz vám zobrazí diff pouze z toho, co máte v indexu.
ignored = ls-files --exclude-standard --ignored --others
Zobrazí seznam ignorovaných souborů.
l = log -20 --no-merges --pretty='format:%C(yellow)%h %C(green)%ai %C(bold blue)%an %C(red)%d%C(reset) %s' lf = log --no-merges --numstat --pretty='format:%C(yellow)%h %C(green)%ai %C(bold blue)%an %C(red)%d%C(reset) %s' lg = log --graph --pretty='format:%C(yellow)%h %C(green)%ai %C(bold blue)%an %C(red)%d%C(reset) %s' lga = log --graph --branches --remotes --tags --pretty='format:%C(yellow)%h %C(green)%ai %C(bold blue)%an %C(red)%d%C(reset) %s' ll = log --no-merges --pretty='format:%C(yellow)%h %C(green)%ai %C(bold blue)%an %C(red)%d%C(reset) %s'
Přehledné zobrazení logů. První příkaz zobrazí posledních 20 změn s ignorováním merge commitů. Druhý příkaz zobrazí log a u každého commitu zobrazí změněné soubory ("f
" jako "files"). Třetí příkaz zobrazí log strukturovaný do grafu ("g" jako "graph"). Čtvrtý příkaz (git lga
) zobrazí taktéž log ve formě grafu, ale zahrne do něj informace ze všech větví ("a
" jako "all"). Poslední příkaz je podobný prvnímu, ale zobrazí změny v pageru (můžete se pak posouvat v historii, což je nutné, pokud máte v repozitáři více commitů, než se vám vleze na obrazovku :)). Doporučuji si všechny tyto příkazy vyzkoušet, abyste viděli, co to všechno zobrazuje.
m = merge --no-ff
Provede merge s tím, že nepovolí tzv. fast forward merge. Vytvoří se tedy vždy merge commit, i když by nemusel. Osobně používám hodně topic branches s popisným jménem a když už je merguji, tak chci, aby v historii zůstalo, že tyto commity patří k sobě.
p = push pb = "!git push --set-upstream origin `git rev-parse --abbrev-ref HEAD`"
První příkaz je pouze zkratka. Ten druhý pushne aktuální větev na server s tím, že ji nastaví jako tracking branch ("b" jako "branch").
rb = rebase rba = rebase --abort rbc = rebase --continue rbi = rebase --interactive rbs = rebase --skip
Různé parametry pro rebase. Především se doporučuji seznámit s interaktivním rebase, což je parádní věc.
s = status --short --branch
Parametr --short
způsobí, že bude výstup kompaktnější a (z mého pohledu) mnohem přehlednější, než standardní výstup příkazu git status
. Parametr --branch
navíc do výstupu zahrne název větve, na které se aktuálně nacházíte.
sh = stash sha = stash apply shd = stash drop shl = stash list shp = stash pop shs = stash show -p
Zkratky pro stash. Poslední příkaz zobrazí, co se nachází v nejvrchnějším stashi (diff).
tags = tag -l -n1
Zobrazí seznam tagů v repozitáři.
this = "!git init && git add . && git commit -m 'Initial commit.'"
Udělá z aktuálního adresáře git repozitář, přidá do něj neignorované soubory a vše commitne jako první commit. Použití: git this
aneb "gitni mi tenhle adresář" :).
undo = reset --soft HEAD^
Zruší poslední commit s tím, že změny ponechá v indexu. Pro git reset --hard HEAD^
si raději žádný alias nedávám :). Ale tak když už git
má reflog, tak o tom možná pouvažuji.
wip = "!git add --all && git commit -m 'WIP'" unwip = "!if [ `git show --oneline --pretty='%s' | head -n1` == 'WIP' ]; then git undo && git reset; fi"
Určitě jste už zažili situaci, kdy máte rozdělanou práci na některé větvi a ozve se vám kolega, že by něco potřeboval upravit na jiné větvi. Příkaz git wip
vám vezme změněné soubory a commitne je jako commit s předmětem "WIP"
. Pak se můžete vesele přesunout na jinou větev, provést požadované změny, vrátit se na původní větev a dát git unwip
, což vás vrátí do stavu, v jakém jste na větvi skončili s tím. Poznámka: příkaz nezachovává stav indexu.
Závěr
Kompletní .gitconfig
je ke stažení u mě na GitHubu. Samozřejmě, aliasy byste si měli nastavit sami podle toho, které příkazy používáte. Pokud zjistíte, že často píšete nějaký delší příkaz, tak si na něj udělejte alias. Ušetří vám to čas.
Na závěr bych chtěl ještě zmínit, že v shellu je možné si udělat aliasy přímo na ony příkazy v gitu, tedy bez toho, abyste museli psát mezeru za g
:
alias ga='git add' alias gs='git status' ...
Pokud však používáte automatické doplňování, tak je potřeba jej korektně nastavit i pro tyto aliasy.
A co vy, jaký je váš oblíbený alias v git
u?