Git completion with zsh: filenames with spaces aren’t being escaped properly

autocompletegitzsh

Git completion:

I'm having difficulty with git's filename autocompletions on my system. I'm using zsh (5.0.5) with git (1.9.3) on OS X (10.9.3). Both zsh and git have been installed via homebrew. (Full version output are at the bottom of the post.)

git's filename completion isn't inserting spaces like I expect. When I type the name of a file with a space in the name, the shell inserts the filename without spaces escaped. zsh's built-in completion doesn't do this, but git's does.

Here's an example of what I'm seeing.

I have a repository with a few files with spaces in their names.

% ls -la
test
test four - latest.txt
test three.txt
test two

The shell backslash escapes the filenames as expected when I use tab completion to insert the file name.

% echo "testing" >> test<tab>

autocompletes to this after hitting tab three times.

% echo "testing" >> test\ four\ -\ latest.txt
––– file
test                       test\ four\ -\ latest.txt  test\ three.txt            test\ two                

git status shows these filenames in quotes (it totally understands what's up):

% git status --short
 M test
 M "test four - latest.txt"
 M "test three.txt"
 M "test two"

but when I try to git add with tab autocompletion, it goes sideways.

% git add test<tab>

results in this after hitting tab three times:

% git add test four - latest.txt
test                    test four - latest.txt  test three.txt          test two

I've tried regressing this a bit: my dotfiles are in version control, so I've tried zsh 4.3.15, git 1.8.3, and my dotfiles from a year ago, when I'm nearly certain this worked. Weirdly, this setup was still broken.

I have narrowed it down to the _git completion file that is being sourced from /usr/local/share/zsh/site-functions:

% echo $FPATH
/usr/local/share/zsh/site-functions:/usr/local/Cellar/zsh/5.0.5/share/zsh/functions
% ls -l /usr/local/share/zsh/site-functions
_git@ -> ../../../Cellar/git/1.9.3/share/zsh/site-functions/_git
_hg@ -> ../../../Cellar/mercurial/3.0/share/zsh/site-functions/_hg
_j@ -> ../../../Cellar/autojump/21.7.1/share/zsh/site-functions/_j
git-completion.bash@ -> ../../../Cellar/git/1.9.3/share/zsh/site-functions/git-completion.bash
go@ -> ../../../Cellar/go/HEAD/share/zsh/site-functions/go

If I manually change $FPATH before my .zshrc runs compinit (or simply remove the /usr/local/share/zsh/site-functions/_git symbolic link), then completions fall back to zsh and work as expected.

The zsh completion without _git:

% git add test<tab>

hitting tab three times produces correct results:

% git add test\ four\ -\ latest.txt
––– modified file
test                       test\ four\ -\ latest.txt  test\ three.txt            test\ two                

Side note: I've tried removing the git-completion.bash link, and it just totally breaks things:

% git add test<tab>

produces this busted-ness:

% git add test__git_zsh_bash_func:9: command not found: __git_aliased_command
    git add test
––– file
test                       test\ four\ -\ latest.txt  test\ three.txt            test\ two                

I really want to get this working properly: the rest of the _git completions were great because they're more repo-aware than the zsh ones, but I need filenames with spaces or other special characters to be properly escaped.


Software versions:

% zsh --version
zsh 5.0.5 (x86_64-apple-darwin13.0.0)

% git --version
git version 1.9.3

% sw_vers
ProductName:    Mac OS X
ProductVersion: 10.9.3
BuildVersion:   13D65

I've uploaded the _git and git-completion.bash files: git-completion.bash and _git (renamed to _git.sh so CloudApp will make it viewable in the browser.)

Best Answer

This bug is mentioned on the mailing list.

The fix is to edit the file git-completion.zsh and remove the -Q option from compadd, in in __gitcomp_file.

--- i/contrib/completion/git-completion.zsh
+++ w/contrib/completion/git-completion.zsh
@@ -90,7 +90,7 @@ __gitcomp_file ()

    local IFS=$'\n'
    compset -P '*[=:]'
-   compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
+   compadd -p "${2-}" -f -- ${=1} && _ret=0
 }

 __git_zsh_bash_func ()

This file is installed from the contrib/completion directory, and its path may vary with your package manager. If you installed with homebrew on macOS, it's located in /usr/local/Cellar/git/2.10.2/share/zsh/site-functions.

Related Question