Home > Enterprise >  Limit Git Tab Autocompletion
Limit Git Tab Autocompletion

Time:11-03

I recently upgraded my laptop and have been making sure my developer workflow is how I'm used to. Everything has been working fine except Git tab autocompletion.

Normally I can type git che then hit tab and it will autocomplete to git checkout. For whatever reason, on my new laptop, it does not do that. Now it will list every option that starts with "che" (check-attr, check-ignore, cherry, cherry-pick, etc.)

I've read a bunch but can't seem to figure what is (a) causing this (b) how to change it.

Specs: Laptop - Macbook Pro M1 Shell - zsh

Note: I think it may have to do with Zsh's tab-completion library but not sure how to change it.

I've read documentation and updated zshrc files

Added and removed:

autoload -Uz compinit && compinit

CodePudding user response:

Interesting question! I looked into it and here is what I found:

There are two separate zsh completion systems for git:

  1. The one that ships with git (https://github.com/git/git/blob/master/contrib/completion/git-completion.zsh), which, as shown in the docs you linked, offers the completion system you have, based on any available git binaries.

  2. The one that ships with zsh (https://github.com/zsh-users/zsh/blob/master/Completion/Unix/Command/_git), which is much more complex, as well as apparently more context-aware.

Starting a new zsh session with an empty zshrc (zsh -d -f -i) we see this:

josh% autoload -Uz compinit && compinit
josh% git che<TAB>
check-attr       -- display gitattributes information
check-ignore     -- debug gitignore/exclude files
check-mailmap    -- show canonical names and email addresses of contacts
check-ref-format -- ensure that a reference name is well formed
checkout         -- checkout branch or paths to working tree
checkout-index   -- copy files from index to working directory
cherry           -- find commits not merged upstream
cherry-pick      -- apply changes introduced by some existing commits

Then after loading the other completion system (I'll discuss how exactly to do this next):

josh% git che<TAB>

becomes

josh% git checkout

So how do we switch? The way I do it is via the OMZ plugin gitfast. I don't actually (heaven forbid) use OMZ, but just clone the plugin and source it to my fpath in zshrc with fpath=( $XDG_CONFIG_HOME/ohmyzsh/plugins/gitfast $fpath )

But it looks like a more direct way would be to follow the instructions in _git in that repo:

# The recommended way to install this script is to make a copy of it as a
# file named '_git' inside any directory in your fpath.
#
# For example, create a directory '~/.zsh/', copy this file to '~/.zsh/_git',
# and then add the following to your ~/.zshrc file:
#
#  fpath=(~/.zsh $fpath)
#
# You need git's bash completion script installed. By default bash-completion's
# location will be used (e.g. pkg-config --variable=completionsdir bash-completion).
#
# If your bash completion script is somewhere else, you can specify the
# location in your ~/.zshrc:
#
#  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
  • Related