git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/3] git-completion.bash: pass $__git_subcommand_idx from __git_main()

From
Denton Liu <liu.denton@gmail.com>
Date
Mar 24, 2021, 08:36 UTC
Message-ID
<e4aa3e8cd7f64512ce0d72906f4d15f1f0dc0a60.1616574955.git.liu.denton@gmail.com>
In-Reply-To
<cover.1616574955.git.liu.denton@gmail.com>

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>
---
 contrib/completion/git-completion.bash | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 7dc6cd8eb8..a2f1b5e916 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1474,12 +1474,12 @@ _git_branch ()
 
 _git_bundle ()
 {
-	local cmd="${words[2]}"
+	local cmd="${words[__git_subcommand_idx+1]}"
 	case "$cword" in
-	2)
+	$((__git_subcommand_idx+1)))
 		__gitcomp "create list-heads verify unbundle"
 		;;
-	3)
+	$((__git_subcommand_idx+2)))
 		# looking for a file
 		;;
 	*)
@@ -1894,7 +1894,7 @@ _git_grep ()
 	esac
 
 	case "$cword,$prev" in
-	2,*|*,-*)
+	$((__git_subcommand_idx+1)),*|*,-*)
 		__git_complete_symbol && return
 		;;
 	esac
@@ -3058,7 +3058,7 @@ _git_stash ()
 		branch,--*)
 			;;
 		branch,*)
-			if [ $cword -eq 3 ]; then
+			if [ $cword -eq $((__git_subcommand_idx+2)) ]; then
 				__git_complete_refs
 			else
 				__gitcomp_nl "$(__git stash list \
@@ -3277,11 +3277,9 @@ __git_complete_worktree_paths ()
 _git_worktree ()
 {
 	local subcommands="add list lock move prune remove unlock"
-	local subcommand subcommand_idx
+	local subcommand
 
-	subcommand="$(__git_find_on_cmdline --show-idx "$subcommands")"
-	subcommand_idx="${subcommand% *}"
-	subcommand="${subcommand#* }"
+	subcommand="$(__git_find_on_cmdline "$subcommands")"
 
 	case "$subcommand,$cur" in
 	,*)
@@ -3306,7 +3304,7 @@ _git_worktree ()
 			# be either the 'add' subcommand, the unstuck
 			# argument of an option (e.g. branch for -b|-B), or
 			# 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
 				# complete the path, so fall back to Bash
 				# filename completion.
@@ -3330,7 +3328,7 @@ _git_worktree ()
 		__git_complete_worktree_paths
 		;;
 	move,*)
-		if [ $cword -eq $((subcommand_idx+1)) ]; then
+		if [ $cword -eq $((__git_subcommand_idx+2)) ]; then
 			# The first parameter must be an existing working
 			# tree to be moved.
 			__git_complete_worktree_paths
@@ -3398,6 +3396,7 @@ __git_main ()
 {
 	local i c=1 command __git_dir __git_repo_path
 	local __git_C_args C_args_count=0
+	local __git_subcommand_idx
 
 	while [ $c -lt $cword ]; do
 		i="${words[c]}"
@@ -3412,7 +3411,7 @@ __git_main ()
 			__git_C_args[C_args_count++]="${words[c]}"
 			;;
 		-*) ;;
-		*) command="$i"; break ;;
+		*) command="$i"; __git_subcommand_idx="$c"; break ;;
 		esac
 		((c++))
 	done
-- 
2.31.0.rc2.261.g7f71774620
Previous: Denton LiuNext: SZEDER Gábor
Message 16 of 22 in “git-completion.bash: improvements to _git_stash()”
  1. 0/3 git-completion.bash: improvements to _git_stash()Denton Liu, Mar 16, 2021
  2. 1/3 git-completion.bash: extract from else in _git_stash()Denton Liu, Mar 16, 2021
  3. 2/3 git-completion.bash: fix `git <args>... stash branch` bugDenton Liu, Mar 16, 2021
  4. 3/3 git-completion.bash: use __gitcomp_builtin() in _git_stash()Denton Liu, Mar 16, 2021
  5. 0/3 git-completion.bash: improvements to _git_stash()Denton Liu, Mar 18, 2021
  6. 2/3 git-completion.bash: fix `git <args>... stash branch` bugDenton Liu, Mar 18, 2021
  7. Junio C HamanoMar 18, 2021
  8. Denton LiuMar 19, 2021
  9. Junio C HamanoMar 19, 2021
  10. 1/3 git-completion.bash: extract from else in _git_stash()Denton Liu, Mar 18, 2021
  11. 3/3 git-completion.bash: use __gitcomp_builtin() in _git_stash()Denton Liu, Mar 18, 2021
  12. Junio C HamanoMar 18, 2021
  13. Denton LiuMar 19, 2021
  14. Junio C HamanoMar 19, 2021
  15. 0/3 git-completion.bash: improvements to _git_stash()Denton Liu, Mar 24, 2021
  16. 1/3 git-completion.bash: pass $__git_subcommand_idx from __git_main()Denton Liu, Mar 24, 2021
  17. SZEDER GáborMar 27, 2021
  18. SZEDER GáborMar 28, 2021
  19. 3/3 git-completion.bash: use __gitcomp_builtin() in _git_stash()Denton Liu, Mar 24, 2021
  20. SZEDER GáborMar 28, 2021
  21. 2/3 git-completion.bash: extract from else in _git_stash()Denton Liu, Mar 24, 2021
  22. SZEDER GáborMar 28, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.