{"thread":{"id":"60795","subject":"[PATCH 0/4] completion for git-reflog show","startedAt":"2024-01-26T12:46:23Z","lastAt":"2024-03-02T15:52:29Z","messageCount":22,"participants":["Rubén Justo","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"487405","messageId":"98daf977-dbad-4d3b-a293-6a769895088f@gmail.com","threadId":"60795","inReplyTo":null,"subject":"[PATCH 0/4] completion for git-reflog show","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T12:46:15Z","receivedAt":"2024-01-26T12:46:23Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"When no subcommand is specified to \"reflog\" we assume \"show\" [1]:\n\n    $ git reflog -h\n    usage: git reflog [show] [<log-options>] [<ref>]\n    ...\n\nWe are not completing correctly this implicit uses of \"show\":\n\nWith ...\n\n    $ git checkout -b default\n\n... we are not completing \"default\":\n\n    $ git reflog def<TAB><TAB>\n\nAnd we are incorrectly returning the \"subcommands\" when:\n\n    $ git reflog default <TAB><TAB>\n    delete expire show\n\nThis series fixes this and also adds completion for <log-options> in\n\"reflog show\", so that the user can easily discover uses like:\n\n   $ git reflog --since=1.day.ago\n\n  1. cf39f54efc (git reflog show, 2007-02-08)\n\nRubén Justo (4):\n  completion: introduce __gitcomp_subcommand\n  completion: introduce __git_find_subcommand\n  completion: reflog with implicit \"show\"\n  completion: reflog show <log-options>\n\n contrib/completion/git-completion.bash | 63 +++++++++++++++++++++++---\n t/t9902-completion.sh                  | 11 +++++\n 2 files changed, 68 insertions(+), 6 deletions(-)\n\n-- \n2.43.0\n"},{"id":"487406","messageId":"8c902c53-815d-43c2-8ba9-8144d8884804@gmail.com","threadId":"60795","inReplyTo":"98daf977-dbad-4d3b-a293-6a769895088f@gmail.com","subject":"[PATCH 1/4] completion: introduce __gitcomp_subcommand","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T12:51:27Z","receivedAt":"2024-01-26T12:51:42Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"Let's have a function to complete \"subcommands\" only in the correct\nposition (right after the command), in commands that follow the syntax:\n\n    git <command> <subcommand>\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 21 +++++++++++++++++++++\n 1 file changed, 21 insertions(+)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8c40ade494..916e137021 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -554,6 +554,27 @@ __gitcomp_file ()\n \ttrue\n }\n \n+# Completion for subcommands in commands that follow the syntax:\n+#\n+#    git <command> <subcommand>\n+#\n+# 1: List of possible completion words.\n+# Returns false if the current word is not a possible subcommand\n+# (possitioned after the command), or if no option is found in\n+# the list provided.\n+__gitcomp_subcommand ()\n+{\n+\tlocal subcommands=\"$1\"\n+\n+\tif [ $cword -eq $(($__git_cmd_idx + 1)) ]; then\n+\t\t__gitcomp \"$subcommands\"\n+\n+\t\ttest -n \"$COMPREPLY\"\n+\telse\n+\t\tfalse\n+\tfi\n+}\n+\n # Execute 'git ls-files', unless the --committable option is specified, in\n # which case it runs 'git diff-index' to find out the files that can be\n # committed.  It return paths relative to the directory specified in the first\n-- \n2.43.0\n\n"},{"id":"487407","messageId":"221f88b9-fc91-479f-8d08-f530796e2d13@gmail.com","threadId":"60795","inReplyTo":"98daf977-dbad-4d3b-a293-6a769895088f@gmail.com","subject":"[PATCH 2/4] completion: introduce __git_find_subcommand","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T12:51:46Z","receivedAt":"2024-01-26T12:51:53Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"Let's have a function to get the current subcommand when completing\ncommands that follow the syntax:\n\n    git <command> <subcommand>\n\nAs a convenience, let's allow an optional \"default subcommand\" to be\nreturned if none is found.\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 20 ++++++++++++++++++++\n 1 file changed, 20 insertions(+)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 916e137021..5f2e904b56 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -575,6 +575,26 @@ __gitcomp_subcommand ()\n \tfi\n }\n \n+# Find the current subcommand for commands that follow the syntax:\n+#\n+#    git <command> <subcommand>\n+#\n+# 1: List of possible subcommands.\n+# 2: Optional subcommand to return when none is found.\n+__git_find_subcommand ()\n+{\n+\tlocal subcommand subcommands=\"$1\" default_subcommand=\"$2\"\n+\n+\tfor subcommand in $subcommands; do\n+\t\tif [ \"$subcommand\" = \"${words[__git_cmd_idx+1]}\" ]; then\n+\t\t\techo $subcommand\n+\t\t\treturn\n+\t\tfi\n+\tdone\n+\n+\techo $default_subcommand\n+}\n+\n # Execute 'git ls-files', unless the --committable option is specified, in\n # which case it runs 'git diff-index' to find out the files that can be\n # committed.  It return paths relative to the directory specified in the first\n-- \n2.43.0\n\n"},{"id":"487408","messageId":"5991b58c-770c-4aaa-bce5-f396d9f7f16f@gmail.com","threadId":"60795","inReplyTo":"98daf977-dbad-4d3b-a293-6a769895088f@gmail.com","subject":"[PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T12:53:01Z","receivedAt":"2024-01-26T12:53:09Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"When no subcommand is specified to \"reflog\", we assume \"show\" [1]:\n\n    $ git reflog -h\n    usage: git reflog [show] [<log-options>] [<ref>]\n    ...\n\nWe are not completing correctly this implicit uses of \"show\":\n\nWith ...\n\n    $ git checkout -b default\n\n... we are not completing \"default\":\n\n    $ git reflog def<TAB><TAB>\n\nAnd we are incorrectly returning the \"subcommands\" when:\n\n    $ git reflog default <TAB><TAB>\n    delete expire show\n\nLet's use __gitcomp_subcommand to correctly handle implicit\nsubcommands.\n\n  1. cf39f54efc (git reflog show, 2007-02-08)\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 9 ++++-----\n t/t9902-completion.sh                  | 8 ++++++++\n 2 files changed, 12 insertions(+), 5 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 5f2e904b56..c41f25aa80 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2448,13 +2448,12 @@ _git_rebase ()\n _git_reflog ()\n {\n \tlocal subcommands=\"show delete expire\"\n-\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \n-\tif [ -z \"$subcommand\" ]; then\n-\t\t__gitcomp \"$subcommands\"\n-\telse\n-\t\t__git_complete_refs\n+\tif __gitcomp_subcommand \"$subcommands\"; then\n+\t\treturn\n \tfi\n+\n+\t__git_complete_refs\n }\n \n __git_send_email_confirm_options=\"always never auto cc compose\"\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex aa9a614de3..231e17f378 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2618,6 +2618,14 @@ test_expect_success 'git clone --config= - value' '\n \tEOF\n '\n \n+test_expect_success 'git reflog show' '\n+\ttest_when_finished \"git checkout -\" &&\n+\tgit checkout -b shown &&\n+\ttest_completion \"git reflog sho\" \"show \" &&\n+\ttest_completion \"git reflog show sho\" \"shown \" &&\n+\ttest_completion \"git reflog shown sho\" \"shown \"\n+'\n+\n test_expect_success 'options with value' '\n \ttest_completion \"git merge -X diff-algorithm=\" <<-\\EOF\n \n-- \n2.43.0\n\n"},{"id":"487409","messageId":"42861028-3ffa-40e2-bb97-a54cfc11ddcc@gmail.com","threadId":"60795","inReplyTo":"98daf977-dbad-4d3b-a293-6a769895088f@gmail.com","subject":"[PATCH 4/4] completion: reflog show <log-options>","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T12:53:24Z","receivedAt":"2024-01-26T12:53:30Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"Let's add completion for <log-options> in \"reflog show\" so that the user\ncan easily discover uses like:\n\n   $ git reflog --since=1.day.ago\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 13 ++++++++++++-\n t/t9902-completion.sh                  |  5 ++++-\n 2 files changed, 16 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c41f25aa80..3deb98389c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2447,12 +2447,23 @@ _git_rebase ()\n \n _git_reflog ()\n {\n-\tlocal subcommands=\"show delete expire\"\n+\tlocal subcommand subcommands=\"show delete expire\"\n \n \tif __gitcomp_subcommand \"$subcommands\"; then\n \t\treturn\n \tfi\n \n+\tsubcommand=\"$(__git_find_subcommand \"$subcommands\" \"show\")\"\n+\n+\tcase \"$subcommand,$cur\" in\n+\tshow,--*)\n+\t\t__gitcomp \"\n+\t\t\t$__git_log_common_options\n+\t\t\t\"\n+\t\treturn\n+\t\t;;\n+\tesac\n+\n \t__git_complete_refs\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 231e17f378..a74d774168 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2623,7 +2623,10 @@ test_expect_success 'git reflog show' '\n \tgit checkout -b shown &&\n \ttest_completion \"git reflog sho\" \"show \" &&\n \ttest_completion \"git reflog show sho\" \"shown \" &&\n-\ttest_completion \"git reflog shown sho\" \"shown \"\n+\ttest_completion \"git reflog shown sho\" \"shown \" &&\n+\ttest_completion \"git reflog --unt\" \"--until=\" &&\n+\ttest_completion \"git reflog show --unt\" \"--until=\" &&\n+\ttest_completion \"git reflog shown --unt\" \"--until=\"\n '\n \n test_expect_success 'options with value' '\n-- \n2.43.0\n\n"},{"id":"487417","messageId":"xmqqmsssngyz.fsf@gitster.g","threadId":"60795","inReplyTo":"8c902c53-815d-43c2-8ba9-8144d8884804@gmail.com","subject":"Re: [PATCH 1/4] completion: introduce __gitcomp_subcommand","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-01-26T17:26:44Z","receivedAt":"2024-01-26T17:26:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rubén Justo <rjusto@gmail.com> writes:\n\n> +# Completion for subcommands in commands that follow the syntax:\n> +#\n> +#    git <command> <subcommand>\n> +#\n> +# 1: List of possible completion words.\n> +# Returns false if the current word is not a possible subcommand\n> +# (possitioned after the command), or if no option is found in\n> +# the list provided.\n> +__gitcomp_subcommand ()\n> +{\n> +\tlocal subcommands=\"$1\"\n> +\n> +\tif [ $cword -eq $(($__git_cmd_idx + 1)) ]; then\n> +\t\t__gitcomp \"$subcommands\"\n> +\n> +\t\ttest -n \"$COMPREPLY\"\n> +\telse\n> +\t\tfalse\n> +\tfi\n> +}\n\n\nI am not at all familiar with the code in this file, so treat this\nas a question from somebody who do not know the calling convention\nused around here.\n\nThis helper function clobbers what was in COMPREPLY[@] before\ncalling it, from a caller's point of view.  Is it a pattern that\npotential callers in this file should already find familiar, and\nthey do not have to be reminded that they cannot rely on what they\nprepared in COMPREPLY to be preserved across a call into this\nfunction?  Otherwise I would suggest mentioning it in the helpful\ncomment before the function, but I cannot tell if such a comment is\neven needed by the intended audience, so...\n\n\n"},{"id":"487418","messageId":"xmqqh6j0ngsb.fsf@gitster.g","threadId":"60795","inReplyTo":"221f88b9-fc91-479f-8d08-f530796e2d13@gmail.com","subject":"Re: [PATCH 2/4] completion: introduce __git_find_subcommand","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-01-26T17:30:44Z","receivedAt":"2024-01-26T17:30:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rubén Justo <rjusto@gmail.com> writes:\n\n> Let's have a function to get the current subcommand when completing\n> commands that follow the syntax:\n>\n>     git <command> <subcommand>\n>\n> As a convenience, let's allow an optional \"default subcommand\" to be\n> returned if none is found.\n>\n> Signed-off-by: Rubén Justo <rjusto@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 20 ++++++++++++++++++++\n>  1 file changed, 20 insertions(+)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 916e137021..5f2e904b56 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -575,6 +575,26 @@ __gitcomp_subcommand ()\n>  \tfi\n>  }\n>  \n> +# Find the current subcommand for commands that follow the syntax:\n> +#\n> +#    git <command> <subcommand>\n> +#\n> +# 1: List of possible subcommands.\n> +# 2: Optional subcommand to return when none is found.\n> +__git_find_subcommand ()\n> +{\n> +\tlocal subcommand subcommands=\"$1\" default_subcommand=\"$2\"\n\nAre the callers expected to form \"$1\" by concatenating known tokens\nwith a space?\n\nI am just wondering if we can avoid looping, e.g.\n\n\tlocal nextword=${words[__git_cmd_idx+1]}\n\tcase \" $subcommands \" in\n\t*\" $nextword \"*)\n\t\techo \"$nextword\"\n\t\treturn\n\t\t;;\n\tesac\n\nIt hopefully should not be a huge deal either way, though. \n\n> +\n> +\tfor subcommand in $subcommands; do\n> +\t\tif [ \"$subcommand\" = \"${words[__git_cmd_idx+1]}\" ]; then\n> +\t\t\techo $subcommand\n> +\t\t\treturn\n> +\t\tfi\n> +\tdone\n> +\n> +\techo $default_subcommand\n> +}\n> +\n>  # Execute 'git ls-files', unless the --committable option is specified, in\n>  # which case it runs 'git diff-index' to find out the files that can be\n>  # committed.  It return paths relative to the directory specified in the first\n"},{"id":"487419","messageId":"xmqq8r4cnfju.fsf@gitster.g","threadId":"60795","inReplyTo":"5991b58c-770c-4aaa-bce5-f396d9f7f16f@gmail.com","subject":"Re: [PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-01-26T17:57:25Z","receivedAt":"2024-01-26T17:57:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rubén Justo <rjusto@gmail.com> writes:\n\n> When no subcommand is specified to \"reflog\", we assume \"show\" [1]:\n>\n>     $ git reflog -h\n>     usage: git reflog [show] [<log-options>] [<ref>]\n>     ...\n>\n> We are not completing correctly this implicit uses of \"show\":\n>\n> With ...\n>\n>     $ git checkout -b default\n>\n> ... we are not completing \"default\":\n>\n>     $ git reflog def<TAB><TAB>\n>\n> And we are incorrectly returning the \"subcommands\" when:\n>\n>     $ git reflog default <TAB><TAB>\n>     delete expire show\n>\n> Let's use __gitcomp_subcommand to correctly handle implicit\n> subcommands.\n\nAs with a good bug report, if you are showing an \"incorrect\"\nbehaviour, you should also illustrate what you think is the\n\"correct\" behaviour (see below).\n\n>   1. cf39f54efc (git reflog show, 2007-02-08)\n>\n> Signed-off-by: Rubén Justo <rjusto@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 9 ++++-----\n>  t/t9902-completion.sh                  | 8 ++++++++\n>  2 files changed, 12 insertions(+), 5 deletions(-)\n>\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 5f2e904b56..c41f25aa80 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2448,13 +2448,12 @@ _git_rebase ()\n>  _git_reflog ()\n>  {\n>  \tlocal subcommands=\"show delete expire\"\n> -\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>  \n> -\tif [ -z \"$subcommand\" ]; then\n> -\t\t__gitcomp \"$subcommands\"\n> -\telse\n> -\t\t__git_complete_refs\n> +\tif __gitcomp_subcommand \"$subcommands\"; then\n> +\t\treturn\n>  \tfi\n> +\n> +\t__git_complete_refs\n>  }\n\nSo, when we see something that could be a subcommand we complete it\nas a subcommand and return.  In your example, how should\n\n    $ git reflog def<TAB>\n\nwork?  We try to see if there is a subcommand that begins with\n\"def\", we see nothing matching, and then run __git_complete_refs?\nWhat if the branch you created earlier were not named \"default\" but,\nsay, \"delmonte\", and you did \"git reflog del<TAB>\"?  Shouldn't the\nuser be offered \"delete\" and \"delmonte\" as potential completions?\n\n>  __git_send_email_confirm_options=\"always never auto cc compose\"\n> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> index aa9a614de3..231e17f378 100755\n> --- a/t/t9902-completion.sh\n> +++ b/t/t9902-completion.sh\n> @@ -2618,6 +2618,14 @@ test_expect_success 'git clone --config= - value' '\n>  \tEOF\n>  '\n>  \n> +test_expect_success 'git reflog show' '\n> +\ttest_when_finished \"git checkout -\" &&\n> +\tgit checkout -b shown &&\n> +\ttest_completion \"git reflog sho\" \"show \" &&\n\nIOW, shouldn't this offer both show and shown?\n\n> +\ttest_completion \"git reflog show sho\" \"shown \" &&\n> +\ttest_completion \"git reflog shown sho\" \"shown \"\n> +'\n> +\n>  test_expect_success 'options with value' '\n>  \ttest_completion \"git merge -X diff-algorithm=\" <<-\\EOF\n"},{"id":"487422","messageId":"48717a57-42ad-4c00-bdd5-c23c0f3ccbe9@gmail.com","threadId":"60795","inReplyTo":"xmqqmsssngyz.fsf@gitster.g","subject":"Re: [PATCH 1/4] completion: introduce __gitcomp_subcommand","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T20:09:51Z","receivedAt":"2024-01-26T20:10:01Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"On 26-ene-2024 09:26:44, Junio C Hamano wrote:\n> Rubén Justo <rjusto@gmail.com> writes:\n> \n> > +# Completion for subcommands in commands that follow the syntax:\n> > +#\n> > +#    git <command> <subcommand>\n> > +#\n> > +# 1: List of possible completion words.\n> > +# Returns false if the current word is not a possible subcommand\n> > +# (possitioned after the command), or if no option is found in\n> > +# the list provided.\n> > +__gitcomp_subcommand ()\n> > +{\n> > +\tlocal subcommands=\"$1\"\n> > +\n> > +\tif [ $cword -eq $(($__git_cmd_idx + 1)) ]; then\n> > +\t\t__gitcomp \"$subcommands\"\n> > +\n> > +\t\ttest -n \"$COMPREPLY\"\n> > +\telse\n> > +\t\tfalse\n> > +\tfi\n> > +}\n> \n> \n> I am not at all familiar with the code in this file, so treat this\n> as a question from somebody who do not know the calling convention\n> used around here.\n> \n> This helper function clobbers what was in COMPREPLY[@] before\n> calling it, from a caller's point of view.  Is it a pattern that\n> potential callers in this file should already find familiar, and\n> they do not have to be reminded that they cannot rely on what they\n> prepared in COMPREPLY to be preserved across a call into this\n> function?  Otherwise I would suggest mentioning it in the helpful\n> comment before the function, but I cannot tell if such a comment is\n> even needed by the intended audience, so...\n\nMaybe adding such a comment might suggest at first glance that we're\nworking different here than in the rest of the __gitcomp_* family of\nfunctions, which is not the intention ... I dunno.\n"},{"id":"487425","messageId":"dd106d87-3363-426a-90a2-16e1f2d04661@gmail.com","threadId":"60795","inReplyTo":"xmqq8r4cnfju.fsf@gitster.g","subject":"Re: [PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-26T20:20:07Z","receivedAt":"2024-01-26T20:20:17Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"On 26-ene-2024 09:57:25, Junio C Hamano wrote:\n> Rubén Justo <rjusto@gmail.com> writes:\n> \n> > When no subcommand is specified to \"reflog\", we assume \"show\" [1]:\n> >\n> >     $ git reflog -h\n> >     usage: git reflog [show] [<log-options>] [<ref>]\n> >     ...\n> >\n> > We are not completing correctly this implicit uses of \"show\":\n> >\n> > With ...\n> >\n> >     $ git checkout -b default\n> >\n> > ... we are not completing \"default\":\n> >\n> >     $ git reflog def<TAB><TAB>\n> >\n> > And we are incorrectly returning the \"subcommands\" when:\n> >\n> >     $ git reflog default <TAB><TAB>\n> >     delete expire show\n> >\n> > Let's use __gitcomp_subcommand to correctly handle implicit\n> > subcommands.\n> \n> As with a good bug report, if you are showing an \"incorrect\"\n> behaviour, you should also illustrate what you think is the\n> \"correct\" behaviour (see below).\n> \n> >   1. cf39f54efc (git reflog show, 2007-02-08)\n> >\n> > Signed-off-by: Rubén Justo <rjusto@gmail.com>\n> > ---\n> >  contrib/completion/git-completion.bash | 9 ++++-----\n> >  t/t9902-completion.sh                  | 8 ++++++++\n> >  2 files changed, 12 insertions(+), 5 deletions(-)\n> >\n> > diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> > index 5f2e904b56..c41f25aa80 100644\n> > --- a/contrib/completion/git-completion.bash\n> > +++ b/contrib/completion/git-completion.bash\n> > @@ -2448,13 +2448,12 @@ _git_rebase ()\n> >  _git_reflog ()\n> >  {\n> >  \tlocal subcommands=\"show delete expire\"\n> > -\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n> >  \n> > -\tif [ -z \"$subcommand\" ]; then\n> > -\t\t__gitcomp \"$subcommands\"\n> > -\telse\n> > -\t\t__git_complete_refs\n> > +\tif __gitcomp_subcommand \"$subcommands\"; then\n> > +\t\treturn\n> >  \tfi\n> > +\n> > +\t__git_complete_refs\n> >  }\n> \n> So, when we see something that could be a subcommand we complete it\n> as a subcommand and return.  In your example, how should\n> \n>     $ git reflog def<TAB>\n> \n> work?  We try to see if there is a subcommand that begins with\n> \"def\", we see nothing matching, and then run __git_complete_refs?\n> What if the branch you created earlier were not named \"default\" but,\n> say, \"delmonte\", and you did \"git reflog del<TAB>\"?  Shouldn't the\n> user be offered \"delete\" and \"delmonte\" as potential completions?\n> \n> >  __git_send_email_confirm_options=\"always never auto cc compose\"\n> > diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n> > index aa9a614de3..231e17f378 100755\n> > --- a/t/t9902-completion.sh\n> > +++ b/t/t9902-completion.sh\n> > @@ -2618,6 +2618,14 @@ test_expect_success 'git clone --config= - value' '\n> >  \tEOF\n> >  '\n> >  \n> > +test_expect_success 'git reflog show' '\n> > +\ttest_when_finished \"git checkout -\" &&\n> > +\tgit checkout -b shown &&\n> > +\ttest_completion \"git reflog sho\" \"show \" &&\n> \n> IOW, shouldn't this offer both show and shown?\n\nWhat should we do?\n\nWhen the user have a branch \"show\":\n\n   $ git checkout -b show\n   $ git reflog sho<TAB><TAB>\n\nAnd with:\n\n   $ git reflog <TAB><TAB>\n\nShould we suggest the subcommands alongside the branches?\n\nI thought about this, and it's a can of worms.  I concluded that a sane\nan instructive for the user approach is to first try the subcommands and\nif no option is found, then try the implicit \"show\".\n\nMaybe I'm overthinking it ...\n\n> \n> > +\ttest_completion \"git reflog show sho\" \"shown \" &&\n> > +\ttest_completion \"git reflog shown sho\" \"shown \"\n> > +'\n> > +\n> >  test_expect_success 'options with value' '\n> >  \ttest_completion \"git merge -X diff-algorithm=\" <<-\\EOF\n\nThanks.\n"},{"id":"487426","messageId":"xmqqsf2jn8ae.fsf@gitster.g","threadId":"60795","inReplyTo":"48717a57-42ad-4c00-bdd5-c23c0f3ccbe9@gmail.com","subject":"Re: [PATCH 1/4] completion: introduce __gitcomp_subcommand","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-01-26T20:34:17Z","receivedAt":"2024-01-26T20:34:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rubén Justo <rjusto@gmail.com> writes:\n\n> On 26-ene-2024 09:26:44, Junio C Hamano wrote:\n>> Rubén Justo <rjusto@gmail.com> writes:\n>> \n>> > +# Completion for subcommands in commands that follow the syntax:\n>> > +#\n>> > +#    git <command> <subcommand>\n>> > +#\n>> > +# 1: List of possible completion words.\n>> > +# Returns false if the current word is not a possible subcommand\n>> > +# (possitioned after the command), or if no option is found in\n>> > +# the list provided.\n>> > +__gitcomp_subcommand ()\n>> > +{\n>> > +\tlocal subcommands=\"$1\"\n>> > +\n>> > +\tif [ $cword -eq $(($__git_cmd_idx + 1)) ]; then\n>> > +\t\t__gitcomp \"$subcommands\"\n>> > +\n>> > +\t\ttest -n \"$COMPREPLY\"\n>> > +\telse\n>> > +\t\tfalse\n>> > +\tfi\n>> > +}\n>> \n>> \n>> I am not at all familiar with the code in this file, so treat this\n>> as a question from somebody who do not know the calling convention\n>> used around here.\n>> \n>> This helper function clobbers what was in COMPREPLY[@] before\n>> calling it, from a caller's point of view.  Is it a pattern that\n>> potential callers in this file should already find familiar, and\n>> they do not have to be reminded that they cannot rely on what they\n>> prepared in COMPREPLY to be preserved across a call into this\n>> function?  Otherwise I would suggest mentioning it in the helpful\n>> comment before the function, but I cannot tell if such a comment is\n>> even needed by the intended audience, so...\n>\n> Maybe adding such a comment might suggest at first glance that we're\n> working different here than in the rest of the __gitcomp_* family of\n> functions, which is not the intention ... I dunno.\n\nExactly.  That is why I asked.  If it is a norm for all these helper\nfunctions to stomp on COMPREPLY and if it is accepted as a common\npattern by developers who touch this file, then I agree it would be\nmisleading to have such a comment only to this function.\n\nTHanks.\n"},{"id":"487451","messageId":"c49d1df1-13ca-449e-a826-94be84953ece@gmail.com","threadId":"60795","inReplyTo":"xmqqh6j0ngsb.fsf@gitster.g","subject":"Re: [PATCH 2/4] completion: introduce __git_find_subcommand","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-01-27T13:20:21Z","receivedAt":"2024-01-27T13:20:32Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"On 26-ene-2024 09:30:44, Junio C Hamano wrote:\n> Rubén Justo <rjusto@gmail.com> writes:\n> \n> > Let's have a function to get the current subcommand when completing\n> > commands that follow the syntax:\n> >\n> >     git <command> <subcommand>\n> >\n> > As a convenience, let's allow an optional \"default subcommand\" to be\n> > returned if none is found.\n> >\n> > Signed-off-by: Rubén Justo <rjusto@gmail.com>\n> > ---\n> >  contrib/completion/git-completion.bash | 20 ++++++++++++++++++++\n> >  1 file changed, 20 insertions(+)\n> >\n> > diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> > index 916e137021..5f2e904b56 100644\n> > --- a/contrib/completion/git-completion.bash\n> > +++ b/contrib/completion/git-completion.bash\n> > @@ -575,6 +575,26 @@ __gitcomp_subcommand ()\n> >  \tfi\n> >  }\n> >  \n> > +# Find the current subcommand for commands that follow the syntax:\n> > +#\n> > +#    git <command> <subcommand>\n> > +#\n> > +# 1: List of possible subcommands.\n> > +# 2: Optional subcommand to return when none is found.\n> > +__git_find_subcommand ()\n> > +{\n> > +\tlocal subcommand subcommands=\"$1\" default_subcommand=\"$2\"\n> \n> Are the callers expected to form \"$1\" by concatenating known tokens\n> with a space?\n> \n> I am just wondering if we can avoid looping, e.g.\n> \n> \tlocal nextword=${words[__git_cmd_idx+1]}\n> \tcase \" $subcommands \" in\n> \t*\" $nextword \"*)\n> \t\techo \"$nextword\"\n> \t\treturn\n> \t\t;;\n> \tesac\n> \n\nI like the idea; and it works:\n\n     $ words=(\"a\" \"b\"); __git_cmd_idx=0; __git_find_subcommand \"a b\" \"test\"\n     b\n\n     $ : simulate that the user moves the cursor backwards\n     $ words=(\"a\" \"\" \"b\"); __git_cmd_idx=0; __git_find_subcommand \"a b\" \"test\"\n     test\n\n     $ : simulate that the user moves the cursor backwards\n     $ words=(\"a\" \" \" \"b\"); __git_cmd_idx=0; __git_find_subcommand \"a b\" \"test\"\n     test\n\nBut functions like __git_find_on_cmdline or __git-find_last_on_cmdline\nare already iterating.  I feel we should keep the loop.\n\nThank you.\n"},{"id":"489045","messageId":"xmqqwmqyr3mb.fsf@gitster.g","threadId":"60795","inReplyTo":"dd106d87-3363-426a-90a2-16e1f2d04661@gmail.com","subject":"Re: [PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-02-21T01:46:20Z","receivedAt":"2024-02-21T01:46:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rubén Justo <rjusto@gmail.com> writes:\n\n>> So, when we see something that could be a subcommand we complete it\n>> as a subcommand and return.  In your example, how should\n>> \n>>     $ git reflog def<TAB>\n>> \n>> work?  We try to see if there is a subcommand that begins with\n>> \"def\", we see nothing matching, and then run __git_complete_refs?\n>> What if the branch you created earlier were not named \"default\" but,\n>> say, \"delmonte\", and you did \"git reflog del<TAB>\"?  Shouldn't the\n>> user be offered \"delete\" and \"delmonte\" as potential completions?\n>> \n>> >  __git_send_email_confirm_options=\"always never auto cc compose\"\n>> > diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\n>> > index aa9a614de3..231e17f378 100755\n>> > --- a/t/t9902-completion.sh\n>> > +++ b/t/t9902-completion.sh\n>> > @@ -2618,6 +2618,14 @@ test_expect_success 'git clone --config= - value' '\n>> >  \tEOF\n>> >  '\n>> >  \n>> > +test_expect_success 'git reflog show' '\n>> > +\ttest_when_finished \"git checkout -\" &&\n>> > +\tgit checkout -b shown &&\n>> > +\ttest_completion \"git reflog sho\" \"show \" &&\n>> \n>> IOW, shouldn't this offer both show and shown?\n>\n> What should we do?\n\nI would imagine that we should make the above offer both \"show\"\n(because it can be what the user meant) and \"shown\" (because it can\nalso be what the user meant)?  But thinking of it again, because\n\"show\" is a prefix of \"shown\", this should offer \"show\" and then\nanother <TAB> would offer \"show\" and \"shown\".  At least, that is\nwhat I would expect from the usual bash completion behaviour, which\nwould look like:\n\n    $ mkdir /var/tmp/scratch && cd /var/tmp/scratch\n    $ : >show 2>shown\n    $ echo sho<TAB>\n\nThe <TAB> makes the above line expand to\n\n    $ echo show\n\nand place the curser immediately after 'w' (without a space after it).\nGiving another <TAB> at this point offers two possible candidates.\n\n    $ echo show<TAB>\n    show shown\n\nSo, I'd expect a similar completion to happen, i.e.\n\n    $ git reflog sho<TAB>\n-->\n    $ git reflog show\n\nbecause there are two candidates, \"show\" and \"shown\", and I can type\nanother <TAB> at that point to see the two candidates.\n\n    $ git reflog show<TAB>\n    show shown\n\nIf the branch name were \"shot\" instead of \"shown\", then the possible\nchoices would become \"show\" and \"shot\", so we'd skip one step from\nthe above and immediately get the two candidates against \"sho<TAB>\".\n\n    $ git reflog sho<TAB>\n    shot show\n\nThat is what I would expect.    \n\nThanks.\n"},{"id":"489102","messageId":"abe1c96d-48f7-4355-8688-e1fb05c67448@gmail.com","threadId":"60795","inReplyTo":"xmqqwmqyr3mb.fsf@gitster.g","subject":"Re: [PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-02-21T18:06:36Z","receivedAt":"2024-02-21T18:06:40Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"On Tue, Feb 20, 2024 at 17:46:20 -0800, Junio C Hamano wrote:\n\n>     $ git reflog sho<TAB>\n>     shot show\n> \n> That is what I would expect.    \n\nThank you for responding.\n\nOf course that's the logical expectation.\n\nHowever I'm not sure if it is sensible to offer completion for\nsub-commands mixed with branch names.\n\nFurthermore, I am also worried that such an approach implies making the\nuser pay, probably unnecessarily many times, for __git_complete_refs in\ncases such as:\n\n    $ git reflog <TAB><TAB>  ;# the user may be just exploring the sub-commands\n    $ git reflog s<TAB>      ;# the user may be lazy and just want \"show \"\n    $ git reflog show<TAB>   ;# likewise, to complete the SP\n    $ git reflog expir<TAB>  ;# how often a expir... branch is expected here?\n\nThe experienced user, if not most users, should be intuitive enough to\ncircumvent the corner cases:\n\n    $ git reflog <TAB><TAB>\n    delete expire show\n    ...\n    $ git reflog s<TAB>\n    ...\n    $ git reflog show s<TAB>\n    ...\n    $ git reflog show shot\n\nThis is why I choose to fallback to __git_complete_ref only when no\nother option is available.\n\nIf you think, or anyone else, that these concerns don't make sense, I'm\nopen to make it work as you described.\n"},{"id":"489675","messageId":"ff1c650b-5776-4881-ad0d-c39d311fa7e7@gmail.com","threadId":"60795","inReplyTo":"abe1c96d-48f7-4355-8688-e1fb05c67448@gmail.com","subject":"Re: [PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-02-29T19:00:26Z","receivedAt":"2024-02-29T19:00:29Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"On Wed, Feb 21, 2024 at 07:06:36PM +0100, Rubén Justo wrote:\n> On Tue, Feb 20, 2024 at 17:46:20 -0800, Junio C Hamano wrote:\n> \n> >     $ git reflog sho<TAB>\n> >     shot show\n> > \n> > That is what I would expect.    \n> \n> Thank you for responding.\n> \n> Of course that's the logical expectation.\n> \n> However I'm not sure if it is sensible to offer completion for\n> sub-commands mixed with branch names.\n> \n> Furthermore, I am also worried that such an approach implies making the\n> user pay, probably unnecessarily many times, for __git_complete_refs in\n> cases such as:\n> \n>     $ git reflog <TAB><TAB>  ;# the user may be just exploring the sub-commands\n>     $ git reflog s<TAB>      ;# the user may be lazy and just want \"show \"\n>     $ git reflog show<TAB>   ;# likewise, to complete the SP\n>     $ git reflog expir<TAB>  ;# how often a expir... branch is expected here?\n> \n> The experienced user, if not most users, should be intuitive enough to\n> circumvent the corner cases:\n> \n>     $ git reflog <TAB><TAB>\n>     delete expire show\n>     ...\n>     $ git reflog s<TAB>\n>     ...\n>     $ git reflog show s<TAB>\n>     ...\n>     $ git reflog show shot\n> \n> This is why I choose to fallback to __git_complete_ref only when no\n> other option is available.\n> \n> If you think, or anyone else, that these concerns don't make sense, I'm\n> open to make it work as you described.\n\nI am happy with the current iteration and I still think that mixing\nbranch names with options is a source of confusion.\n\nHowever, this topic in the latest 'What's cooking' is marked with:\n\n Expecting a reroll.\n cf. <dd106d87-3363-426a-90a2-16e1f2d04661@gmail.com>\n source: <98daf977-dbad-4d3b-a293-6a769895088f@gmail.com>\n\nI am confused about what the expectation is.\n\nConsider this message a ping as maybe the message I'm responding to has\nbeen missed.\n\nThanks.\n"},{"id":"489681","messageId":"xmqqo7bzf53v.fsf@gitster.g","threadId":"60795","inReplyTo":"ff1c650b-5776-4881-ad0d-c39d311fa7e7@gmail.com","subject":"Re: [PATCH 3/4] completion: reflog with implicit \"show\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-02-29T19:22:12Z","receivedAt":"2024-02-29T19:22:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Rubén Justo <rjusto@gmail.com> writes:\n\n> I am happy with the current iteration and I still think that mixing\n> branch names with options is a source of confusion.\n>\n> However, this topic in the latest 'What's cooking' is marked with:\n>\n>  Expecting a reroll.\n>  cf. <dd106d87-3363-426a-90a2-16e1f2d04661@gmail.com>\n>  source: <98daf977-dbad-4d3b-a293-6a769895088f@gmail.com>\n>\n> I am confused about what the expectation is.\n\nExpectation is to show both possible commands and branch names\navailable so that users with enough typing can pick from either, as\nI do see it even more confusing if only branch names (or only\ncommand names) are visible sometimes (namely, if the prefix is\nshared by both) but some other times command names (or branch names)\nare completed just fine (namely, if the prefix is unique to only one\nset of names between command names and branch names).\n\n"},{"id":"489769","messageId":"ea6c8890-9ff3-46c9-b933-6a52083b1001@gmail.com","threadId":"60795","inReplyTo":"98daf977-dbad-4d3b-a293-6a769895088f@gmail.com","subject":"[PATCH v2 0/5] completion for git-reflog show","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-02T14:30:21Z","receivedAt":"2024-03-02T14:30:31Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"This iteration has three main changes and two new commits since v2.\n\nThe changes:\n\n - The function __gitcomp_subcommand is no longer needed in this series.\n   The patch that introduced it has been removed.\n \n - The description for the behaviour we're fixing in the patch 1/5 has\n   been reworded to better explain the behaviour we're expecting.\n \n - Provide completion for both subcommands and references when the\n   expectation is such that we're not sure if the implicit subcommand\n   \"show\" is desired.\n\nAbout the two new commits:\n\nThis series is described in the last \"What's cooking\" with:\n\n The command line completion script (in contrib/) learned to\n complete \"git reflog\" better.\n\nSo, while we're here I've included two new commits, 4/5 and 5/5, that\nfit well in that description.\n\nAn important note is in the last patch, reporting the special case\nneeded for the <log-options> in the \"show\" subcommand.  This is what has\nmade me decide to include the new commits in this series.\n\nRubén Justo (5):\n  completion: reflog with implicit \"show\"\n  completion: introduce __git_find_subcommand\n  completion: reflog show <log-options>\n  completion: factor out __git_builtin\n  completion: reflog subcommands and options\n\n contrib/completion/git-completion.bash | 70 ++++++++++++++++++++++----\n t/t9902-completion.sh                  | 14 ++++++\n 2 files changed, 73 insertions(+), 11 deletions(-)\n\nRange-diff against v1:\n1:  1a76491362 < -:  ---------- completion: introduce __gitcomp_subcommand\n3:  8defb041ac ! 1:  61b9696238 completion: reflog with implicit \"show\"\n    @@ Commit message\n             usage: git reflog [show] [<log-options>] [<ref>]\n             ...\n     \n    -    We are not completing correctly this implicit uses of \"show\":\n    -\n    -    With ...\n    +    This implicit \"show\" is not being completed correctly:\n     \n             $ git checkout -b default\n    +        $ git reflog def<TAB><TAB>\n    +        ... no completion options ...\n     \n    -    ... we are not completing \"default\":\n    +    The expected result is:\n     \n    -        $ git reflog def<TAB><TAB>\n    +        $ git reflog default\n    +\n    +    This happens because we're completing references after seeing a valid\n    +    subcommand in the command line.  This prevents the implicit \"show\" from\n    +    working properly, but also introduces a new problem: it keeps offering\n    +    subcommand options when the subcommand is implicit:\n    +\n    +        $ git checkout -b explore\n    +        $ git reflog default ex<TAB>\n    +        ...\n    +        $ git reflog default expire\n     \n    -    And we are incorrectly returning the \"subcommands\" when:\n    +    The expected result is:\n     \n    -        $ git reflog default <TAB><TAB>\n    -        delete expire show\n    +        $ git reflog default explore\n     \n    -    Let's use __gitcomp_subcommand to correctly handle implicit\n    -    subcommands.\n    +    To fix this, complete references even if no subcommand is present, or in\n    +    other words when the subcommand is implicit \"show\".\n    +\n    +    Also, only include completion options for subcommands when completing\n    +    the right position in the command line.\n     \n           1. cf39f54efc (git reflog show, 2007-02-08)\n     \n    @@ contrib/completion/git-completion.bash: _git_rebase ()\n     -\t\t__gitcomp \"$subcommands\"\n     -\telse\n     -\t\t__git_complete_refs\n    -+\tif __gitcomp_subcommand \"$subcommands\"; then\n    -+\t\treturn\n    - \tfi\n    -+\n     +\t__git_complete_refs\n    ++\n    ++\tif [ $((cword - __git_cmd_idx)) -eq 1 ]; then\n    ++\t\t__gitcompappend \"$subcommands\" \"\" \"$cur\" \" \"\n    + \tfi\n      }\n      \n    - __git_send_email_confirm_options=\"always never auto cc compose\"\n     \n      ## t/t9902-completion.sh ##\n     @@ t/t9902-completion.sh: test_expect_success 'git clone --config= - value' '\n    @@ t/t9902-completion.sh: test_expect_success 'git clone --config= - value' '\n      '\n      \n     +test_expect_success 'git reflog show' '\n    -+\ttest_when_finished \"git checkout -\" &&\n    ++\ttest_when_finished \"git checkout - && git branch -d shown\" &&\n     +\tgit checkout -b shown &&\n    -+\ttest_completion \"git reflog sho\" \"show \" &&\n    ++\ttest_completion \"git reflog sho\" <<-\\EOF &&\n    ++\tshow Z\n    ++\tshown Z\n    ++\tEOF\n     +\ttest_completion \"git reflog show sho\" \"shown \" &&\n     +\ttest_completion \"git reflog shown sho\" \"shown \"\n     +'\n2:  b1aad9a667 ! 2:  b3133c69d3 completion: introduce __git_find_subcommand\n    @@ Commit message\n         Signed-off-by: Rubén Justo <rjusto@gmail.com>\n     \n      ## contrib/completion/git-completion.bash ##\n    -@@ contrib/completion/git-completion.bash: __gitcomp_subcommand ()\n    - \tfi\n    +@@ contrib/completion/git-completion.bash: __gitcomp_file ()\n    + \ttrue\n      }\n      \n     +# Find the current subcommand for commands that follow the syntax:\n4:  4d3fb1d563 ! 3:  e6e526b436 completion: reflog show <log-options>\n    @@ Commit message\n     \n      ## contrib/completion/git-completion.bash ##\n     @@ contrib/completion/git-completion.bash: _git_rebase ()\n    - \n      _git_reflog ()\n      {\n    --\tlocal subcommands=\"show delete expire\"\n    -+\tlocal subcommand subcommands=\"show delete expire\"\n    - \n    - \tif __gitcomp_subcommand \"$subcommands\"; then\n    - \t\treturn\n    - \tfi\n    - \n    -+\tsubcommand=\"$(__git_find_subcommand \"$subcommands\" \"show\")\"\n    + \tlocal subcommands=\"show delete expire\"\n    ++\tlocal subcommand=\"$(__git_find_subcommand \"$subcommands\" \"show\")\"\n     +\n     +\tcase \"$subcommand,$cur\" in\n     +\tshow,--*)\n    @@ contrib/completion/git-completion.bash: _git_rebase ()\n     +\t\treturn\n     +\t\t;;\n     +\tesac\n    -+\n    + \n      \t__git_complete_refs\n    - }\n      \n     \n      ## t/t9902-completion.sh ##\n     @@ t/t9902-completion.sh: test_expect_success 'git reflog show' '\n    - \tgit checkout -b shown &&\n    - \ttest_completion \"git reflog sho\" \"show \" &&\n    + \tshown Z\n    + \tEOF\n      \ttest_completion \"git reflog show sho\" \"shown \" &&\n     -\ttest_completion \"git reflog shown sho\" \"shown \"\n     +\ttest_completion \"git reflog shown sho\" \"shown \" &&\n-:  ---------- > 4:  dfed95d495 completion: factor out __git_builtin\n-:  ---------- > 5:  8193b7f4f9 completion: reflog subcommands and options\n-- \n2.44.0\n"},{"id":"489770","messageId":"ae0e2eaa-b7b9-4d95-8b73-c6be762341ef@gmail.com","threadId":"60795","inReplyTo":"ea6c8890-9ff3-46c9-b933-6a52083b1001@gmail.com","subject":"[PATCH v2 1/5] completion: reflog with implicit \"show\"","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-02T14:37:34Z","receivedAt":"2024-03-02T14:37:41Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"When no subcommand is specified to \"reflog\", we assume \"show\" [1]:\n\n    $ git reflog -h\n    usage: git reflog [show] [<log-options>] [<ref>]\n    ...\n\nThis implicit \"show\" is not being completed correctly:\n\n    $ git checkout -b default\n    $ git reflog def<TAB><TAB>\n    ... no completion options ...\n\nThe expected result is:\n\n    $ git reflog default\n\nThis happens because we're completing references after seeing a valid\nsubcommand in the command line.  This prevents the implicit \"show\" from\nworking properly, but also introduces a new problem: it keeps offering\nsubcommand options when the subcommand is implicit:\n\n    $ git checkout -b explore\n    $ git reflog default ex<TAB>\n    ...\n    $ git reflog default expire\n\nThe expected result is:\n\n    $ git reflog default explore\n\nTo fix this, complete references even if no subcommand is present, or in\nother words when the subcommand is implicit \"show\".\n\nAlso, only include completion options for subcommands when completing\nthe right position in the command line.\n\n  1. cf39f54efc (git reflog show, 2007-02-08)\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash |  9 ++++-----\n t/t9902-completion.sh                  | 11 +++++++++++\n 2 files changed, 15 insertions(+), 5 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8c40ade494..ff216f1c65 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2407,12 +2407,11 @@ _git_rebase ()\n _git_reflog ()\n {\n \tlocal subcommands=\"show delete expire\"\n-\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \n-\tif [ -z \"$subcommand\" ]; then\n-\t\t__gitcomp \"$subcommands\"\n-\telse\n-\t\t__git_complete_refs\n+\t__git_complete_refs\n+\n+\tif [ $((cword - __git_cmd_idx)) -eq 1 ]; then\n+\t\t__gitcompappend \"$subcommands\" \"\" \"$cur\" \" \"\n \tfi\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex aa9a614de3..dbd57e6a28 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2618,6 +2618,17 @@ test_expect_success 'git clone --config= - value' '\n \tEOF\n '\n \n+test_expect_success 'git reflog show' '\n+\ttest_when_finished \"git checkout - && git branch -d shown\" &&\n+\tgit checkout -b shown &&\n+\ttest_completion \"git reflog sho\" <<-\\EOF &&\n+\tshow Z\n+\tshown Z\n+\tEOF\n+\ttest_completion \"git reflog show sho\" \"shown \" &&\n+\ttest_completion \"git reflog shown sho\" \"shown \"\n+'\n+\n test_expect_success 'options with value' '\n \ttest_completion \"git merge -X diff-algorithm=\" <<-\\EOF\n \n-- \n2.44.0\n\n"},{"id":"489772","messageId":"27fe304d-6011-430d-8f43-7e0581566182@gmail.com","threadId":"60795","inReplyTo":"ea6c8890-9ff3-46c9-b933-6a52083b1001@gmail.com","subject":"[PATCH v2 3/5] completion: reflog show <log-options>","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-02T15:50:47Z","receivedAt":"2024-03-02T15:50:53Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"Let's add completion for <log-options> in \"reflog show\" so that the user\ncan easily discover uses like:\n\n   $ git reflog --since=1.day.ago\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 10 ++++++++++\n t/t9902-completion.sh                  |  5 ++++-\n 2 files changed, 14 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 849d191b02..dc5f73a9f3 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2427,6 +2427,16 @@ _git_rebase ()\n _git_reflog ()\n {\n \tlocal subcommands=\"show delete expire\"\n+\tlocal subcommand=\"$(__git_find_subcommand \"$subcommands\" \"show\")\"\n+\n+\tcase \"$subcommand,$cur\" in\n+\tshow,--*)\n+\t\t__gitcomp \"\n+\t\t\t$__git_log_common_options\n+\t\t\t\"\n+\t\treturn\n+\t\t;;\n+\tesac\n \n \t__git_complete_refs\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex dbd57e6a28..04f3620e5b 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2626,7 +2626,10 @@ test_expect_success 'git reflog show' '\n \tshown Z\n \tEOF\n \ttest_completion \"git reflog show sho\" \"shown \" &&\n-\ttest_completion \"git reflog shown sho\" \"shown \"\n+\ttest_completion \"git reflog shown sho\" \"shown \" &&\n+\ttest_completion \"git reflog --unt\" \"--until=\" &&\n+\ttest_completion \"git reflog show --unt\" \"--until=\" &&\n+\ttest_completion \"git reflog shown --unt\" \"--until=\"\n '\n \n test_expect_success 'options with value' '\n-- \n2.44.0\n"},{"id":"489773","messageId":"58420452-9491-4e46-8746-55afe95f41de@gmail.com","threadId":"60795","inReplyTo":"ea6c8890-9ff3-46c9-b933-6a52083b1001@gmail.com","subject":"[PATCH v2 2/5] completion: introduce __git_find_subcommand","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-02T15:51:08Z","receivedAt":"2024-03-02T15:51:14Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"Let's have a function to get the current subcommand when completing\ncommands that follow the syntax:\n\n    git <command> <subcommand>\n\nAs a convenience, let's allow an optional \"default subcommand\" to be\nreturned if none is found.\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 20 ++++++++++++++++++++\n 1 file changed, 20 insertions(+)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex ff216f1c65..849d191b02 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -554,6 +554,26 @@ __gitcomp_file ()\n \ttrue\n }\n \n+# Find the current subcommand for commands that follow the syntax:\n+#\n+#    git <command> <subcommand>\n+#\n+# 1: List of possible subcommands.\n+# 2: Optional subcommand to return when none is found.\n+__git_find_subcommand ()\n+{\n+\tlocal subcommand subcommands=\"$1\" default_subcommand=\"$2\"\n+\n+\tfor subcommand in $subcommands; do\n+\t\tif [ \"$subcommand\" = \"${words[__git_cmd_idx+1]}\" ]; then\n+\t\t\techo $subcommand\n+\t\t\treturn\n+\t\tfi\n+\tdone\n+\n+\techo $default_subcommand\n+}\n+\n # Execute 'git ls-files', unless the --committable option is specified, in\n # which case it runs 'git diff-index' to find out the files that can be\n # committed.  It return paths relative to the directory specified in the first\n-- \n2.44.0\n"},{"id":"489774","messageId":"69f1dd45-e19d-47ad-b83d-746e9f67368c@gmail.com","threadId":"60795","inReplyTo":"ea6c8890-9ff3-46c9-b933-6a52083b1001@gmail.com","subject":"[PATCH v2 4/5] completion: factor out __git_resolve_builtins","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-02T15:52:03Z","receivedAt":"2024-03-02T15:52:09Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"We're going to use the result of \"git xxx --git-completion-helper\" not\nonly for feeding COMPREPLY.\n\nTherefore, factor out the execution and the caching of its results in\n__gitcomp_builtin, to a new function __git_resolve_builtins.\n\nWhile we're here, move an important comment we have in the function to\nits header, so it gains visibility.\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n\nI've changed my mind last minute, and renamed the function to\n__git_resolve_builtins, so the subject of this patch is different\nfrom the one included in the cover letter.\n\n contrib/completion/git-completion.bash | 31 +++++++++++++++++++++-----\n 1 file changed, 25 insertions(+), 6 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex dc5f73a9f3..f9fbf1f703 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -452,16 +452,18 @@ fi\n \n # This function is equivalent to\n #\n-#    __gitcomp \"$(git xxx --git-completion-helper) ...\"\n+#    ___git_resolved_builtins=$(git xxx --git-completion-helper)\n #\n-# except that the output is cached. Accept 1-3 arguments:\n+# except that the result of the execution is cached.\n+#\n+# Accept 1-3 arguments:\n # 1: the git command to execute, this is also the cache key\n+#    (use \"_\" when the command contains spaces, e.g. \"remote add\"\n+#    becomes \"remote_add\")\n # 2: extra options to be added on top (e.g. negative forms)\n # 3: options to be excluded\n-__gitcomp_builtin ()\n+__git_resolve_builtins ()\n {\n-\t# spaces must be replaced with underscore for multi-word\n-\t# commands, e.g. \"git remote add\" becomes remote_add.\n \tlocal cmd=\"$1\"\n \tlocal incl=\"${2-}\"\n \tlocal excl=\"${3-}\"\n@@ -487,7 +489,24 @@ __gitcomp_builtin ()\n \t\teval \"$var=\\\"$options\\\"\"\n \tfi\n \n-\t__gitcomp \"$options\"\n+\t___git_resolved_builtins=\"$options\"\n+}\n+\n+# This function is equivalent to\n+#\n+#    __gitcomp \"$(git xxx --git-completion-helper) ...\"\n+#\n+# except that the output is cached. Accept 1-3 arguments:\n+# 1: the git command to execute, this is also the cache key\n+#    (use \"_\" when the command contains spaces, e.g. \"remote add\"\n+#    becomes \"remote_add\")\n+# 2: extra options to be added on top (e.g. negative forms)\n+# 3: options to be excluded\n+__gitcomp_builtin ()\n+{\n+\t__git_resolve_builtins \"$1\" \"$2\" \"$3\"\n+\n+\t__gitcomp \"$___git_resolved_builtins\"\n }\n \n # Variation of __gitcomp_nl () that appends to the existing list of\n-- \n2.44.0\n"},{"id":"489775","messageId":"cf3933b2-a577-4df1-9425-cf324f03d6da@gmail.com","threadId":"60795","inReplyTo":"ea6c8890-9ff3-46c9-b933-6a52083b1001@gmail.com","subject":"[PATCH v2 5/5] completion: reflog subcommands and options","fromName":"Rubén Justo","fromEmail":"rjusto@gmail.com","sentAt":"2024-03-02T15:52:24Z","receivedAt":"2024-03-02T15:52:29Z","isPatch":true,"sender":{"key":"rjusto@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5685487?v=4"},"body":"Make generic the completion for reflog subcommands and its options.\n\nNote that we still need to special case the options for \"show\".\n\nSigned-off-by: Rubén Justo <rjusto@gmail.com>\n---\n contrib/completion/git-completion.bash | 12 ++++++++++--\n 1 file changed, 10 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex f9fbf1f703..c5c9e9de2d 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2445,8 +2445,12 @@ _git_rebase ()\n \n _git_reflog ()\n {\n-\tlocal subcommands=\"show delete expire\"\n-\tlocal subcommand=\"$(__git_find_subcommand \"$subcommands\" \"show\")\"\n+\tlocal subcommands subcommand\n+\n+\t__git_resolve_builtins \"reflog\"\n+\n+\tsubcommands=\"$___git_resolved_builtins\"\n+\tsubcommand=\"$(__git_find_subcommand \"$subcommands\" \"show\")\"\n \n \tcase \"$subcommand,$cur\" in\n \tshow,--*)\n@@ -2455,6 +2459,10 @@ _git_reflog ()\n \t\t\t\"\n \t\treturn\n \t\t;;\n+\t$subcommand,--*)\n+\t\t__gitcomp_builtin \"reflog_$subcommand\"\n+\t\treturn\n+\t\t;;\n \tesac\n \n \t__git_complete_refs\n-- \n2.44.0\n"}]}