22

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.)

13
  • 2
    For the non-OSX users in the audience, could you link to some place where we can download the completions that ship with your git package? May 28, 2014 at 0:08
  • 2
    Sure: _git (renamed to _git.sh for CloudApp): cl.ly/code/423e0i1X1p29 and git-completion.bash: cl.ly/code/153v2t142i2G
    – cbowns
    May 28, 2014 at 0:17
  • 3
    I had a glance at _git. The calls to compadd -Q look weird: -Q means “don't quote special characters”. Try removing -Q from the compadd calls. May 28, 2014 at 0:54
  • 3
    I'm fairly sure the problem is due to zsh's default behavior of not word-splitting command-substitution results. In fact - the \bs escape isn't necessary - or is futile, depending on how you look at it. Set "SH_WORD_SPLIT" zsh.sourceforge.net/FAQ/zshfaq03.html
    – mikeserv
    May 28, 2014 at 2:55
  • 4
    Alternatively edit the bash completion functions to output like ${=$(completion)} or whatever it is that they return.
    – mikeserv
    May 28, 2014 at 3:04

1 Answer 1

5

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.

3
  • The error about __git_aliased_command is because the share directory changed name to git-core (at least on FreeBSD), which causes it to not find git-completion.bash. If you change the first location on line 33 to a hardcoded /usr/local/share/git-core/contrib/completion/git-completion.bash it works again.
    – Melvyn
    Dec 4, 2016 at 15:39
  • There's an echo in that file just above these function definitions, and the lack of appearance of it in my shell (and some adjacent code when testing) suggests these completions aren't even used: if [[ -n ${ZSH_VERSION-} ]]; then echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
    – cbowns
    Jan 5, 2017 at 23:00
  • 1
    This worked for me (git 2.18, zsh 5.4.2 osx) when I changed compadd -Q -> compadd for all instances in _git and git-completion.bash in the folder /usr/local/Cellar/git/2.18.0/share/zsh/site-functions/ of my brew git installation. Thank you!!!
    – Merlin
    Aug 25, 2018 at 5:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .