This is related to Disable auto-completion of remote branches in Git Bash?.
Anyone knows how to do the same with zsh?
zstyle :completion::complete:git-checkout:argument-rest:headrefs command "git for-each-ref --format='%(refname)' refs/heads 2>/dev/null"
Explanation:
Typing git checkout <Control-x><h>
invokes _complete_help
which exposes the internals of how zsh's completion system would act if you pressed TAB in the current context (instead of pressing <Control-x><h>
). From this it is possible to see that zsh would invoke the __git_heads
function to complete names of git branch heads. If you then type which __git_heads
, you can see that these branch head names are obtained via:
_call_program headrefs git for-each-ref --format='"%(refname)"' refs/heads refs/remotes 2>/dev/null
Luckily for us, _call_program
is designed specifically to allow the user to change the default behaviour. So the above zstyle
command instructs zsh to use an alternative git for-each-ref ...
invocation instead of the built-in one, and you can see that in the invocation above, I removed the refs/remotes
parameter. The first parameter to zstyle
is the completion context, and here it means "whenever the completion system is requesting completion for the headrefs
tag when the user is completing an argument for git checkout
. So this zstyle
will only affect git checkout
, and not any other git
sub-commands.
By typing git checkout <Ctrl-X><H>
you see a bunch of tags, some which seem relevant are:
$ 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)
[...]
At first sight, we need to change remote-branch-names-noprefix
's behavior to stop providing remote branch names with no prefix.
To double check, let's see what entries these tags are associated with, use:
$ 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
In the parenthesis following the tag names above, there is a chain of commands which led to an autocomplete entry being generated for that tag. In remote-branch-names-noprefix
's chain you can see __git_remote_branch_names_noprefix
which seems relevant. Look in /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' "$@"
}
You can see how _call_program
is used to define remote-branch-refs-noprefix
. We want to change this definition in git-checkout
's case. By replacing it with "echo", it will stop providing autocomplete entries:
zstyle ':completion::complete:git-checkout:argument-rest:remote-branch-refs-noprefix' command "echo"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With