Defina aliases git com base em gitconfig em zsh

Defina aliases git com base em gitconfig em zsh

Eu tenho as seguintes linhas no meu ~/.aliases:

function __function_exists() {
    declare -f -F $1 > /dev/null
    return $?
}

# git aliases (need to have git bash completion installed)
for al in `__git_aliases`; do
    alias g$al="git $al"

    complete_func=_git_$(__git_aliased_command $al)
    __function_exists $complete_fnc && __git_complete g$al $complete_func
done

E no meu ~/.gitconfigeu tenho:

[alias]
    # one-line log
    l = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=short

    a = add
    ap = add -p
    c = commit --verbose
    ca = commit -a --verbose
    cm = commit -m
    cam = commit -a -m
    m = commit --amend --verbose

    d = diff
    ds = diff --stat
    dc = diff --cached

    s = status -s
    co = checkout
    cob = checkout -b
    # list branches sorted by last modified
    b = "!git for-each-ref --sort='-authordate' --format='%(authordate)%09%(objectname:short)%09%(refname)' refs/heads | sed -e 's-refs/heads/--'"

    # list aliases
    la = "!git config -l | grep alias | cut -c 7-"

E no meu ~/.zshrc:

zstyle :compinstall filename '/home/giuliani/.zshrc'
autoload -Uz compinit
compinit
[[ -f $HOME/.aliases ]] && source "$HOME/.aliases"

Portanto, para cada alias em meu gitconfig definirei um alias de shell como glfor git loge assim por diante.

Tentando portar isso para zsh, estou tendo um problema: o zsh autoloadintegrado só carrega o arquivo /usr/share/zsh/functions/Completion/Unix/_gitna primeira vez que tento concluir algum comando git.

Tentei chamar/carregar _gito arquivo diretamente do .zshrcmas outros avisos, não funcionou.

Qual é a maneira correta de ter a mesma funcionalidade que tenho no bash, usando zsh?

Responder1

Na verdade, chamar _gitde your .zshrcfunciona, pois define _gite suas funções complementares, incluindo __git_aliases, e tenta fazer alguma conclusão, mas falha (sem sequer uma mensagem de erro neste caso específico).Isso funciona com a maioria das funções de conclusão. Você precisa fazer isso depois compinitpara que _gitsuas funções auxiliares sejam marcadas para carregamento automático.

% zsh -f
darkstar% autoload compinit          
darkstar% compinit
darkstar% _git 
darkstar% __git_aliases 
_tags:comptags:36: can only be called from completion function
_tags:comptry:55: can only be called from completion function
_tags:comptags:60: can only be called from completion function
_tags:comptags:67: can only be called from completion function

O problema é que quando você executa __git_aliases, ele chama componentes internos que só podem ser usados ​​durante a conclusão. Você pode contornar isso definindo temporariamente funções com o mesmo nome desses componentes internos que fazem apenas a parte que você deseja, o que geralmente não é nada, mas é muito desajeitado. Não vou mostrar como porque existe uma maneira muito mais simples neste caso específico.

Como você está se aprofundando no _gitarquivo de conclusão, chame __git_extract_aliasesem vez de __git_aliases. __git_extract_aliasesinsere informações na variável aliasesde uma maneira que seja fácil de extrair. (Nota: escrevi esta resposta para o zsh 5.4.2, que é a versão no Ubuntu 18.04. Outras versões do zsh podem ter uma estrutura diferente em _git.)

_git 2>/dev/null
define_git_aliases () {
  local -a aliases; local al
  __git_extract_aliases
  for al in ${aliases%%:*}; do
    alias g$al="git $al"
  done
}
define_git_aliases

Isso ainda é muito mais esforço do que o necessário e um esforço de portabilidade potencialmente extra para lidar com diferentes versões do zsh. __git_extract_aliasesé basicamente uma linha de código.

for al in ${${${(0)"$(git config -z --get-regexp '^alias.')"}%%$'\n'*}#alias.}; do
  alias g$al="git $al"
done

informação relacionada