选项卡完成仅冻结Git命令

时间:2014-11-04 16:53:50

标签: git shell zsh tab-completion iterm2

我对我的设置有一些奇怪的行为,我似乎无法缩小范围。

我在shell中使用tab完成没有任何问题(我的shell是zsh)。我遇到的问题是在发出git命令后关于标签完成。

示例1(工作正常):

我创建了一个新目录,并将其更改为git init。然后我touch hello.rb。如果我执行git add <tab>,则会将其更改为git add hello.rb

示例2(不起作用):

我在一个非常大的rails应用程序中,如果我试图运行git add G<tab>,意图它会提升我的Gemfile,它只是挂起并挂起,直到我用ctrl-c杀死它,输出:

Killed by signal in __git_complete_index_file after 159s

在zsh中我使用:

# completion
autoload -U compinit
compinit

还有其他人有这个问题吗?我可以解决它,但我必须做错事,我不确定在哪里看。

事物的版本:

git version 2.1.2
zsh 5.0.7
iTerm2 Build 2.0.0.20141103

更新

Git v 2.2.0修复了此问题,因此如果您遇到此问题,请进行升级。

1 个答案:

答案 0 :(得分:7)

我假设你正在使用RVM或类似的工具。

当前git(2.1.3)和旧版本附带的git-completion.bash中存在一个错误,在使用RVM的目录中列出文件完成时会导致无限循环。

这种无限循环的原因是由{RVM和其他一些工具改变chpwd_functions

我找到了a patch git-comletion.bash只影响用于列出文件的__git_ls_files_helper方法。补丁忽略chpwd_functions,因此省略了这些无限循环。

简而言之:__git_ls_files_helper函数需要更改:

__git_ls_files_helper ()
{
  (
    test -n "${CDPATH+set}" && unset CDPATH
    cd "$1"
    if [ "$2" == "--committable" ]; then
      git diff-index --name-only --relative HEAD
    else
      # NOTE: $2 is not quoted in order to support multiple options
      git ls-files --exclude-standard $2
    fi
   ) 2>/dev/null
}

为:

__git_ls_files_helper ()
{
  (
    test -n "${CDPATH+set}" && unset CDPATH
    (( ${+functions[chpwd]} )) && unfunction chpwd
    (( ${#chpwd_functions} )) && chpwd_functions=()
    setopt chaselinks
    builtin cd "$1" 2>/dev/null
    if [ "$2" == "--committable" ]; then
      git diff-index --name-only --relative HEAD
    else
      # NOTE: $2 is not quoted in order to support multiple options
      git ls-files --exclude-standard $2
    fi
  ) 2>/dev/null
}

更多信息可在RVM issue discussion on Github中找到。 你的git-completion.bash的位置取决于你如何安装git。使用Homebrew时,位置类似于

/usr/local/Cellar/git/<git version>/etc/bash_completion.d/

在其他系统上,或者在使用其他包管理器时,通常应该是

/opt/local/etc/bash_completion.d

有关git-completion.bash的更多信息,请参阅git-scm.com一书中的第2.7章Git提示与技巧。

<强>更新

Git v 2.2.0修复了此问题,因此如果您遇到此问题,请进行升级。