Search code examples
gitbashautocompletebash-completion

Branch autocompletion does not work with git alias for push


I am using Git with git-completion and everything works fine with a single exception: when I do

git p some_remote [TAB]

I get as autocomplete suggestions the files in the current directory (wrong). p is a Git alias:

$ cat ~/.gitconfig
[alias]
    p = push

Still, when I do:

git push some_remote [TAB]

I get as suggestions the branches in the current repository (correct). In both cases the completion for some_remote works correctly.

What is the reason for this?


Solution

  • It's a bug!

    git-completion.bash does go through your git aliases, wiring each up to the right completion function.

    But then four of those—the functions for git push, fetch, pull, and remote—delegate to __git_complete_remote_or_refspec(), which starts like this:

    __git_complete_remote_or_refspec ()
    {
        local cur_="$cur" cmd="${words[1]}"
        ...
    

    $words is just the list of tokens from the command line, and a few lines down, it starts checking $cmd without expanding aliases, for example:

    case "$cmd" in
    fetch)
      # ...
    pull|remote)
      # ...
    


    As far as I can tell, Gábor Szeder first reported this two years ago in a thread about making completion work with shell aliases.

    He mentioned it again in 2012 in reply to a patch from Felipe Contreras (@felipec). Last month, Felipe announced his fork of git, which actually has a self-contained patch for this: b7b6be72.

    I don't know if that's been submitted upstream, but in the meantime... if you want to test it out, apply the patch to your git-completion.bash:

    curl https://github.com/felipec/git/commit/b7b6be72d60d.diff |
      patch -d [directory containing git-completion.bash]
      # useful options for patch: --verbose --dry-run
    

    If you don't know where your current git-completion.bash lives, try declare -F:

    dirname "$(shopt -s extdebug; declare -F __git_complete | awk '{ print $3 }')"
    

    (After patching git-completion.bash, it'll prompt you for the location of git-completion.zsh to apply the second hunk... you can just hit ^C to skip it.)