使用裸 git 存储库自动完成 Zsh 文件

使用裸 git 存储库自动完成 Zsh 文件

我的 .zshrc 中有这个:

# command completion
autoload -Uz compinit
compinit

通常让我浏览命令、参数和文件。

但对于git --git-dir=<the path> --work-tree="$HOME"(通常是别名)它仅适用于子命令(如添加和推送)和参数,不适用于文件。我希望它也能处理文件。

我尝试将其放入脚本中,如下所示:

#!/usr/bin/env sh

git --git-dir=<the path> --work-tree="$HOME" "$@"

它适用于文件,但子命令和参数会中断。

谢谢。

答案1

如果--git-dir出现在命令行上,如果您的 zsh 足够新(≥5.3),则完成代码会识别它并在查找要完成的事情时考虑它。它通过将参数--git-dir作为环境变量传递来实现这一点GIT_DIR。例如,要在 后补全远程名称git fetch,zsh 运行git remote。之后git --git-dir=/some/where,zsh在环境中git remote运行。GIT_DIR=/some/where所以这部分确实有效。

不幸的是,从当前的 zsh 版本(5.7.1+)开始,它通过了未展开的争论。因此,如果您写类似的内容git --git-dir=~/repositories/foo.git,zsh 会通过GIT_DIR=~/repositories/foo.git,但不会GIT_DIR=/home/aaa/repositories/foo.git

zsh 补全代码没有对--work-tree.

我认为您可以通过编辑文件并替换行来解决扩展问题--git-dir并添加支持--git-worktree_git

        (( $+opt_args[--git-dir] )) && local -x GIT_DIR=$opt_args[--git-dir]

经过

        (( $+opt_args[--git-dir] )) && local -x GIT_DIR=${(e)~opt_args[--git-dir]}
        (( $+opt_args[--work-tree] )) && local -x GIT_WORKTREE=${(e)~opt_args[--work-tree]}

我没有测试过这个。

我没有足够的动力发帖到 zsh 邮件列表,但请这样做:这个(或者它的工作版本,如果它不起作用)将是一个有用的补丁。

如果您将--git-dir--work-tree放在别名中,这是透明的:zsh 在完成之前扩展别名(假设您没有关闭该选项complete_aliases)。如果你把它们放在一个函数或脚本中,这是不透明的:zsh不会看到它们,甚至不会知道函数或脚本调用了git,除非你告诉它。

如果您无法让此补丁发挥作用,或者您不想维护自己的 版本_git,则可以通过使用包装 git 的自定义完成函数定义自定义命令来解决此问题。

gitx () {
  git --git-dir=/some/where --work-tree=/else/where "$@"
}
_gitx () {
  local -x GIT_DIR=/some/where GIT_WORKTREE=/else/where
  _git "$@"
}
compdef _gitx gitx

如果您有多个包装器,则每个包装器都需要一个完成函数。或者,您可以向完成函数添加一些逻辑来确定要使用的GIT_DIR和的值。GIT_WORKTREE函数的名称位于$service.

相关内容