Definieren Sie Git-Aliase basierend auf Gitconfig in zsh

Definieren Sie Git-Aliase basierend auf Gitconfig in zsh

Ich habe die folgenden Zeilen in meinem ~/.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

Und in meinem ~/.gitconfighabe ich:

[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-"

Und in meinem ~/.zshrc:

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

Also definiere ich für jeden Alias ​​in meiner Gitconfig einen Shell-Alias ​​wie gl„for“ git logund so weiter.

Beim Versuch, dies auf zsh zu portieren, habe ich ein Problem: Das autoloadintegrierte zsh lädt die Datei nur /usr/share/zsh/functions/Completion/Unix/_gitbeim ersten Versuch, einen Git-Befehl auszuführen.

Ich habe versucht, _gitdie Datei direkt von dort aufzurufen/zu laden .zshrc, aber trotz einiger Warnungen hat es nicht funktioniert.

Was ist der richtige Weg, um mit zsh die gleiche Funktionalität zu erreichen, die ich in Bash habe?

Antwort1

Tatsächlich funktioniert der Aufruf _gitvon Ihrer aus .zshrc, indem er _gitund die zugehörigen Funktionen einschließlich definiert und __git_aliasesversucht, eine Vervollständigung durchzuführen, was jedoch fehlschlägt (in diesem speziellen Fall sogar ohne eine Fehlermeldung).Dies funktioniert mit den meisten Vervollständigungsfunktionen. Dies müssen Sie anschließend tun, compinitdamit _gitund seine Zusatzfunktionen zum automatischen Laden markiert werden.

% 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

Das Problem besteht darin, dass beim Ausführen von __git_aliasesBuilt-ins aufgerufen werden, die nur während der Vervollständigung verwendet werden können. Sie können das umgehen, indem Sie vorübergehend Funktionen mit demselben Namen wie diese Built-ins definieren, die nur den Teil ausführen, den Sie ausführen möchten, was oft nichts ist, aber das ist sehr umständlich. Ich werde nicht zeigen, wie das geht, da es in diesem speziellen Fall einen viel einfacheren Weg gibt.

_gitDa Sie ohnehin tief in die Vervollständigungsdatei eintauchen , rufen Sie __git_extract_aliasesstatt auf __git_aliases. __git_extract_aliasesInformationen werden so in die Variable gepackt aliases, dass sie leicht zu extrahieren sind. (Hinweis: Ich habe diese Antwort für zsh 5.4.2 geschrieben, die Version von Ubuntu 18.04. Andere Versionen von zsh haben möglicherweise eine andere Struktur in _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

Dies bedeutet immer noch viel mehr Aufwand als nötig und möglicherweise zusätzlichen Portierungsaufwand, um mit verschiedenen Versionen von zsh zurechtzukommen. __git_extract_aliasesist im Grunde eine Codezeile.

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

verwandte Informationen