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?
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.)
Update April 2014, for Git 2.0:
The commit 880111c (Felipe Contreras (felipec
)) now includes:
Some commands need the first word to determine the actual action that is being executed, however, the command is wrong when we use an alias, for example '
alias.p=push
', if we try to complete 'git p origin <TAB>
', the result would be wrong because__git_complete_remote_or_refspec()
doesn't know where it came from.So let's override
words[1]
, so the alias 'p
' is override by the actual command, 'push
'.
git-completion
doesn't seem to work well with git alias
or regular alias.
For instance, if you had defined an alias 'gp
' for 'git push
', as in "How do I get bash completion to work with aliases?", you could type:
__git_complete gp _git_push
Maybe something similar exist for git aliases, as in this script.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With