14

这与在 Git Bash 中禁用远程分支的自动完成有关?.

任何人都知道如何对 zsh 做同样的事情?

4

5 回答 5

12
zstyle :completion::complete:git-checkout:argument-rest:headrefs command "git for-each-ref --format='%(refname)' refs/heads 2>/dev/null"

解释:

如果您在当前上下文中按 TAB (而不是按) ,键入git checkout <Control-x><h>调用_complete_help会公开 zsh 完成系统如何操作的内部结构。<Control-x><h>从这里可以看出zsh会调用该__git_heads函数来完成git分支头的名称。如果然后键入which __git_heads,您可以看到这些分支头名称是通过以下方式获得的:

_call_program headrefs git for-each-ref --format='"%(refname)"' refs/heads refs/remotes 2>/dev/null

幸运的是,_call_program它专门设计用于允许用户更改默认行为。所以上面的zstyle命令指示 zsh 使用替代git for-each-ref ...调用而不是内置的调用,你可以看到在上面的调用中,我删除了refs/remotes参数。的第一个参数zstyle是完成上下文,这里它的意思是“headrefs当用户完成参数时,完成系统请求完成标签的完成git checkout。所以这zstyle只会影响git checkout,而不影响任何其他git子命令。

于 2013-06-16T12:21:52.677 回答
3

通过键入git checkout <Ctrl-X><H>,您会看到一堆标签,其中一些似乎相关的是:

$ git checkout
tags in context :completion::complete:git-checkout:argument-rest:
    remote-branch-names-noprefix              (__git_describe_branch __git_describe_commit __git_remote_branch_names_noprefix _git-checkout _git) 
    heads-remote                              (__git_describe_branch __git_describe_commit __git_heads_remote __git_heads __git_commits __git_tree_ishs _git-checkout _git) 
    [...]

乍一看,我们需要改变remote-branch-names-noprefix's 的行为以停止提供不带前缀的远程分支名称。

要仔细检查,让我们看看这些标签与哪些条目相关联,使用:

$ zstyle ':completion:*' group-name ''
$ zstyle ':completion:*' format 'Completing "%d":'
$ git checkout T<Tab>
Completing "remote branch name":
T3522-plugins_and_stuff  T7482
Completing "local head":
T7626-async

在上面标签名称后面的括号中,有一串命令会导致为该标签生成自动完成条目。在remote-branch-names-noprefix's 链中,您可以看到__git_remote_branch_names_noprefix哪些似乎相关。看看/usr/share/zsh/functions/Completion/Unix/_git

(( $+functions[__git_remote_branch_names_noprefix] )) ||
__git_remote_branch_names_noprefix () {
  declare -a heads

  branch_names=(${${${${(f)"$(_call_program remote-branch-refs-noprefix git for-each-ref --format='"%(refname)"' refs/remotes 2>/dev/null)"}#refs/remotes/}#*/}:#HEAD})
  __git_command_successful $pipestatus || return 1

  __git_describe_commit branch_names remote-branch-names-noprefix 'remote branch name' "$@"
}

您可以看到如何_call_program用于定义remote-branch-refs-noprefix. 我们想在git-checkout's 的情况下改变这个定义。通过将其替换为“echo”,它将停止提供自动完成条目:

zstyle ':completion::complete:git-checkout:argument-rest:remote-branch-refs-noprefix' command "echo"
于 2016-11-29T15:56:28.150 回答
1

看来__git_heads现在只检查本地分支,而是调用完成文件__git_refs

我通过将此补丁应用到 来破解它git-completion.bash,它由 zsh_git命令代理:

--- git-completion.bash.old 2015-04-02 16:09:38.000000000 -0700
+++ git-completion.bash     2015-04-02 16:10:24.000000000 -0700
@@ -1032,13 +1032,7 @@
                    "
            ;;
    *)
-           # check if --track, --no-track, or --no-guess was specified
-           # if so, disable DWIM mode
-           local flags="--track --no-track --no-guess" track=1
-           if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
-                   track=''
-           fi
-           __gitcomp_nl "$(__git_refs '' $track)"
+           __gitcomp_nl "$(__git_heads)"
            ;;
    esac
 }

这不是一个完美的解决方案,但它适用于我的用例,并且可以立即完成而不是 10 秒。

于 2015-04-02T23:14:36.073 回答
0

没有一个答案不帮助我。尝试这个:

$ git checkout <Ctrl+X><H>
tags in context :completion::complete:git::
    argument-rest  (_arguments _git)
tags in context :completion::complete:git-checkout::
    argument-rest options  (_arguments _git-checkout _call_function _git)
tags in context :completion::complete:git-checkout:argument-rest:
    remote branches tree-ishs modified-files  (_alternative _git-checkout _call_function _git) 
    remote-branch-names-noprefix              (__git_remote_branch_names_noprefix _alternative _git-checkout _call_function _git) 
    heads commit-tags commit-objects          (_alternative __git_commits __git_tree_ishs _alternative _git-checkout _call_function _git) 
    heads-local                               (__git_heads_local __git_heads _alternative __git_commits __git_tree_ishs _alternative _git-checkout _call_function _git) 
    commit-tags                               (__git_tags_of_type __git_commit_tags _alternative __git_commits __git_tree_ishs _alternative _git-checkout _call_function _git) 
    modified-files                            (__git_files __git_modified_files _alternative _git-checkout _call_function _git)

你可以在这个输出函数中找到,它会为命令生成完成。您可以在.zshrc. 把它放在配置文件的最顶部

__git_heads_remote() {}

之后,您将不会在完成时看到远程磁头。您可以对任何功能执行此操作。

于 2018-03-27T08:39:13.263 回答
-2

git checkout您可以通过将此行添加到.zshrc文件中来禁用自动完成功能:

compdef -d git checkout
于 2012-08-29T13:17:02.463 回答