How to get bash-style autocompletion in zsh, (for git command)

autocompletebashgitshellzsh

I switched to zsh and find it better than bash, but I have a problem with oh-my-zsh's (hereafter "OMZ") autocomplete feature.

When I type git chec, OMZ completes that to git check; in bash it gets completed to git checkout. I have also a problem with remote branches: ori completed to oriG, and orig to origin, in bash it gets completed to origin/

I have the same problem with other git commands like checkout.

I think the problem is the aliases added by the plugin. I don't use them, as I don't want to get used to them, but they break auto-completion for me.

Is there any way to get the bash autocomplete (I know there isn't a built-in autocomplete in bash) in zsh? Or a way to hack the OMZ plugin so that it doesn't break at each update.

Best Answer

Completion and where it comes from can be rather confusing. Take a Ubuntu 14.04 system as an example:

$ dpkg -L zsh-common | grep git
/usr/share/zsh/functions/Completion/Debian/_git-buildpackage
/usr/share/zsh/functions/Completion/Unix/_stgit
/usr/share/zsh/functions/Completion/Unix/_git
/usr/share/zsh/functions/Completion/Unix/_topgit
/usr/share/zsh/functions/VCS_Info/Backends/VCS_INFO_get_data_git
/usr/share/zsh/functions/VCS_Info/Backends/VCS_INFO_detect_git
/usr/share/zsh/functions/Misc/run-help-git

The zsh-common package ships git completion functions. On the other hand, the git package also comes with completion files for bash and zsh:

$ dpkg -L git | grep compl
/etc/bash_completion.d
/etc/bash_completion.d/git-prompt
/usr/share/bash-completion
/usr/share/bash-completion/completions
/usr/share/bash-completion/completions/git
/usr/share/bash-completion/completions/gitk

Which contains files such as

$ head -n 5 /usr/share/bash-completion/completions/gitk
# bash/zsh completion support for core Git.
#
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
# Distributed under the GNU General Public License, version 2.0.

The git package even provides a git aware prompt which can be enabled, all without fancy addons such as oh-my-zsh.

To summarize, git subcommand completion can come from your shell (zsh):

https://github.com/zsh-users/zsh/blob/master/Completion/Unix/Command/_git

from git

https://github.com/git/git/tree/master/contrib/completion

or from plugins such as oh-my-zsh.

To get back to your question: The old behavior of completing git chec that you describe is actually buggy. chec is still ambiguous and a proper completion script should not complete it to checkout, since there are multiple subcommands that begin with chec. If you want that behavior, find out which of the many completion scripts out there you were using before, disable the oh-my-zsh git plugin and continue to use your old completion script.

Alternatively, I'd recommend to set up an alias and get used to it. You can use

git config --global alias.co checkout

to make git co your new git checkout - the oh-my-zsh plugin is aware of these aliases and will still complete branch and tag names next!

Related Question