• Skip to primary navigation
  • Skip to main content
Sal Ferrarello
  • About Sal Ferrarello
  • Speaking
  • Connect
    Mastodon GitHub Twitter (deprecated)
You are here: Home / Dev Tips / Git Alias Tab Completion Not Working

Git Alias Tab Completion Not Working

Last updated on August 26, 2024 by Sal Ferrarello

After setting up new machine I noticed my Git alias tab completion had stopped working. I created this blog post to document how I tracked down this issue and resolved it.

The Issue

I have a Git alias that I use called git can-ff-merge based on Check If We Can Do a Git Fast-Forward Merge (source).

When using this alias we give it a branch name (e.g. git can-ff-merge feat/add-fallback-value).

Using the Git alias tab completion trick of putting : git branch ; \ in my alias, typing git can-ff-merge followed by tab outputs the list of branches.

Example where I hit tab after git can-ff-merge

$ git can-ff-merge
HEAD
ORIG_HEAD
feat/set-dates
main
origin/HEAD
origin/chore/improve-backwards-compat-for-branch-name
origin/chore/update-installation-location-instructions-20
origin/feat/add-git-blame-ignore-revs-alias-29
origin/feat/git-blame-ignore-some-commits
origin/feat/push-default-current
origin/feat/set-auto-setup-remote-true
origin/feat/show-branch-name-w-dash-34
origin/main

Expected Behavior

The branches are show as above (this is the behavior on my old machine).

Actual Behavior

The files in the directory are displayed (this is the behavior on the new machine).

$ git can-ff-merge
LICENSE
README.md
gitconfig

Note: Other tab completion (e.g. tab after git branch) works as expected.

Details

Both machines are using zsh version 5.9 (x86_64-apple-darwin23.0) and git version 2.46.0

How I Fixed It Summary

First, I added these lines to my ~/.zshrc file

# Use brew installed program completions
# See https://docs.brew.sh/Shell-Completion#configuring-completions-in-zsh
if type brew &>/dev/null
then
    FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}"
    autoload -Uz compinit
    compinit
fi

# Use Git's tab completion (_git) installed by brew instead of zsh's default
if type brew &>/dev/null && [ -f "$(brew --prefix)/share/zsh/site-functions/_git" ];
then
    _git () {
        builtin autoload -XUz "$(brew --prefix)/share/zsh/site-functions"
    }
fi
  • PR 63 Add brew completions to FPATH
  • PR 64 When available, use brew installed _git completion

Then I ran this command from the command line

rm ~/.zcompdump

How I Fixed It Details

What Controls Tab Completion

In tab completion is controlled by a function or file in path with a matching name that starts with an underscore (_), therefore the git tab completion is handled by _git

zsh has built in functions for many common commands (e.g. _git for git). You can get information about _git by opening a new terminal window and running

type _git

_git is an autoload shell function from /usr/share/zsh/5.9/functions/_git

Based on this path we can see _git is part of zsh

Brew Shell Completion

I install many of my programs, including git, with the Homebrew Package Manager (a.k.a. “brew”) by default when brew installs a program it does NOT setup the tab completion for that program. If we want tab completion for brew installed programs, we need to follow the brew Shell Completion documentation.

Following these instructions I ran

brew completions link

and added the necessary lines to my zsh configuration for configuring completions in zsh – see PR 63 Add brew completions to FPATH.

Now I had tab completion for other programs I installed with brew like ripgrep and GitHub CLI but Git tab completion for aliases still did not work.

Two Competing Completion Functions

At this point, I opened a new terminal window I gathered some information about the completion functions.

$ type _gh
_gh is an autoload shell function from /opt/homebrew/share/zsh/site-functions/_gh
$ type _rg
_rg is an autoload shell function from /opt/homebrew/share/zsh/site-functions/_rg
$ type _git
_git is an autoload shell function from /usr/share/zsh/5.9/functions/_git

What I noticed is the other programs installed by brew (e.g. gh and rg) were loading the completion function from one directory, while git was loading the completion function from another directory.

I suspected that I should be loading the _git completion function from the same directory as the other brew installed completions and indeed when I added that to my zsh configuration (PR 64 When available, use brew installed _git completion ) and I deleted the ~/.zcompdump cache file (which is the “dumped configuration” of the zsh completion created by zsh’s built-in compinit), it worked!

Alternate Solution

As more than one of the clever developers I know pointed out, I likely could have corrected this issue by using the zsh configuration framework Oh My Zsh. This is a great point and probably would have been the path of least resistance, however the minimalist in me (and the drive of curiosity) led me down the path that resulted in this blog post.

Sal Ferrarello
Sal Ferrarello (@salcode)
Sal is a PHP and JavaScript developer with a focus on the WordPress platform. He is a conference speaker with a background including Piano Player, Radio DJ, Magician/Juggler, Beach Photographer, and High School Math Teacher. Sal can be found professionally at WebDevStudios, where he works as a principal engineer.

Filed Under: Computing, Dev Tips Tagged With: Git, git alias, zsh

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Copyright © 2026 · Bootstrap4 Genesis on Genesis Framework · WordPress · Log in