On Mon, Jun 11, 2018 at 8:20 PM, Jonathan Nieder <jrnieder@xxxxxxxxx> wrote: > From: SZEDER Gábor <szeder.dev@xxxxxxxxx> > Subject: completion: correct zsh detection when run from git-completion.zsh > > v2.18.0-rc0~90^2 (completion: reduce overhead of clearing cached > --options, 2018-04-18) worked around a bug in bash's "set" builtin on > MacOS by using compgen instead. It was careful to avoid breaking zsh > by guarding this workaround with > > if [[ -n ${ZSH_VERSION-}} ]] > > Alas, this interacts poorly with git-completion.zsh's bash emulation: > > ZSH_VERSION='' . "$script" > > Correct it by instead using a new GIT_SOURCING_ZSH_COMPLETION shell > variable to detect whether git-completion.bash is being sourced from > git-completion.zsh. This way, the zsh variant is used both when run > from zsh directly and when run via git-completion.zsh. > > Reproduction recipe: > > 1. cd git/contrib/completion && cp git-completion.zsh _git > 2. Put the following in a new ~/.zshrc file: > > autoload -U compinit; compinit > autoload -U bashcompinit; bashcompinit > fpath=(~/src/git/contrib/completion $fpath) > > 3. Open zsh and "git <TAB>". > > With this patch: > Triggers nice git-completion.bash based tab completion > > Without: > contrib/completion/git-completion.bash:354: read-only variable: QISUFFIX > zsh:12: command not found: ___main > zsh:15: _default: function definition file not found > _dispatch:70: bad math expression: operand expected at `/usr/bin/g...' > Segmentation fault Btw, even if ZSH were not to segfault, the resulting shell would be next to useless. The thing is that 'compgen -v foo' is supposed to list only variable names starting with 'foo', at least that's what it does under Bash. In ZSH's Bash emulation, however, it lists _all_ variable names, including such fundamental env vars like PATH, HOME, and IFS. So when ZSH took the wrong if branch and run that unset $(compgen -v __gitcomp_builtin_) then it would unset PATH and everything else as well.