我的 .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
.