Executando verificação de segurança...
8

[Dica] Turbinando seu git bash (Windows) adicionando aliases (como se fosse o git plugin do zsh)

Sobre

Nesse guia simples vou mostrar como turbinar o seu git bash com aliases que vão facilitar e agilizar muito na hora de fazer seus commits, pulls, pegarem logs, trocarem de branch, rebases, merges, etc..

Primeiro pra quem não conhece, o famoso plugin de git do zsh é esse: zsh git plugin

Bom o primeiro passo para adicionar esses aliases é você ter o git bash instalado.

E para adicionar os aliases é bem simples basta acessar a pasta onde estão os profiles do git bash (lembrando que esse guia é somente para Windows), que vai estar no seguinte caminho: C:\Program Files\Git\etc\profile.d

Selecionando o arquivo aliases

Depois você vai procurar o arquivo aliases.sh e abrir no seu editor de texto preferido (pode até ser o notepad) e adicionar as seguintes linhas:

alias g=git
alias ga='git add'
alias gaa='git add --all'
alias gam='git am'
alias gama='git am --abort'
alias gamc='git am --continue'
alias gams='git am --skip'
alias gamscp='git am --show-current-patch'
alias gap='git apply'
alias gapa='git add --patch'
alias gapt='git apply --3way'
alias gau='git add --update'
alias gav='git add --verbose'
alias gb='git branch'
alias gbD='git branch -D'
alias gba='git branch -a'
alias gbd='git branch -d'
alias gbda='git branch --no-color --merged | command grep -vE "^([+*]|\s*($(git_main_branch)|$(git_develop_branch))\s*$)" | command xargs git branch -d 2>/dev/null'
alias gbl='git blame -b -w'
alias gbnm='git branch --no-merged'
alias gbr='git branch --remote'
alias gbs='git bisect'
alias gbsb='git bisect bad'
alias gbsg='git bisect good'
alias gbsr='git bisect reset'
alias gbss='git bisect start'
alias gc='git commit -v'
alias 'gc!'='git commit -v --amend'
alias gca='git commit -v -a'
alias 'gca!'='git commit -v -a --amend'
alias gcam='git commit -a -m'
alias 'gcan!'='git commit -v -a --no-edit --amend'
alias 'gcans!'='git commit -v -a -s --no-edit --amend'
alias gcas='git commit -a -s'
alias gcasm='git commit -a -s -m'
alias gcb='git checkout -b'
alias gcd='git checkout $(git_develop_branch)'
alias gcf='git config --list'
alias gcl='git clone --recurse-submodules'
alias gclean='git clean -id'
alias gcm='git checkout $(git_main_branch)'
alias gcmsg='git commit -m'
alias 'gcn!'='git commit -v --no-edit --amend'
alias gco='git checkout'
alias gcor='git checkout --recurse-submodules'
alias gcount='git shortlog -sn'
alias gcp='git cherry-pick'
alias gcpa='git cherry-pick --abort'
alias gcpc='git cherry-pick --continue'
alias gcs='git commit -S'
alias gcsm='git commit -s -m'
alias gcss='git commit -S -s'
alias gcssm='git commit -S -s -m'
alias gd='git diff'
alias gdca='git diff --cached'
alias gdct='git describe --tags $(git rev-list --tags --max-count=1)'
alias gdcw='git diff --cached --word-diff'
alias gds='git diff --staged'
alias gdt='git diff-tree --no-commit-id --name-only -r'
alias gdup='git diff @{upstream}'
alias gdw='git diff --word-diff'
alias gf='git fetch'
alias gfa='git fetch --all --prune --jobs=10'
alias gfg='git ls-files | grep'
alias gfo='git fetch origin'
alias gg='git gui citool'
alias gga='git gui citool --amend'
alias ggpull='git pull origin "$(git_current_branch)"'
alias ggpur=ggu
alias ggpush='git push origin "$(git_current_branch)"'
alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)'
alias ghh='git help'
alias gignore='git update-index --assume-unchanged'
alias gignored='git ls-files -v | grep "^[[:lower:]]"'
alias git-svn-dcommit-push='git svn dcommit && git push github $(git_main_branch):svntrunk'
alias gk='\gitk --all --branches &!'
alias gke='\gitk --all $(git log -g --pretty=%h) &!'
alias gl='git pull'
alias glg='git log --stat'
alias glgg='git log --graph'
alias glgga='git log --graph --decorate --all'
alias glgm='git log --graph --max-count=10'
alias glgp='git log --stat -p'
alias glo='git log --oneline --decorate'
alias globurl='noglob urlglobber '
alias glod='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset'\'
alias glods='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset'\'' --date=short'
alias glog='git log --oneline --decorate --graph'
alias gloga='git log --oneline --decorate --graph --all'
alias glol='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'\'
alias glola='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'\'' --all'
alias glols='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'\'' --stat'
alias glp=_git_log_prettily
alias gluc='git pull upstream $(git_current_branch)'
alias glum='git pull upstream $(git_main_branch)'
alias gm='git merge'
alias gma='git merge --abort'
alias gmom='git merge origin/$(git_main_branch)'
alias gmtl='git mergetool --no-prompt'
alias gmtlvim='git mergetool --no-prompt --tool=vimdiff'
alias gmum='git merge upstream/$(git_main_branch)'
alias gp='git push'
alias gpd='git push --dry-run'
alias gpf='git push --force-with-lease'
alias 'gpf!'='git push --force'
alias gpoat='git push origin --all && git push origin --tags'
alias gpr='git pull --rebase'
alias gpristine='git reset --hard && git clean -dffx'
alias gpsup='git push --set-upstream origin $(git_current_branch)'
alias gpu='git push upstream'
alias gpv='git push -v'
alias gr='git remote'
alias gra='git remote add'
alias grb='git rebase'
alias grba='git rebase --abort'
alias grbc='git rebase --continue'
alias grbd='git rebase $(git_develop_branch)'
alias grbi='git rebase -i'
alias grbm='git rebase $(git_main_branch)'
alias grbo='git rebase --onto'
alias grbom='git rebase origin/$(git_main_branch)'
alias grbs='git rebase --skip'
alias grep='grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn,.idea,.tox}'
alias grev='git revert'
alias grh='git reset'
alias grhh='git reset --hard'
alias grm='git rm'
alias grmc='git rm --cached'
alias grmv='git remote rename'
alias groh='git reset origin/$(git_current_branch) --hard'
alias grrm='git remote remove'
alias grs='git restore'
alias grset='git remote set-url'
alias grss='git restore --source'
alias grst='git restore --staged'
alias grt='cd "$(git rev-parse --show-toplevel || echo .)"'
alias gru='git reset --'
alias grup='git remote update'
alias grv='git remote -v'
alias gsb='git status -sb'
alias gsd='git svn dcommit'
alias gsh='git show'
alias gsi='git submodule init'
alias gsps='git show --pretty=short --show-signature'
alias gsr='git svn rebase'
alias gss='git status -s'
alias gst='git status'
alias gsta='git stash push'
alias gstaa='git stash apply'
alias gstall='git stash --all'
alias gstc='git stash clear'
alias gstd='git stash drop'
alias gstl='git stash list'
alias gstp='git stash pop'
alias gsts='git stash show --text'
alias gstu='gsta --include-untracked'
alias gsu='git submodule update'
alias gsw='git switch'
alias gswc='git switch -c'
alias gswd='git switch $(git_develop_branch)'
alias gswm='git switch $(git_main_branch)'
alias gtl='gtl(){ git tag --sort=-v:refname -n -l "${1}*" }; noglob gtl'
alias gts='git tag -s'
alias gtv='git tag | sort -V'
alias gunignore='git update-index --no-assume-unchanged'
alias gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1'
alias gup='git pull --rebase'
alias gupa='git pull --rebase --autostash'
alias gupav='git pull --rebase --autostash -v'
alias gupom='git pull --rebase origin $(git_main_branch)'
alias gupomi='git pull --rebase=interactive origin $(git_main_branch)'
alias gupv='git pull --rebase -v'
alias gwch='git whatchanged -p --abbrev-commit --pretty=medium'
alias gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]"'

Pronto! Agora você pode ser mais feliz utilizando o git de forma mais ágil e escrevendo bem menos com esses aliases! :D

Publicado originalmente em https://thayto.com/blog/turbinando-seu-git-bash-windows-adicionando-aliases-como-se-fosse-o-git-plugin-do-zsh

Carregando publicação patrocinada...
4

Complementando:

Note que o primeiro alias que vc criou foi alias g=git. Então ele poderia ser usado nos demais:

alias g=git

# os próximos podem usar o primeiro alias
alias ga='g add'
alias gaa='g add --all'
# etc...

Neste caso meio que dá na mesma (exceto talvez pela "economia de caracteres", que nem acho um fator tão importante assim). Isso faz diferença em casos em que vc sempre chama o comando com algum parâmetro (por exemplo, alias c='comando --op1 --op2 e depois alias c1='c acao', pois aí garanto que o comando sempre será chamado com as opções desejadas). Como não é o caso aqui, não faz tanta diferença, foi só pra citar que é uma possibilidade.

Só que tem outro ponto que acho mais relevante. Vc está criando aliases do Bash, mas existe outra alternativa, que é criar aliases dentro do próprio Git. E tem uma diferença importante, que citarei em detalhes no final.


Git aliases

Em vez de criar aliases no shell, vc pode criar dentro do próprio Git. Os detalhes estão na documentação, mas abaixo segue um pequeno resumo.

No seu caso, em vez de alias ga='git add', você poderia fazer algo como:

git config alias.a add

Isso adicionará o alias no arquivo .git/config do seu repositório local:

[alias]
    a = add

Assim, sempre que eu chamar git a, ele entenderá que na verdade estou chamando git add. Da mesma forma, basta fazer git config alias.aa "add --all", assim git aa equivale a git add --all.

E se quiser, pode usar git config --global para alterar a configuração global, assim os aliases ficarão disponíveis em todos os repositórios locais que estiverem na sua máquina.

E claro, vc também pode editar o arquivo de configuração diretamente (.git/config para um repositório específico, ou ~/.gitconfig para a configuração global).

Diferença importante

Como já disse, há uma diferença importante, e que faz com que eu prefira esta opção: o auto complete. Usando aliases do Bash, vc não terá o auto complete do Git disponível.

Por exemplo, usando meu alias que criei acima (git a para git add): se eu digitar git a -- e TAB duas vezes, serão mostradas as opções do git add:

$ git a --
--all                  --edit                 --ignore-missing       --interactive          --patch                --refresh              --update               
--chmod=               --force                --ignore-removal       --no-...               --pathspec-file-nul    --renormalize          --verbose              
--dry-run              --ignore-errors        --intent-to-add        --no-dry-run           --pathspec-from-file=  --sparse

Agora se eu usar o seu alias: ga -- e TAB duas vezes, nada acontece. Isso porque o auto complete do Bash está tentando verificar se existe alguma opção para o comando ga, e no caso não tem, por isso ele não mostra nada. Quando eu uso git a, o auto complete do Git procura pelas opções do git add (pois ele entende que o comando a é um alias e sabe onde procurar).

Além disso, o auto complete do Git é bem esperto e age de acordo com o contexto. Por exemplo, se digitar git add, espaço e TAB duas vezes, ele mostra somente os arquivos que ainda não foram adicionados. Enquanto que se fosse usar o auto complete do Bash (ga, espaço e TAB duas vezes), ele mostra todos os arquivos. Além disso, o Git mostra as opções e seus valores (por exemplo, git log --format= e TAB duas vezes mostra somente os valores que a opção --format aceita, o que não acontece com o alias do Bash, etc).

Até existem formas de contornar isso (ver aqui e aqui), mas eu prefiro usar os aliases do próprio Git para não precisar desta configuração adicional (além de não poluir os aliases do próprio Bash).

Mas claro que a escolha vai de cada um, o importante é saber que existem alternativas, e aí cada um escolhe o que achar melhor. Eu prefiro os Git aliases porque uso bastante a linha de comando, e o auto complete agiliza bastante as coisas.


Obs: quando digo "auto complete do Git", na verdade é um script que usa o comando complete, e que roda dentro do próprio Bash (e que pode ou não vir junto com a instalação do Git - no caso do Git Bash, se não me engano, já vem). Este script contém todas as regras para que o auto complete seja esperto e sensível ao contexto, mas no fundo ele também está rodando dentro do mesmo shell. Eu só usei o termo "auto complete do Git" para diferenciar o caso em que estou usando um alias do Git e não do Bash. Espero não ter ficado confuso.

3