{"thread":{"id":"55325","subject":"[PATCH 1/3] git-completion.bash: extract from else in _git_stash()","startedAt":"2021-03-16T00:55:12Z","lastAt":"2021-03-28T11:05:44Z","messageCount":22,"participants":["Denton Liu","Junio C Hamano","SZEDER Gábor"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"419217","messageId":"a2d9bc4a6651ea5212ebf7a3ea5441bbd58c1aca.1615855962.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1615855962.git.liu.denton@gmail.com","subject":"[PATCH 1/3] git-completion.bash: extract from else in _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-16T00:54:18Z","receivedAt":"2021-03-16T00:55:12Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"To save a level of indentation, perform an early return in the \"if\" arm\nso we can move the \"else\" code out of the block.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 73 +++++++++++++-------------\n 1 file changed, 37 insertions(+), 36 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7dc6cd8eb8..fe79f6b71c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3035,44 +3035,45 @@ _git_stash ()\n \t\t\tfi\n \t\t\t;;\n \t\tesac\n-\telse\n-\t\tcase \"$subcommand,$cur\" in\n-\t\tpush,--*)\n-\t\t\t__gitcomp \"$save_opts --message\"\n-\t\t\t;;\n-\t\tsave,--*)\n-\t\t\t__gitcomp \"$save_opts\"\n-\t\t\t;;\n-\t\tapply,--*|pop,--*)\n-\t\t\t__gitcomp \"--index --quiet\"\n-\t\t\t;;\n-\t\tdrop,--*)\n-\t\t\t__gitcomp \"--quiet\"\n-\t\t\t;;\n-\t\tlist,--*)\n-\t\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n-\t\t\t;;\n-\t\tshow,--*)\n-\t\t\t__gitcomp \"$__git_diff_common_options\"\n-\t\t\t;;\n-\t\tbranch,--*)\n-\t\t\t;;\n-\t\tbranch,*)\n-\t\t\tif [ $cword -eq 3 ]; then\n-\t\t\t\t__git_complete_refs\n-\t\t\telse\n-\t\t\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n-\t\t\tfi\n-\t\t\t;;\n-\t\tshow,*|apply,*|drop,*|pop,*)\n+\t\treturn\n+\tfi\n+\n+\tcase \"$subcommand,$cur\" in\n+\tpush,--*)\n+\t\t__gitcomp \"$save_opts --message\"\n+\t\t;;\n+\tsave,--*)\n+\t\t__gitcomp \"$save_opts\"\n+\t\t;;\n+\tapply,--*|pop,--*)\n+\t\t__gitcomp \"--index --quiet\"\n+\t\t;;\n+\tdrop,--*)\n+\t\t__gitcomp \"--quiet\"\n+\t\t;;\n+\tlist,--*)\n+\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t;;\n+\tshow,--*)\n+\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t;;\n+\tbranch,--*)\n+\t\t;;\n+\tbranch,*)\n+\t\tif [ $cword -eq 3 ]; then\n+\t\t\t__git_complete_refs\n+\t\telse\n \t\t\t__gitcomp_nl \"$(__git stash list \\\n \t\t\t\t\t| sed -n -e 's/:.*//p')\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\t;;\n-\t\tesac\n-\tfi\n+\t\tfi\n+\t\t;;\n+\tshow,*|apply,*|drop,*|pop,*)\n+\t\t__gitcomp_nl \"$(__git stash list \\\n+\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t;;\n+\t*)\n+\t\t;;\n+\tesac\n }\n \n _git_submodule ()\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419219","messageId":"cover.1615855962.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":null,"subject":"[PATCH 0/3] git-completion.bash: improvements to _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-16T00:54:17Z","receivedAt":"2021-03-16T00:55:12Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"This series modernises the _git_stash() completion handler by letting it\ntake advantage of __gitcomp_builtin(). Also, it fixes a bug with how it\noffers completions when arguments are provided to the main git command.\n\nDenton Liu (3):\n  git-completion.bash: extract from else in _git_stash()\n  git-completion.bash: fix `git <args>... stash branch` bug\n  git-completion.bash: use __gitcomp_builtin() in _git_stash()\n\n contrib/completion/git-completion.bash | 103 +++++++++++++------------\n 1 file changed, 52 insertions(+), 51 deletions(-)\n\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419220","messageId":"be727d0171b16e488a357a959176e60bf9210d40.1615855962.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1615855962.git.liu.denton@gmail.com","subject":"[PATCH 2/3] git-completion.bash: fix `git <args>... stash branch` bug","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-16T00:54:19Z","receivedAt":"2021-03-16T00:55:12Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"When completions are offered for `git stash branch<TAB>`, the user is\nsupposed to receive refs. This works in the case where the main git\ncommand is called without arguments but if options are provided, such as\n`git -C dir stash branch<TAB>`, then the `$cword -eq 3` provides\nincorrect results.\n\nCount the words relative to the first instance of \"stash\" so that we\nignore arguments to the main git command.\n\nUnfortunately, this still does not work 100% correctly. For example, in\nthe case of something like `git -C stash stash branch<TAB>`, this will\nincorrectly identify the first \"stash\" as the command. This seems to be\nan edge-case that we can ignore, though, as other functions, such as\n_git_worktree(), suffer from the same problem.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex fe79f6b71c..da46f46e3c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3016,6 +3016,9 @@ _git_stash ()\n \tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n \tlocal subcommands='push list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n+\tlocal stash_idx=\"$(__git_find_on_cmdline --show-idx stash)\"\n+\tstash_idx=\"${stash_idx% *}\"\n+\n \tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n \t\tsubcommand=\"push\"\n \tfi\n@@ -3060,7 +3063,7 @@ _git_stash ()\n \tbranch,--*)\n \t\t;;\n \tbranch,*)\n-\t\tif [ $cword -eq 3 ]; then\n+\t\tif [ $((cword - stash_idx)) -eq 2 ]; then\n \t\t\t__git_complete_refs\n \t\telse\n \t\t\t__gitcomp_nl \"$(__git stash list \\\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419221","messageId":"d6deaecc1feb771b245f50bc8b9cb197bf693405.1615855962.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1615855962.git.liu.denton@gmail.com","subject":"[PATCH 3/3] git-completion.bash: use __gitcomp_builtin() in _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-16T00:54:20Z","receivedAt":"2021-03-16T00:55:12Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"The completion for 'git stash' has not changed in a major way since it\nwas converted from shell script to builtin. Now that it's a builtin, we\ncan take advantage of the groundwork laid out by parse-options and use\nthe generated options.\n\nRewrite _git_stash() to take use __gitcomp_builtin() to generate\ncompletions for subcommands.\n\nThe main `git stash` command does not take any arguments directly. If no\nsubcommand is given, it automatically defaults to `git stash push`. This\nmeans that we can simplify the logic for when no subcommands have been\ngiven yet. We only have to offer subcommand completions when we're\ncompleting the word after \"stash\". Unfortunately, this does not work\n100% correctly. For example, in the case of something like `git -C stash\nstash<TAB>`, this will incorrectly identify the first \"stash\" as the\ncommand. This seems to be an edge-case that we can ignore, though, as\nother functions, such as _git_worktree(), suffer from the same problem.\n\nOne area that this patch could improve upon is that the `git stash list`\ncommand accepts log-options. It would be nice if the completion for this\nwere unified with that of _git_log() and _git_show() which would allow\ncompletions to be provided for options such as `--pretty` but that is\noutside the scope of this patch.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 41 ++++++++++++--------------\n 1 file changed, 19 insertions(+), 22 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex da46f46e3c..83b6415b13 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3013,29 +3013,21 @@ _git_sparse_checkout ()\n \n _git_stash ()\n {\n-\tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n \tlocal subcommands='push list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n \tlocal stash_idx=\"$(__git_find_on_cmdline --show-idx stash)\"\n \tstash_idx=\"${stash_idx% *}\"\n \n-\tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n-\t\tsubcommand=\"push\"\n-\tfi\n \tif [ -z \"$subcommand\" ]; then\n-\t\tcase \"$cur\" in\n-\t\t--*)\n-\t\t\t__gitcomp \"$save_opts\"\n+\t\tcase \"$((cword - stash_idx)),$cur\" in\n+\t\t*,--*)\n+\t\t\t__gitcomp_builtin stash_push\n \t\t\t;;\n-\t\tsa*)\n-\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n-\t\t\t\t__gitcomp \"save\"\n-\t\t\tfi\n+\t\t1,sa*)\n+\t\t\t__gitcomp \"save\"\n \t\t\t;;\n-\t\t*)\n-\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n-\t\t\t\t__gitcomp \"$subcommands\"\n-\t\t\tfi\n+\t\t1,*)\n+\t\t\t__gitcomp \"$subcommands\"\n \t\t\t;;\n \t\tesac\n \t\treturn\n@@ -3043,24 +3035,29 @@ _git_stash ()\n \n \tcase \"$subcommand,$cur\" in\n \tpush,--*)\n-\t\t__gitcomp \"$save_opts --message\"\n+\t\t__gitcomp_builtin stash_push\n \t\t;;\n \tsave,--*)\n-\t\t__gitcomp \"$save_opts\"\n+\t\t__gitcomp_builtin stash_save\n \t\t;;\n-\tapply,--*|pop,--*)\n-\t\t__gitcomp \"--index --quiet\"\n+\tpop,--*)\n+\t\t__gitcomp_builtin stash_pop\n+\t\t;;\n+\tapply,--*)\n+\t\t__gitcomp_builtin stash_apply\n \t\t;;\n \tdrop,--*)\n-\t\t__gitcomp \"--quiet\"\n+\t\t__gitcomp_builtin stash_drop\n \t\t;;\n \tlist,--*)\n-\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t# NEEDSWORK: can we somehow unify this with the options in _git_log() and _git_show()\n+\t\t__gitcomp_builtin stash_list \"$__git_log_common_options $__git_diff_common_options\"\n \t\t;;\n \tshow,--*)\n-\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t__gitcomp_builtin stash_show \"$__git_diff_common_options\"\n \t\t;;\n \tbranch,--*)\n+\t\t__gitcomp_builtin stash_branch\n \t\t;;\n \tbranch,*)\n \t\tif [ $((cword - stash_idx)) -eq 2 ]; then\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419621","messageId":"cover.1616060793.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1615855962.git.liu.denton@gmail.com","subject":"[RESEND PATCH 0/3] git-completion.bash: improvements to _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-18T09:46:53Z","receivedAt":"2021-03-18T09:47:57Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"This series modernises the _git_stash() completion handler by letting it\ntake advantage of __gitcomp_builtin(). Also, it fixes a bug with how it\noffers completions when arguments are provided to the main git command.\n\nDenton Liu (3):\n  git-completion.bash: extract from else in _git_stash()\n  git-completion.bash: fix `git <args>... stash branch` bug\n  git-completion.bash: use __gitcomp_builtin() in _git_stash()\n\n contrib/completion/git-completion.bash | 103 +++++++++++++------------\n 1 file changed, 52 insertions(+), 51 deletions(-)\n\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419622","messageId":"be727d0171b16e488a357a959176e60bf9210d40.1616060793.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1616060793.git.liu.denton@gmail.com","subject":"[RESEND PATCH 2/3] git-completion.bash: fix `git <args>... stash branch` bug","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-18T09:46:55Z","receivedAt":"2021-03-18T09:47:58Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"When completions are offered for `git stash branch<TAB>`, the user is\nsupposed to receive refs. This works in the case where the main git\ncommand is called without arguments but if options are provided, such as\n`git -C dir stash branch<TAB>`, then the `$cword -eq 3` provides\nincorrect results.\n\nCount the words relative to the first instance of \"stash\" so that we\nignore arguments to the main git command.\n\nUnfortunately, this still does not work 100% correctly. For example, in\nthe case of something like `git -C stash stash branch<TAB>`, this will\nincorrectly identify the first \"stash\" as the command. This seems to be\nan edge-case that we can ignore, though, as other functions, such as\n_git_worktree(), suffer from the same problem.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex fe79f6b71c..da46f46e3c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3016,6 +3016,9 @@ _git_stash ()\n \tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n \tlocal subcommands='push list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n+\tlocal stash_idx=\"$(__git_find_on_cmdline --show-idx stash)\"\n+\tstash_idx=\"${stash_idx% *}\"\n+\n \tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n \t\tsubcommand=\"push\"\n \tfi\n@@ -3060,7 +3063,7 @@ _git_stash ()\n \tbranch,--*)\n \t\t;;\n \tbranch,*)\n-\t\tif [ $cword -eq 3 ]; then\n+\t\tif [ $((cword - stash_idx)) -eq 2 ]; then\n \t\t\t__git_complete_refs\n \t\telse\n \t\t\t__gitcomp_nl \"$(__git stash list \\\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419623","messageId":"a2d9bc4a6651ea5212ebf7a3ea5441bbd58c1aca.1616060793.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1616060793.git.liu.denton@gmail.com","subject":"[RESEND PATCH 1/3] git-completion.bash: extract from else in _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-18T09:46:54Z","receivedAt":"2021-03-18T09:47:58Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"To save a level of indentation, perform an early return in the \"if\" arm\nso we can move the \"else\" code out of the block.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 73 +++++++++++++-------------\n 1 file changed, 37 insertions(+), 36 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7dc6cd8eb8..fe79f6b71c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3035,44 +3035,45 @@ _git_stash ()\n \t\t\tfi\n \t\t\t;;\n \t\tesac\n-\telse\n-\t\tcase \"$subcommand,$cur\" in\n-\t\tpush,--*)\n-\t\t\t__gitcomp \"$save_opts --message\"\n-\t\t\t;;\n-\t\tsave,--*)\n-\t\t\t__gitcomp \"$save_opts\"\n-\t\t\t;;\n-\t\tapply,--*|pop,--*)\n-\t\t\t__gitcomp \"--index --quiet\"\n-\t\t\t;;\n-\t\tdrop,--*)\n-\t\t\t__gitcomp \"--quiet\"\n-\t\t\t;;\n-\t\tlist,--*)\n-\t\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n-\t\t\t;;\n-\t\tshow,--*)\n-\t\t\t__gitcomp \"$__git_diff_common_options\"\n-\t\t\t;;\n-\t\tbranch,--*)\n-\t\t\t;;\n-\t\tbranch,*)\n-\t\t\tif [ $cword -eq 3 ]; then\n-\t\t\t\t__git_complete_refs\n-\t\t\telse\n-\t\t\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n-\t\t\tfi\n-\t\t\t;;\n-\t\tshow,*|apply,*|drop,*|pop,*)\n+\t\treturn\n+\tfi\n+\n+\tcase \"$subcommand,$cur\" in\n+\tpush,--*)\n+\t\t__gitcomp \"$save_opts --message\"\n+\t\t;;\n+\tsave,--*)\n+\t\t__gitcomp \"$save_opts\"\n+\t\t;;\n+\tapply,--*|pop,--*)\n+\t\t__gitcomp \"--index --quiet\"\n+\t\t;;\n+\tdrop,--*)\n+\t\t__gitcomp \"--quiet\"\n+\t\t;;\n+\tlist,--*)\n+\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t;;\n+\tshow,--*)\n+\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t;;\n+\tbranch,--*)\n+\t\t;;\n+\tbranch,*)\n+\t\tif [ $cword -eq 3 ]; then\n+\t\t\t__git_complete_refs\n+\t\telse\n \t\t\t__gitcomp_nl \"$(__git stash list \\\n \t\t\t\t\t| sed -n -e 's/:.*//p')\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\t;;\n-\t\tesac\n-\tfi\n+\t\tfi\n+\t\t;;\n+\tshow,*|apply,*|drop,*|pop,*)\n+\t\t__gitcomp_nl \"$(__git stash list \\\n+\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t;;\n+\t*)\n+\t\t;;\n+\tesac\n }\n \n _git_submodule ()\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419624","messageId":"d6deaecc1feb771b245f50bc8b9cb197bf693405.1616060793.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1616060793.git.liu.denton@gmail.com","subject":"[RESEND PATCH 3/3] git-completion.bash: use __gitcomp_builtin() in _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-18T09:46:56Z","receivedAt":"2021-03-18T09:47:58Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"The completion for 'git stash' has not changed in a major way since it\nwas converted from shell script to builtin. Now that it's a builtin, we\ncan take advantage of the groundwork laid out by parse-options and use\nthe generated options.\n\nRewrite _git_stash() to take use __gitcomp_builtin() to generate\ncompletions for subcommands.\n\nThe main `git stash` command does not take any arguments directly. If no\nsubcommand is given, it automatically defaults to `git stash push`. This\nmeans that we can simplify the logic for when no subcommands have been\ngiven yet. We only have to offer subcommand completions when we're\ncompleting the word after \"stash\". Unfortunately, this does not work\n100% correctly. For example, in the case of something like `git -C stash\nstash<TAB>`, this will incorrectly identify the first \"stash\" as the\ncommand. This seems to be an edge-case that we can ignore, though, as\nother functions, such as _git_worktree(), suffer from the same problem.\n\nOne area that this patch could improve upon is that the `git stash list`\ncommand accepts log-options. It would be nice if the completion for this\nwere unified with that of _git_log() and _git_show() which would allow\ncompletions to be provided for options such as `--pretty` but that is\noutside the scope of this patch.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 41 ++++++++++++--------------\n 1 file changed, 19 insertions(+), 22 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex da46f46e3c..83b6415b13 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3013,29 +3013,21 @@ _git_sparse_checkout ()\n \n _git_stash ()\n {\n-\tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n \tlocal subcommands='push list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n \tlocal stash_idx=\"$(__git_find_on_cmdline --show-idx stash)\"\n \tstash_idx=\"${stash_idx% *}\"\n \n-\tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n-\t\tsubcommand=\"push\"\n-\tfi\n \tif [ -z \"$subcommand\" ]; then\n-\t\tcase \"$cur\" in\n-\t\t--*)\n-\t\t\t__gitcomp \"$save_opts\"\n+\t\tcase \"$((cword - stash_idx)),$cur\" in\n+\t\t*,--*)\n+\t\t\t__gitcomp_builtin stash_push\n \t\t\t;;\n-\t\tsa*)\n-\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n-\t\t\t\t__gitcomp \"save\"\n-\t\t\tfi\n+\t\t1,sa*)\n+\t\t\t__gitcomp \"save\"\n \t\t\t;;\n-\t\t*)\n-\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n-\t\t\t\t__gitcomp \"$subcommands\"\n-\t\t\tfi\n+\t\t1,*)\n+\t\t\t__gitcomp \"$subcommands\"\n \t\t\t;;\n \t\tesac\n \t\treturn\n@@ -3043,24 +3035,29 @@ _git_stash ()\n \n \tcase \"$subcommand,$cur\" in\n \tpush,--*)\n-\t\t__gitcomp \"$save_opts --message\"\n+\t\t__gitcomp_builtin stash_push\n \t\t;;\n \tsave,--*)\n-\t\t__gitcomp \"$save_opts\"\n+\t\t__gitcomp_builtin stash_save\n \t\t;;\n-\tapply,--*|pop,--*)\n-\t\t__gitcomp \"--index --quiet\"\n+\tpop,--*)\n+\t\t__gitcomp_builtin stash_pop\n+\t\t;;\n+\tapply,--*)\n+\t\t__gitcomp_builtin stash_apply\n \t\t;;\n \tdrop,--*)\n-\t\t__gitcomp \"--quiet\"\n+\t\t__gitcomp_builtin stash_drop\n \t\t;;\n \tlist,--*)\n-\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t# NEEDSWORK: can we somehow unify this with the options in _git_log() and _git_show()\n+\t\t__gitcomp_builtin stash_list \"$__git_log_common_options $__git_diff_common_options\"\n \t\t;;\n \tshow,--*)\n-\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t__gitcomp_builtin stash_show \"$__git_diff_common_options\"\n \t\t;;\n \tbranch,--*)\n+\t\t__gitcomp_builtin stash_branch\n \t\t;;\n \tbranch,*)\n \t\tif [ $((cword - stash_idx)) -eq 2 ]; then\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"419650","messageId":"xmqqsg4sryq9.fsf@gitster.g","threadId":"55325","inReplyTo":"be727d0171b16e488a357a959176e60bf9210d40.1616060793.git.liu.denton@gmail.com","subject":"Re: [RESEND PATCH 2/3] git-completion.bash: fix `git <args>... stash branch` bug","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-03-18T20:30:38Z","receivedAt":"2021-03-18T20:31:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Denton Liu <liu.denton@gmail.com> writes:\n\n> When completions are offered for `git stash branch<TAB>`, the user is\n> supposed to receive refs. This works in the case where the main git\n> command is called without arguments but if options are provided, such as\n> `git -C dir stash branch<TAB>`, then the `$cword -eq 3` provides\n> incorrect results.\n>\n> Count the words relative to the first instance of \"stash\" so that we\n> ignore arguments to the main git command.\n>\n> Unfortunately, this still does not work 100% correctly. For example, in\n> the case of something like `git -C stash stash branch<TAB>`, this will\n> incorrectly identify the first \"stash\" as the command. This seems to be\n> an edge-case that we can ignore, though, as other functions, such as\n> _git_worktree(), suffer from the same problem.\n\nI am not familiar with how the completion support works, but doing\nthis inside _git_stash() and still not being able to tell which\n\"stash\" on the command line is supposed to be the git subcommand\nsmells quite fishy to me.  \n\nHow did the caller decide to invoke _git_stash helper function in\nthe first place?\n\nWhen it is given \"git -C push --paginate stash branch<TAB>\", it must\nhave parsed the command line, past the options given to the \"git\"\npotty, to find \"stash\" on the command line that it is _git_stash and\nnot _git_push that needs to be called, no?  If it were possible to\npropagate that information without losing it, then we do not have to\nrecompute where the subcommand name is at all, do we?\n\n> Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 5 ++++-\n>  1 file changed, 4 insertions(+), 1 deletion(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index fe79f6b71c..da46f46e3c 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -3016,6 +3016,9 @@ _git_stash ()\n>  \tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n>  \tlocal subcommands='push list show apply clear drop pop create branch'\n>  \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n> +\tlocal stash_idx=\"$(__git_find_on_cmdline --show-idx stash)\"\n> +\tstash_idx=\"${stash_idx% *}\"\n> +\n>  \tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n>  \t\tsubcommand=\"push\"\n>  \tfi\n> @@ -3060,7 +3063,7 @@ _git_stash ()\n>  \tbranch,--*)\n>  \t\t;;\n>  \tbranch,*)\n> -\t\tif [ $cword -eq 3 ]; then\n> +\t\tif [ $((cword - stash_idx)) -eq 2 ]; then\n>  \t\t\t__git_complete_refs\n>  \t\telse\n>  \t\t\t__gitcomp_nl \"$(__git stash list \\\n"},{"id":"419661","messageId":"xmqqv99oqg39.fsf@gitster.g","threadId":"55325","inReplyTo":"cover.1616060793.git.liu.denton@gmail.com","subject":"Re: [RESEND PATCH 0/3] git-completion.bash: improvements to _git_stash()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-03-18T21:58:34Z","receivedAt":"2021-03-18T21:59:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Denton Liu <liu.denton@gmail.com> writes:\n\n> This series modernises the _git_stash() completion handler by letting it\n> take advantage of __gitcomp_builtin(). Also, it fixes a bug with how it\n> offers completions when arguments are provided to the main git command.\n>\n> Denton Liu (3):\n>   git-completion.bash: extract from else in _git_stash()\n>   git-completion.bash: fix `git <args>... stash branch` bug\n>   git-completion.bash: use __gitcomp_builtin() in _git_stash()\n>\n>  contrib/completion/git-completion.bash | 103 +++++++++++++------------\n>  1 file changed, 52 insertions(+), 51 deletions(-)\n\nHmph, this comflicts with your own \"stash show --include-untracked\nand --only-untracked\" completion patch d3c7bf73bdb67, it seems.  How\nready is that topic for 'master'?\n\n"},{"id":"419685","messageId":"YFRbM1st0yINtScF@generichostname","threadId":"55325","inReplyTo":"xmqqsg4sryq9.fsf@gitster.g","subject":"Re: [RESEND PATCH 2/3] git-completion.bash: fix `git <args>... stash branch` bug","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-19T08:05:07Z","receivedAt":"2021-03-19T08:06:02Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"Hi Junio,\n\nOn Thu, Mar 18, 2021 at 01:30:38PM -0700, Junio C Hamano wrote:\n> Denton Liu <liu.denton@gmail.com> writes:\n> \n> > When completions are offered for `git stash branch<TAB>`, the user is\n> > supposed to receive refs. This works in the case where the main git\n> > command is called without arguments but if options are provided, such as\n> > `git -C dir stash branch<TAB>`, then the `$cword -eq 3` provides\n> > incorrect results.\n> >\n> > Count the words relative to the first instance of \"stash\" so that we\n> > ignore arguments to the main git command.\n> >\n> > Unfortunately, this still does not work 100% correctly. For example, in\n> > the case of something like `git -C stash stash branch<TAB>`, this will\n> > incorrectly identify the first \"stash\" as the command. This seems to be\n> > an edge-case that we can ignore, though, as other functions, such as\n> > _git_worktree(), suffer from the same problem.\n> \n> I am not familiar with how the completion support works, but doing\n> this inside _git_stash() and still not being able to tell which\n> \"stash\" on the command line is supposed to be the git subcommand\n> smells quite fishy to me.  \n> \n> How did the caller decide to invoke _git_stash helper function in\n> the first place?\n> \n> When it is given \"git -C push --paginate stash branch<TAB>\", it must\n> have parsed the command line, past the options given to the \"git\"\n> potty, to find \"stash\" on the command line that it is _git_stash and\n> not _git_push that needs to be called, no?  If it were possible to\n> propagate that information without losing it, then we do not have to\n> recompute where the subcommand name is at all, do we?\n\nGood observation. _git_stash() is called in the body of\n__git_complete_command() which is called by __git_main(). There is\ncurrently no mechanism by which to pass the index of the command over to\n_git_*() completion functions.\n\nThat being said, passing in the index to all functions would definitely\nbe doable. I can work on a series in the future that passes in the index\nof the command so that working with $cword is more robust but I'd prefer\nif that were handled outside this series to keep it focused.\n\nThanks,\nDenton\n"},{"id":"419686","messageId":"YFRcLpfRNQbqpHoo@generichostname","threadId":"55325","inReplyTo":"xmqqv99oqg39.fsf@gitster.g","subject":"Re: [RESEND PATCH 0/3] git-completion.bash: improvements to _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-19T08:09:18Z","receivedAt":"2021-03-19T08:10:18Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"Hi Junio,\n\nOn Thu, Mar 18, 2021 at 02:58:34PM -0700, Junio C Hamano wrote:\n> Denton Liu <liu.denton@gmail.com> writes:\n> \n> > This series modernises the _git_stash() completion handler by letting it\n> > take advantage of __gitcomp_builtin(). Also, it fixes a bug with how it\n> > offers completions when arguments are provided to the main git command.\n> >\n> > Denton Liu (3):\n> >   git-completion.bash: extract from else in _git_stash()\n> >   git-completion.bash: fix `git <args>... stash branch` bug\n> >   git-completion.bash: use __gitcomp_builtin() in _git_stash()\n> >\n> >  contrib/completion/git-completion.bash | 103 +++++++++++++------------\n> >  1 file changed, 52 insertions(+), 51 deletions(-)\n> \n> Hmph, this comflicts with your own \"stash show --include-untracked\n> and --only-untracked\" completion patch d3c7bf73bdb67, it seems.  How\n> ready is that topic for 'master'?\n\nAh, sorry I forgot to mention that it conflicts in the cover letter. The\nresolution can be done by just taking these changes. If you'd like, I\ncan also rebase this series on top of 'dl/stash-show-untracked'.\n\nIn any case, unless you have any other concerns, I would declare\n'dl/stash-show-untracked' ready for 'master'.\n\nThanks,\nDenton\n"},{"id":"419716","messageId":"xmqqy2ejnnqp.fsf@gitster.g","threadId":"55325","inReplyTo":"YFRbM1st0yINtScF@generichostname","subject":"Re: [RESEND PATCH 2/3] git-completion.bash: fix `git <args>... stash branch` bug","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-03-19T15:53:50Z","receivedAt":"2021-03-19T15:54:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Denton Liu <liu.denton@gmail.com> writes:\n\n> Good observation. _git_stash() is called in the body of\n> __git_complete_command() which is called by __git_main(). There is\n> currently no mechanism by which to pass the index of the command over to\n> _git_*() completion functions.\n\nI think, given that \"set | grep _git\" tells us we use many globals\nalready, it would be OK to introduce another variable, call it\n$__git_subcmd_pos, and assign to it when the command dispatcher\ndiscovers which token on the command line is the subcommand name and\ndecides to call the subcommand specific completion helper function.\n\nOr does the command dispatcher not exactly know the position\n(e.g. iterates with \"for w\" and knows $w==stash in the current\niteration but it is not counting the position in the array)?  If so,\nthen we'd need a surgery larger than that.\n\nBut if we only need to set a variable, we won't have to change the\ncalling convention of these helpers (well, we shouldn't be changing\nthe arguments to completion functions lightly anyway---third-party\ncompletion functions can be called from __git_complete_command, if I\nam reading the code correctly, and we cannot update them all even if\nwe wanted to).\n\nAnd most subcommands that do not care where on the command line the\nsubcommand name is won't have to change anything.\n\n> That being said, passing in the index to all functions would definitely\n> be doable. I can work on a series in the future that passes in the index\n> of the command so that working with $cword is more robust but I'd prefer\n> if that were handled outside this series to keep it focused.\n\nIf the breakage of \"stash branch\" were a serious show-stopper bug\nthat needs to be fixed right away, I would agree that a band-aid\nsolution that would work most of the time would be fine, but I\ndidn't get an impression that it is so urgent and we can afford to\nfix it right this time, together with the other completion that\nshare the same problem (you mentioned _git_worktree IIRC).\n\nThanks.\n"},{"id":"419717","messageId":"xmqqtup7nnld.fsf@gitster.g","threadId":"55325","inReplyTo":"YFRcLpfRNQbqpHoo@generichostname","subject":"Re: [RESEND PATCH 0/3] git-completion.bash: improvements to _git_stash()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-03-19T15:57:02Z","receivedAt":"2021-03-19T15:58:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Denton Liu <liu.denton@gmail.com> writes:\n\n> In any case, unless you have any other concerns, I would declare\n> 'dl/stash-show-untracked' ready for 'master'.\n\nI've read dl/stash-show-untracked a few times already and agree that\nit would be OK after the \"fixes\" graduate for 'master' and also for\n2.31.x maintenance track at the same time.\n\nIt would be nicer if we just rebuild on top, perhaps making the \"use\n__gitcomp_builtin\" as the first of these \"improvements\" patches.\n\nThanks.\n"},{"id":"420105","messageId":"e4aa3e8cd7f64512ce0d72906f4d15f1f0dc0a60.1616574955.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1616574955.git.liu.denton@gmail.com","subject":"[PATCH v2 1/3] git-completion.bash: pass $__git_subcommand_idx from __git_main()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-24T08:36:27Z","receivedAt":"2021-03-24T08:37:41Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"Many completion functions perform hardcoded comparisons with $cword.\nThis fails in the case where the main git command is given arguments\n(e.g. `git -C . bundle<TAB>` would fail to complete its subcommands).\n\nEven _git_worktree(), which uses __git_find_on_cmdline(), could still\nfail. With something like `git -C add worktree move<TAB>`, the\nsubcommand would be incorrectly identified as \"add\" instead of \"move\".\n\nAssign $__git_subcommand_idx in __git_main(), where the git subcommand\nis actually found and the corresponding completion function is called.\nUse this variable to replace hardcoded comparisons with $cword.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 23 +++++++++++------------\n 1 file changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7dc6cd8eb8..a2f1b5e916 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1474,12 +1474,12 @@ _git_branch ()\n \n _git_bundle ()\n {\n-\tlocal cmd=\"${words[2]}\"\n+\tlocal cmd=\"${words[__git_subcommand_idx+1]}\"\n \tcase \"$cword\" in\n-\t2)\n+\t$((__git_subcommand_idx+1)))\n \t\t__gitcomp \"create list-heads verify unbundle\"\n \t\t;;\n-\t3)\n+\t$((__git_subcommand_idx+2)))\n \t\t# looking for a file\n \t\t;;\n \t*)\n@@ -1894,7 +1894,7 @@ _git_grep ()\n \tesac\n \n \tcase \"$cword,$prev\" in\n-\t2,*|*,-*)\n+\t$((__git_subcommand_idx+1)),*|*,-*)\n \t\t__git_complete_symbol && return\n \t\t;;\n \tesac\n@@ -3058,7 +3058,7 @@ _git_stash ()\n \t\tbranch,--*)\n \t\t\t;;\n \t\tbranch,*)\n-\t\t\tif [ $cword -eq 3 ]; then\n+\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n \t\t\t\t__git_complete_refs\n \t\t\telse\n \t\t\t\t__gitcomp_nl \"$(__git stash list \\\n@@ -3277,11 +3277,9 @@ __git_complete_worktree_paths ()\n _git_worktree ()\n {\n \tlocal subcommands=\"add list lock move prune remove unlock\"\n-\tlocal subcommand subcommand_idx\n+\tlocal subcommand\n \n-\tsubcommand=\"$(__git_find_on_cmdline --show-idx \"$subcommands\")\"\n-\tsubcommand_idx=\"${subcommand% *}\"\n-\tsubcommand=\"${subcommand#* }\"\n+\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \n \tcase \"$subcommand,$cur\" in\n \t,*)\n@@ -3306,7 +3304,7 @@ _git_worktree ()\n \t\t\t# be either the 'add' subcommand, the unstuck\n \t\t\t# argument of an option (e.g. branch for -b|-B), or\n \t\t\t# the path for the new worktree.\n-\t\t\tif [ $cword -eq $((subcommand_idx+1)) ]; then\n+\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n \t\t\t\t# Right after the 'add' subcommand: have to\n \t\t\t\t# complete the path, so fall back to Bash\n \t\t\t\t# filename completion.\n@@ -3330,7 +3328,7 @@ _git_worktree ()\n \t\t__git_complete_worktree_paths\n \t\t;;\n \tmove,*)\n-\t\tif [ $cword -eq $((subcommand_idx+1)) ]; then\n+\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n \t\t\t# The first parameter must be an existing working\n \t\t\t# tree to be moved.\n \t\t\t__git_complete_worktree_paths\n@@ -3398,6 +3396,7 @@ __git_main ()\n {\n \tlocal i c=1 command __git_dir __git_repo_path\n \tlocal __git_C_args C_args_count=0\n+\tlocal __git_subcommand_idx\n \n \twhile [ $c -lt $cword ]; do\n \t\ti=\"${words[c]}\"\n@@ -3412,7 +3411,7 @@ __git_main ()\n \t\t\t__git_C_args[C_args_count++]=\"${words[c]}\"\n \t\t\t;;\n \t\t-*) ;;\n-\t\t*) command=\"$i\"; break ;;\n+\t\t*) command=\"$i\"; __git_subcommand_idx=\"$c\"; break ;;\n \t\tesac\n \t\t((c++))\n \tdone\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"420106","messageId":"cover.1616574955.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1615855962.git.liu.denton@gmail.com","subject":"[PATCH v2 0/3] git-completion.bash: improvements to _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-24T08:36:26Z","receivedAt":"2021-03-24T08:37:41Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"This series modernises the _git_stash() completion handler by letting it\ntake advantage of __gitcomp_builtin(). Also, it fixes a bug with how\ncompletions are offered when arguments are provided to the main git\ncommand.\n\nChanges since v1:\n\n* Fix the hardcoded $cword comparisons in a more generic way\n\nDenton Liu (3):\n  git-completion.bash: pass $__git_subcommand_idx from __git_main()\n  git-completion.bash: extract from else in _git_stash()\n  git-completion.bash: use __gitcomp_builtin() in _git_stash()\n\n contrib/completion/git-completion.bash | 122 ++++++++++++-------------\n 1 file changed, 60 insertions(+), 62 deletions(-)\n\nRange-diff against v1:\n-:  ---------- > 1:  e4aa3e8cd7 git-completion.bash: pass $__git_subcommand_idx from __git_main()\n1:  a2d9bc4a66 ! 2:  430d5acf97 git-completion.bash: extract from else in _git_stash()\n    @@ contrib/completion/git-completion.bash: _git_stash ()\n     -\t\tbranch,--*)\n     -\t\t\t;;\n     -\t\tbranch,*)\n    --\t\t\tif [ $cword -eq 3 ]; then\n    +-\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n     -\t\t\t\t__git_complete_refs\n     -\t\t\telse\n     -\t\t\t\t__gitcomp_nl \"$(__git stash list \\\n    @@ contrib/completion/git-completion.bash: _git_stash ()\n     +\tbranch,--*)\n     +\t\t;;\n     +\tbranch,*)\n    -+\t\tif [ $cword -eq 3 ]; then\n    ++\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n     +\t\t\t__git_complete_refs\n     +\t\telse\n      \t\t\t__gitcomp_nl \"$(__git stash list \\\n2:  be727d0171 < -:  ---------- git-completion.bash: fix `git <args>... stash branch` bug\n3:  d6deaecc1f ! 3:  680f3a3146 git-completion.bash: use __gitcomp_builtin() in _git_stash()\n    @@ Commit message\n         subcommand is given, it automatically defaults to `git stash push`. This\n         means that we can simplify the logic for when no subcommands have been\n         given yet. We only have to offer subcommand completions when we're\n    -    completing the word after \"stash\". Unfortunately, this does not work\n    -    100% correctly. For example, in the case of something like `git -C stash\n    -    stash<TAB>`, this will incorrectly identify the first \"stash\" as the\n    -    command. This seems to be an edge-case that we can ignore, though, as\n    -    other functions, such as _git_worktree(), suffer from the same problem.\n    +    completing a non-option after \"stash\".\n     \n         One area that this patch could improve upon is that the `git stash list`\n         command accepts log-options. It would be nice if the completion for this\n    @@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n     -\tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n      \tlocal subcommands='push list show apply clear drop pop create branch'\n      \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n    - \tlocal stash_idx=\"$(__git_find_on_cmdline --show-idx stash)\"\n    - \tstash_idx=\"${stash_idx% *}\"\n    - \n     -\tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n     -\t\tsubcommand=\"push\"\n     -\tfi\n    ++\n      \tif [ -z \"$subcommand\" ]; then\n     -\t\tcase \"$cur\" in\n     -\t\t--*)\n     -\t\t\t__gitcomp \"$save_opts\"\n    -+\t\tcase \"$((cword - stash_idx)),$cur\" in\n    ++\t\tcase \"$((cword - __git_subcommand_idx)),$cur\" in\n     +\t\t*,--*)\n     +\t\t\t__gitcomp_builtin stash_push\n      \t\t\t;;\n    @@ contrib/completion/git-completion.bash: _git_stash ()\n     +\t\t__gitcomp_builtin stash_branch\n      \t\t;;\n      \tbranch,*)\n    - \t\tif [ $((cword - stash_idx)) -eq 2 ]; then\n    + \t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"420107","messageId":"680f3a3146355e6b09aa2e0f59471c7695954a1b.1616574955.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1616574955.git.liu.denton@gmail.com","subject":"[PATCH v2 3/3] git-completion.bash: use __gitcomp_builtin() in _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-24T08:36:29Z","receivedAt":"2021-03-24T08:37:42Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"The completion for 'git stash' has not changed in a major way since it\nwas converted from shell script to builtin. Now that it's a builtin, we\ncan take advantage of the groundwork laid out by parse-options and use\nthe generated options.\n\nRewrite _git_stash() to take use __gitcomp_builtin() to generate\ncompletions for subcommands.\n\nThe main `git stash` command does not take any arguments directly. If no\nsubcommand is given, it automatically defaults to `git stash push`. This\nmeans that we can simplify the logic for when no subcommands have been\ngiven yet. We only have to offer subcommand completions when we're\ncompleting a non-option after \"stash\".\n\nOne area that this patch could improve upon is that the `git stash list`\ncommand accepts log-options. It would be nice if the completion for this\nwere unified with that of _git_log() and _git_show() which would allow\ncompletions to be provided for options such as `--pretty` but that is\noutside the scope of this patch.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 42 ++++++++++++--------------\n 1 file changed, 20 insertions(+), 22 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8d4d8cc0fe..c926ca26c6 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3013,26 +3013,19 @@ _git_sparse_checkout ()\n \n _git_stash ()\n {\n-\tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n \tlocal subcommands='push list show apply clear drop pop create branch'\n \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n-\tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n-\t\tsubcommand=\"push\"\n-\tfi\n+\n \tif [ -z \"$subcommand\" ]; then\n-\t\tcase \"$cur\" in\n-\t\t--*)\n-\t\t\t__gitcomp \"$save_opts\"\n+\t\tcase \"$((cword - __git_subcommand_idx)),$cur\" in\n+\t\t*,--*)\n+\t\t\t__gitcomp_builtin stash_push\n \t\t\t;;\n-\t\tsa*)\n-\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n-\t\t\t\t__gitcomp \"save\"\n-\t\t\tfi\n+\t\t1,sa*)\n+\t\t\t__gitcomp \"save\"\n \t\t\t;;\n-\t\t*)\n-\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n-\t\t\t\t__gitcomp \"$subcommands\"\n-\t\t\tfi\n+\t\t1,*)\n+\t\t\t__gitcomp \"$subcommands\"\n \t\t\t;;\n \t\tesac\n \t\treturn\n@@ -3040,24 +3033,29 @@ _git_stash ()\n \n \tcase \"$subcommand,$cur\" in\n \tpush,--*)\n-\t\t__gitcomp \"$save_opts --message\"\n+\t\t__gitcomp_builtin stash_push\n \t\t;;\n \tsave,--*)\n-\t\t__gitcomp \"$save_opts\"\n+\t\t__gitcomp_builtin stash_save\n \t\t;;\n-\tapply,--*|pop,--*)\n-\t\t__gitcomp \"--index --quiet\"\n+\tpop,--*)\n+\t\t__gitcomp_builtin stash_pop\n+\t\t;;\n+\tapply,--*)\n+\t\t__gitcomp_builtin stash_apply\n \t\t;;\n \tdrop,--*)\n-\t\t__gitcomp \"--quiet\"\n+\t\t__gitcomp_builtin stash_drop\n \t\t;;\n \tlist,--*)\n-\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t# NEEDSWORK: can we somehow unify this with the options in _git_log() and _git_show()\n+\t\t__gitcomp_builtin stash_list \"$__git_log_common_options $__git_diff_common_options\"\n \t\t;;\n \tshow,--*)\n-\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t__gitcomp_builtin stash_show \"$__git_diff_common_options\"\n \t\t;;\n \tbranch,--*)\n+\t\t__gitcomp_builtin stash_branch\n \t\t;;\n \tbranch,*)\n \t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"420108","messageId":"430d5acf972f39aa8cfc9b266dd658aabcf1babb.1616574955.git.liu.denton@gmail.com","threadId":"55325","inReplyTo":"cover.1616574955.git.liu.denton@gmail.com","subject":"[PATCH v2 2/3] git-completion.bash: extract from else in _git_stash()","fromName":"Denton Liu","fromEmail":"liu.denton@gmail.com","sentAt":"2021-03-24T08:36:28Z","receivedAt":"2021-03-24T08:37:42Z","isPatch":true,"sender":{"key":"liu.denton@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9620836?v=4"},"body":"To save a level of indentation, perform an early return in the \"if\" arm\nso we can move the \"else\" code out of the block.\n\nSigned-off-by: Denton Liu <liu.denton@gmail.com>\n---\n contrib/completion/git-completion.bash | 73 +++++++++++++-------------\n 1 file changed, 37 insertions(+), 36 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex a2f1b5e916..8d4d8cc0fe 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3035,44 +3035,45 @@ _git_stash ()\n \t\t\tfi\n \t\t\t;;\n \t\tesac\n-\telse\n-\t\tcase \"$subcommand,$cur\" in\n-\t\tpush,--*)\n-\t\t\t__gitcomp \"$save_opts --message\"\n-\t\t\t;;\n-\t\tsave,--*)\n-\t\t\t__gitcomp \"$save_opts\"\n-\t\t\t;;\n-\t\tapply,--*|pop,--*)\n-\t\t\t__gitcomp \"--index --quiet\"\n-\t\t\t;;\n-\t\tdrop,--*)\n-\t\t\t__gitcomp \"--quiet\"\n-\t\t\t;;\n-\t\tlist,--*)\n-\t\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n-\t\t\t;;\n-\t\tshow,--*)\n-\t\t\t__gitcomp \"$__git_diff_common_options\"\n-\t\t\t;;\n-\t\tbranch,--*)\n-\t\t\t;;\n-\t\tbranch,*)\n-\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n-\t\t\t\t__git_complete_refs\n-\t\t\telse\n-\t\t\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n-\t\t\tfi\n-\t\t\t;;\n-\t\tshow,*|apply,*|drop,*|pop,*)\n+\t\treturn\n+\tfi\n+\n+\tcase \"$subcommand,$cur\" in\n+\tpush,--*)\n+\t\t__gitcomp \"$save_opts --message\"\n+\t\t;;\n+\tsave,--*)\n+\t\t__gitcomp \"$save_opts\"\n+\t\t;;\n+\tapply,--*|pop,--*)\n+\t\t__gitcomp \"--index --quiet\"\n+\t\t;;\n+\tdrop,--*)\n+\t\t__gitcomp \"--quiet\"\n+\t\t;;\n+\tlist,--*)\n+\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t;;\n+\tshow,--*)\n+\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t;;\n+\tbranch,--*)\n+\t\t;;\n+\tbranch,*)\n+\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n+\t\t\t__git_complete_refs\n+\t\telse\n \t\t\t__gitcomp_nl \"$(__git stash list \\\n \t\t\t\t\t| sed -n -e 's/:.*//p')\"\n-\t\t\t;;\n-\t\t*)\n-\t\t\t;;\n-\t\tesac\n-\tfi\n+\t\tfi\n+\t\t;;\n+\tshow,*|apply,*|drop,*|pop,*)\n+\t\t__gitcomp_nl \"$(__git stash list \\\n+\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t;;\n+\t*)\n+\t\t;;\n+\tesac\n }\n \n _git_submodule ()\n-- \n2.31.0.rc2.261.g7f71774620\n\n"},{"id":"420307","messageId":"20210327183554.GD2271@szeder.dev","threadId":"55325","inReplyTo":"e4aa3e8cd7f64512ce0d72906f4d15f1f0dc0a60.1616574955.git.liu.denton@gmail.com","subject":"Re: [PATCH v2 1/3] git-completion.bash: pass $__git_subcommand_idx from __git_main()","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2021-03-27T18:35:54Z","receivedAt":"2021-03-27T18:37:00Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Nit: I don't like the word \"pass\" in the subject line, because\nyou don't actually \"pass\" that variable as a parameter, but simly set\nit, and it will be visible in all called functions, because that's how\nshell variables work.\n\nOn Wed, Mar 24, 2021 at 01:36:27AM -0700, Denton Liu wrote:\n> Many completion functions perform hardcoded comparisons with $cword.\n> This fails in the case where the main git command is given arguments\n> (e.g. `git -C . bundle<TAB>` would fail to complete its subcommands).\n\nIt's not just the hardcoded comparison with $cword, but the hardcoded\nindices into the $words array that causes these problems:\n\n> Even _git_worktree(), which uses __git_find_on_cmdline(), could still\n> fail. With something like `git -C add worktree move<TAB>`, the\n> subcommand would be incorrectly identified as \"add\" instead of \"move\".\n> \n> Assign $__git_subcommand_idx in __git_main(), where the git subcommand\n\nIn 'git -C add worktree move this there' we invoke the 'worktree'\ncommand's 'move' subcommand.  Therefore, this variable should be\ncalled $__git_command_idx.  Or perhaps $__git_cmd_idx, to spare some\nkeystrokes without sacrificing readability?\n\n> is actually found and the corresponding completion function is called.\n> Use this variable to replace hardcoded comparisons with $cword.\n> \n> Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 23 +++++++++++------------\n>  1 file changed, 11 insertions(+), 12 deletions(-)\n\nThis patch leaves a couple of accesses to $words and $cword unchanged,\nthough they still suffer from the same issues and should be changed,\ne.g.:\n\n__git_complete_remote_or_refspec() assumes that ${words[1]} is the\ncommand and starts looking for options starting at index 2, so e.g.\n'git fetch <TAB>' lists configured remotes, but 'git -C . fetch <TAB>'\ndoesn't.\n\n_git_branch() is curious, because, just like the \"main\" 'git' command,\n'git branch' has '-c' and '-C' options, and as a result 'git branch\no<TAB>' lists branches from 'origin', but 'git -c foo.bar=baz -C .\nbranch o<TAB>' doesn't.\n\nIt's debatable whether __git_find_on_cmdline() and its friends should\nbe changed.  If we only look at the function's name, then no, because\nit implicitly implies that it searches through the whole command line.\nHowever, if we look at how we actually use it, then we'll find that we\nonly use it to check for the presence of subcommands or certain\noptions of a command or subcommand.  This means that we only want to\nsearch the words following the command, but since it starts its scan\nat ${words[1]}, it leads to that issue with 'git worktree' that you\ndescribed in the commit message, but it affects all other commands\nwith subcommands as well.\n\nI haven't looked closely at the other cases, but I'm inclinened to\nthink that all _git_cmd() functions and any helper functions invoked\nby them should only concern themselves with words after the git\ncommand.\n\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 7dc6cd8eb8..a2f1b5e916 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -1474,12 +1474,12 @@ _git_branch ()\n>  \n>  _git_bundle ()\n>  {\n> -\tlocal cmd=\"${words[2]}\"\n> +\tlocal cmd=\"${words[__git_subcommand_idx+1]}\"\n>  \tcase \"$cword\" in\n> -\t2)\n> +\t$((__git_subcommand_idx+1)))\n>  \t\t__gitcomp \"create list-heads verify unbundle\"\n>  \t\t;;\n> -\t3)\n> +\t$((__git_subcommand_idx+2)))\n>  \t\t# looking for a file\n>  \t\t;;\n>  \t*)\n> @@ -1894,7 +1894,7 @@ _git_grep ()\n>  \tesac\n>  \n>  \tcase \"$cword,$prev\" in\n> -\t2,*|*,-*)\n> +\t$((__git_subcommand_idx+1)),*|*,-*)\n>  \t\t__git_complete_symbol && return\n>  \t\t;;\n>  \tesac\n> @@ -3058,7 +3058,7 @@ _git_stash ()\n>  \t\tbranch,--*)\n>  \t\t\t;;\n>  \t\tbranch,*)\n> -\t\t\tif [ $cword -eq 3 ]; then\n> +\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n>  \t\t\t\t__git_complete_refs\n>  \t\t\telse\n>  \t\t\t\t__gitcomp_nl \"$(__git stash list \\\n> @@ -3277,11 +3277,9 @@ __git_complete_worktree_paths ()\n>  _git_worktree ()\n>  {\n>  \tlocal subcommands=\"add list lock move prune remove unlock\"\n> -\tlocal subcommand subcommand_idx\n> +\tlocal subcommand\n>  \n> -\tsubcommand=\"$(__git_find_on_cmdline --show-idx \"$subcommands\")\"\n> -\tsubcommand_idx=\"${subcommand% *}\"\n> -\tsubcommand=\"${subcommand#* }\"\n> +\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>  \n>  \tcase \"$subcommand,$cur\" in\n>  \t,*)\n> @@ -3306,7 +3304,7 @@ _git_worktree ()\n>  \t\t\t# be either the 'add' subcommand, the unstuck\n>  \t\t\t# argument of an option (e.g. branch for -b|-B), or\n>  \t\t\t# the path for the new worktree.\n> -\t\t\tif [ $cword -eq $((subcommand_idx+1)) ]; then\n> +\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n>  \t\t\t\t# Right after the 'add' subcommand: have to\n>  \t\t\t\t# complete the path, so fall back to Bash\n>  \t\t\t\t# filename completion.\n> @@ -3330,7 +3328,7 @@ _git_worktree ()\n>  \t\t__git_complete_worktree_paths\n>  \t\t;;\n>  \tmove,*)\n> -\t\tif [ $cword -eq $((subcommand_idx+1)) ]; then\n> +\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n>  \t\t\t# The first parameter must be an existing working\n>  \t\t\t# tree to be moved.\n>  \t\t\t__git_complete_worktree_paths\n\nI don't like these changes to _git_worktree(), because they implicitly\nassume that 'git worktree' doesn't have any --options, and it would\nthen start to misbehave if we added one.\n\nAnd these changes wouldn't be necessary if __git_find_on_cmdline()\nstarted its search at $__git_cmd_idx instead of at ${words[1]}.\n\n> @@ -3398,6 +3396,7 @@ __git_main ()\n>  {\n>  \tlocal i c=1 command __git_dir __git_repo_path\n>  \tlocal __git_C_args C_args_count=0\n> +\tlocal __git_subcommand_idx\n>  \n>  \twhile [ $c -lt $cword ]; do\n>  \t\ti=\"${words[c]}\"\n> @@ -3412,7 +3411,7 @@ __git_main ()\n>  \t\t\t__git_C_args[C_args_count++]=\"${words[c]}\"\n>  \t\t\t;;\n>  \t\t-*) ;;\n> -\t\t*) command=\"$i\"; break ;;\n> +\t\t*) command=\"$i\"; __git_subcommand_idx=\"$c\"; break ;;\n\nSee what variable is $i assigned to?  $command, not $subcommand.\n\n>  \t\tesac\n>  \t\t((c++))\n>  \tdone\n> -- \n> 2.31.0.rc2.261.g7f71774620\n> \n"},{"id":"420379","messageId":"20210328103057.GE2271@szeder.dev","threadId":"55325","inReplyTo":"430d5acf972f39aa8cfc9b266dd658aabcf1babb.1616574955.git.liu.denton@gmail.com","subject":"Re: [PATCH v2 2/3] git-completion.bash: extract from else in _git_stash()","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2021-03-28T10:30:57Z","receivedAt":"2021-03-28T10:32:36Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Wed, Mar 24, 2021 at 01:36:28AM -0700, Denton Liu wrote:\n> To save a level of indentation, perform an early return in the \"if\" arm\n> so we can move the \"else\" code out of the block.\n> \n> Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 73 +++++++++++++-------------\n>  1 file changed, 37 insertions(+), 36 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index a2f1b5e916..8d4d8cc0fe 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -3035,44 +3035,45 @@ _git_stash ()\n\nThat \"if arm\" mentioned in the commit message outside the patch\ncontext looks like this:\n\n        if [ -z \"$subcommand\" ]; then\n                case \"$cur\" in\n                [ handle the cases when there is no subcommand]\n\nSo we could simplify this further dropping that \"if\" completely, and\nunify the two case blocks from the if and else branches like this:\n\n        case \"$subcommand,$cur\" in\n        [ handle the cases without a subcommand ]\n        ,--*)  [ ... ]\n        [ ... ]\n        [ handle the casese with a subcommand, just like you did in\n          this patch ]\n        esac\n\nI think this would also make the thid patch a bit simpler.\n\n>  \t\t\tfi\n>  \t\t\t;;\n>  \t\tesac\n> -\telse\n> -\t\tcase \"$subcommand,$cur\" in\n> -\t\tpush,--*)\n> -\t\t\t__gitcomp \"$save_opts --message\"\n> -\t\t\t;;\n> -\t\tsave,--*)\n> -\t\t\t__gitcomp \"$save_opts\"\n> -\t\t\t;;\n> -\t\tapply,--*|pop,--*)\n> -\t\t\t__gitcomp \"--index --quiet\"\n> -\t\t\t;;\n> -\t\tdrop,--*)\n> -\t\t\t__gitcomp \"--quiet\"\n> -\t\t\t;;\n> -\t\tlist,--*)\n> -\t\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n> -\t\t\t;;\n> -\t\tshow,--*)\n> -\t\t\t__gitcomp \"$__git_diff_common_options\"\n> -\t\t\t;;\n> -\t\tbranch,--*)\n> -\t\t\t;;\n> -\t\tbranch,*)\n> -\t\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n> -\t\t\t\t__git_complete_refs\n> -\t\t\telse\n> -\t\t\t\t__gitcomp_nl \"$(__git stash list \\\n> -\t\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n> -\t\t\tfi\n> -\t\t\t;;\n> -\t\tshow,*|apply,*|drop,*|pop,*)\n> +\t\treturn\n> +\tfi\n> +\n> +\tcase \"$subcommand,$cur\" in\n> +\tpush,--*)\n> +\t\t__gitcomp \"$save_opts --message\"\n> +\t\t;;\n> +\tsave,--*)\n> +\t\t__gitcomp \"$save_opts\"\n> +\t\t;;\n> +\tapply,--*|pop,--*)\n> +\t\t__gitcomp \"--index --quiet\"\n> +\t\t;;\n> +\tdrop,--*)\n> +\t\t__gitcomp \"--quiet\"\n> +\t\t;;\n> +\tlist,--*)\n> +\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n> +\t\t;;\n> +\tshow,--*)\n> +\t\t__gitcomp \"$__git_diff_common_options\"\n> +\t\t;;\n> +\tbranch,--*)\n> +\t\t;;\n> +\tbranch,*)\n> +\t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n> +\t\t\t__git_complete_refs\n> +\t\telse\n>  \t\t\t__gitcomp_nl \"$(__git stash list \\\n>  \t\t\t\t\t| sed -n -e 's/:.*//p')\"\n> -\t\t\t;;\n> -\t\t*)\n> -\t\t\t;;\n> -\t\tesac\n> -\tfi\n> +\t\tfi\n> +\t\t;;\n> +\tshow,*|apply,*|drop,*|pop,*)\n> +\t\t__gitcomp_nl \"$(__git stash list \\\n> +\t\t\t\t| sed -n -e 's/:.*//p')\"\n> +\t\t;;\n> +\t*)\n> +\t\t;;\n> +\tesac\n>  }\n>  \n>  _git_submodule ()\n> -- \n> 2.31.0.rc2.261.g7f71774620\n> \n"},{"id":"420380","messageId":"20210328103134.GF2271@szeder.dev","threadId":"55325","inReplyTo":"e4aa3e8cd7f64512ce0d72906f4d15f1f0dc0a60.1616574955.git.liu.denton@gmail.com","subject":"Re: [PATCH v2 1/3] git-completion.bash: pass $__git_subcommand_idx from __git_main()","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2021-03-28T10:31:34Z","receivedAt":"2021-03-28T10:32:36Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Wed, Mar 24, 2021 at 01:36:27AM -0700, Denton Liu wrote:\n> @@ -3412,7 +3411,7 @@ __git_main ()\n>  \t\t\t__git_C_args[C_args_count++]=\"${words[c]}\"\n>  \t\t\t;;\n>  \t\t-*) ;;\n> -\t\t*) command=\"$i\"; break ;;\n> +\t\t*) command=\"$i\"; __git_subcommand_idx=\"$c\"; break ;;\n\nPlease put each of these statements on separate lines.\n\n>  \t\tesac\n>  \t\t((c++))\n>  \tdone\n> -- \n> 2.31.0.rc2.261.g7f71774620\n> \n"},{"id":"420382","messageId":"20210328110427.GG2271@szeder.dev","threadId":"55325","inReplyTo":"680f3a3146355e6b09aa2e0f59471c7695954a1b.1616574955.git.liu.denton@gmail.com","subject":"Re: [PATCH v2 3/3] git-completion.bash: use __gitcomp_builtin() in _git_stash()","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2021-03-28T11:04:27Z","receivedAt":"2021-03-28T11:05:44Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Wed, Mar 24, 2021 at 01:36:29AM -0700, Denton Liu wrote:\n> The completion for 'git stash' has not changed in a major way since it\n> was converted from shell script to builtin. Now that it's a builtin, we\n> can take advantage of the groundwork laid out by parse-options and use\n> the generated options.\n> \n> Rewrite _git_stash() to take use __gitcomp_builtin() to generate\n> completions for subcommands.\n> \n> The main `git stash` command does not take any arguments directly. If no\n> subcommand is given, it automatically defaults to `git stash push`. This\n> means that we can simplify the logic for when no subcommands have been\n> given yet. We only have to offer subcommand completions when we're\n> completing a non-option after \"stash\".\n> \n> One area that this patch could improve upon is that the `git stash list`\n> command accepts log-options. It would be nice if the completion for this\n> were unified with that of _git_log() and _git_show() which would allow\n> completions to be provided for options such as `--pretty` but that is\n> outside the scope of this patch.\n> \n> Signed-off-by: Denton Liu <liu.denton@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 42 ++++++++++++--------------\n>  1 file changed, 20 insertions(+), 22 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 8d4d8cc0fe..c926ca26c6 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -3013,26 +3013,19 @@ _git_sparse_checkout ()\n>  \n>  _git_stash ()\n>  {\n> -\tlocal save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'\n>  \tlocal subcommands='push list show apply clear drop pop create branch'\n>  \tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n> -\tif [ -z \"$subcommand\" -a -n \"$(__git_find_on_cmdline \"-p\")\" ]; then\n> -\t\tsubcommand=\"push\"\n> -\tfi\n\nI think it would be better to keep this condition ...\n\n> +\n>  \tif [ -z \"$subcommand\" ]; then\n> -\t\tcase \"$cur\" in\n> -\t\t--*)\n> -\t\t\t__gitcomp \"$save_opts\"\n> +\t\tcase \"$((cword - __git_subcommand_idx)),$cur\" in\n\n... and not bring in such magic with the indices here and ...\n\n> +\t\t*,--*)\n> +\t\t\t__gitcomp_builtin stash_push\n>  \t\t\t;;\n> -\t\tsa*)\n> -\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n> -\t\t\t\t__gitcomp \"save\"\n> -\t\t\tfi\n> +\t\t1,sa*)\n> +\t\t\t__gitcomp \"save\"\n>  \t\t\t;;\n> -\t\t*)\n> -\t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n> -\t\t\t\t__gitcomp \"$subcommands\"\n> -\t\t\tfi\n> +\t\t1,*)\n> +\t\t\t__gitcomp \"$subcommands\"\n\n... here in these two case arms, but instead handle the cases both\nwith and without a subcommand in a unified case statement as I\nsuggested in reply to the previous patch.\n\n>  \t\t\t;;\n>  \t\tesac\n>  \t\treturn\n> @@ -3040,24 +3033,29 @@ _git_stash ()\n>  \n>  \tcase \"$subcommand,$cur\" in\n>  \tpush,--*)\n> -\t\t__gitcomp \"$save_opts --message\"\n> +\t\t__gitcomp_builtin stash_push\n>  \t\t;;\n>  \tsave,--*)\n> -\t\t__gitcomp \"$save_opts\"\n> +\t\t__gitcomp_builtin stash_save\n>  \t\t;;\n> -\tapply,--*|pop,--*)\n> -\t\t__gitcomp \"--index --quiet\"\n> +\tpop,--*)\n> +\t\t__gitcomp_builtin stash_pop\n> +\t\t;;\n> +\tapply,--*)\n> +\t\t__gitcomp_builtin stash_apply\n>  \t\t;;\n>  \tdrop,--*)\n> -\t\t__gitcomp \"--quiet\"\n> +\t\t__gitcomp_builtin stash_drop\n>  \t\t;;\n\nThese case arms are still quite repetitive, and could be handled by a\nsingle arm like this:\n\n        *,--*)\n                __gitcomp_builtin stash_$subcommand\n                ;;\n\nOf course the more specific 'list,--*' and 'show,--*' cases should be\nhandled before.\n\nThe end result would look something like this (taken from a WIP patch\nseries of mine, which has been in a WIP state for about a year and a\nhalf now...):\n\n  https://github.com/szeder/git/commit/83a0e138767040280750062c5c0d43886796fcb1\n\n\n>  \tlist,--*)\n> -\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n> +\t\t# NEEDSWORK: can we somehow unify this with the options in _git_log() and _git_show()\n> +\t\t__gitcomp_builtin stash_list \"$__git_log_common_options $__git_diff_common_options\"\n>  \t\t;;\n>  \tshow,--*)\n> -\t\t__gitcomp \"$__git_diff_common_options\"\n> +\t\t__gitcomp_builtin stash_show \"$__git_diff_common_options\"\n>  \t\t;;\n>  \tbranch,--*)\n> +\t\t__gitcomp_builtin stash_branch\n>  \t\t;;\n>  \tbranch,*)\n>  \t\tif [ $cword -eq $((__git_subcommand_idx+2)) ]; then\n> -- \n> 2.31.0.rc2.261.g7f71774620\n> \n"}]}