Browse Source

git-completion.bash: pass $__git_subcommand_idx from __git_main()

Many completion functions perform hardcoded comparisons with $cword.
This fails in the case where the main git command is given arguments
(e.g. `git -C . bundle<TAB>` would fail to complete its subcommands).

Even _git_worktree(), which uses __git_find_on_cmdline(), could still
fail. With something like `git -C add worktree move<TAB>`, the
subcommand would be incorrectly identified as "add" instead of "move".

Assign $__git_subcommand_idx in __git_main(), where the git subcommand
is actually found and the corresponding completion function is called.
Use this variable to replace hardcoded comparisons with $cword.

Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Denton Liu 4 years ago committed by Junio C Hamano
parent
commit
e94fb44042
  1. 23
      contrib/completion/git-completion.bash

23
contrib/completion/git-completion.bash

@ -1474,12 +1474,12 @@ _git_branch ()


_git_bundle () _git_bundle ()
{ {
local cmd="${words[2]}" local cmd="${words[__git_subcommand_idx+1]}"
case "$cword" in case "$cword" in
2) $((__git_subcommand_idx+1)))
__gitcomp "create list-heads verify unbundle" __gitcomp "create list-heads verify unbundle"
;; ;;
3) $((__git_subcommand_idx+2)))
# looking for a file # looking for a file
;; ;;
*) *)
@ -1894,7 +1894,7 @@ _git_grep ()
esac esac


case "$cword,$prev" in case "$cword,$prev" in
2,*|*,-*) $((__git_subcommand_idx+1)),*|*,-*)
__git_complete_symbol && return __git_complete_symbol && return
;; ;;
esac esac
@ -3058,7 +3058,7 @@ _git_stash ()
branch,--*) branch,--*)
;; ;;
branch,*) branch,*)
if [ $cword -eq 3 ]; then if [ $cword -eq $((__git_subcommand_idx+2)) ]; then
__git_complete_refs __git_complete_refs
else else
__gitcomp_nl "$(__git stash list \ __gitcomp_nl "$(__git stash list \
@ -3277,11 +3277,9 @@ __git_complete_worktree_paths ()
_git_worktree () _git_worktree ()
{ {
local subcommands="add list lock move prune remove unlock" local subcommands="add list lock move prune remove unlock"
local subcommand subcommand_idx local subcommand


subcommand="$(__git_find_on_cmdline --show-idx "$subcommands")" subcommand="$(__git_find_on_cmdline "$subcommands")"
subcommand_idx="${subcommand% *}"
subcommand="${subcommand#* }"


case "$subcommand,$cur" in case "$subcommand,$cur" in
,*) ,*)
@ -3306,7 +3304,7 @@ _git_worktree ()
# be either the 'add' subcommand, the unstuck # be either the 'add' subcommand, the unstuck
# argument of an option (e.g. branch for -b|-B), or # argument of an option (e.g. branch for -b|-B), or
# the path for the new worktree. # the path for the new worktree.
if [ $cword -eq $((subcommand_idx+1)) ]; then if [ $cword -eq $((__git_subcommand_idx+2)) ]; then
# Right after the 'add' subcommand: have to # Right after the 'add' subcommand: have to
# complete the path, so fall back to Bash # complete the path, so fall back to Bash
# filename completion. # filename completion.
@ -3330,7 +3328,7 @@ _git_worktree ()
__git_complete_worktree_paths __git_complete_worktree_paths
;; ;;
move,*) move,*)
if [ $cword -eq $((subcommand_idx+1)) ]; then if [ $cword -eq $((__git_subcommand_idx+2)) ]; then
# The first parameter must be an existing working # The first parameter must be an existing working
# tree to be moved. # tree to be moved.
__git_complete_worktree_paths __git_complete_worktree_paths
@ -3398,6 +3396,7 @@ __git_main ()
{ {
local i c=1 command __git_dir __git_repo_path local i c=1 command __git_dir __git_repo_path
local __git_C_args C_args_count=0 local __git_C_args C_args_count=0
local __git_subcommand_idx


while [ $c -lt $cword ]; do while [ $c -lt $cword ]; do
i="${words[c]}" i="${words[c]}"
@ -3412,7 +3411,7 @@ __git_main ()
__git_C_args[C_args_count++]="${words[c]}" __git_C_args[C_args_count++]="${words[c]}"
;; ;;
-*) ;; -*) ;;
*) command="$i"; break ;; *) command="$i"; __git_subcommand_idx="$c"; break ;;
esac esac
((c++)) ((c++))
done done

Loading…
Cancel
Save