Browse Source

bash completion: fix completion issues with fetch, pull, and push

Sverre Rabbelier noticed a completion issue with push:

 $ git push ori<tab>
 git push origin

 $ git push -f ori<tab>
 git push -f origin/

Markus Heidelberg pointed out that the issue extends to fetch and pull.

The reason is that the current code naively assumes that if
COMP_CWORD=2, it should complete a remote name, otherwise it should
complete a refspec. This assumption fails if there are any --options.

This patch fixes that issue by instead scanning COMP_CWORDS to see if
the remote has been completed yet (we now assume the first non-dashed
argument is the remote). The new logic is factored into a function,
shared by fetch, pull, and push.

The new function also properly handles '.' as the remote.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Acked-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Jay Soffian 16 years ago committed by Junio C Hamano
parent
commit
52d5c3b5b2
  1. 109
      contrib/completion/git-completion.bash

109
contrib/completion/git-completion.bash

@ -387,6 +387,63 @@ __git_complete_revlist () @@ -387,6 +387,63 @@ __git_complete_revlist ()
esac
}

__git_complete_remote_or_refspec ()
{
local cmd="${COMP_WORDS[1]}"
local cur="${COMP_WORDS[COMP_CWORD]}"
local i c=2 remote="" pfx="" lhs=1
while [ $c -lt $COMP_CWORD ]; do
i="${COMP_WORDS[c]}"
case "$i" in
-*) ;;
*) remote="$i"; break ;;
esac
c=$((++c))
done
if [ -z "$remote" ]; then
__gitcomp "$(__git_remotes)"
return
fi
[ "$remote" = "." ] && remote=
case "$cur" in
*:*)
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*) pfx="${cur%%:*}:" ;;
esac
cur="${cur#*:}"
lhs=0
;;
+*)
pfx="+"
cur="${cur#+}"
;;
esac
case "$cmd" in
fetch)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur"
else
__gitcomp "$(__git_refs)" "$pfx" "$cur"
fi
;;
pull)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
else
__gitcomp "$(__git_refs)" "$pfx" "$cur"
fi
;;
push)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs)" "$pfx" "$cur"
else
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
fi
;;
esac
}

__git_all_commands ()
{
if [ -n "${__git_all_commandlist-}" ]; then
@ -832,25 +889,7 @@ _git_diff () @@ -832,25 +889,7 @@ _git_diff ()

_git_fetch ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"

if [ "$COMP_CWORD" = 2 ]; then
__gitcomp "$(__git_remotes)"
else
case "$cur" in
*:*)
local pfx=""
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*) pfx="${cur%%:*}:" ;;
esac
__gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
;;
*)
__gitcomp "$(__git_refs2 "${COMP_WORDS[2]}")"
;;
esac
fi
__git_complete_remote_or_refspec
}

_git_format_patch ()
@ -1120,40 +1159,12 @@ _git_name_rev () @@ -1120,40 +1159,12 @@ _git_name_rev ()

_git_pull ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"

if [ "$COMP_CWORD" = 2 ]; then
__gitcomp "$(__git_remotes)"
else
__gitcomp "$(__git_refs "${COMP_WORDS[2]}")"
fi
__git_complete_remote_or_refspec
}

_git_push ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"

if [ "$COMP_CWORD" = 2 ]; then
__gitcomp "$(__git_remotes)"
else
case "$cur" in
*:*)
local pfx=""
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*) pfx="${cur%%:*}:" ;;
esac

__gitcomp "$(__git_refs "${COMP_WORDS[2]}")" "$pfx" "${cur#*:}"
;;
+*)
__gitcomp "$(__git_refs)" + "${cur#+}"
;;
*)
__gitcomp "$(__git_refs)"
;;
esac
fi
__git_complete_remote_or_refspec
}

_git_rebase ()

Loading…
Cancel
Save