From 85452a1d4b582701772b02b5a70b8bf5a82258bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Justo?= Date: Sat, 2 Mar 2024 15:37:34 +0100 Subject: [PATCH 1/5] completion: reflog with implicit "show" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When no subcommand is specified to "reflog", we assume "show" [1]: $ git reflog -h usage: git reflog [show] [] [] ... This implicit "show" is not being completed correctly: $ git checkout -b default $ git reflog def ... no completion options ... The expected result is: $ git reflog default This happens because we're completing references after seeing a valid subcommand in the command line. This prevents the implicit "show" from working properly, but also introduces a new problem: it keeps offering subcommand options when the subcommand is implicit: $ git checkout -b explore $ git reflog default ex ... $ git reflog default expire The expected result is: $ git reflog default explore To fix this, complete references even if no subcommand is present, or in other words when the subcommand is implicit "show". Also, only include completion options for subcommands when completing the right position in the command line. 1. cf39f54efc (git reflog show, 2007-02-08) Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 9 ++++----- t/t9902-completion.sh | 11 +++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 8c40ade494..ff216f1c65 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2407,12 +2407,11 @@ _git_rebase () _git_reflog () { local subcommands="show delete expire" - local subcommand="$(__git_find_on_cmdline "$subcommands")" - if [ -z "$subcommand" ]; then - __gitcomp "$subcommands" - else - __git_complete_refs + __git_complete_refs + + if [ $((cword - __git_cmd_idx)) -eq 1 ]; then + __gitcompappend "$subcommands" "" "$cur" " " fi } diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index aa9a614de3..dbd57e6a28 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -2618,6 +2618,17 @@ test_expect_success 'git clone --config= - value' ' EOF ' +test_expect_success 'git reflog show' ' + test_when_finished "git checkout - && git branch -d shown" && + git checkout -b shown && + test_completion "git reflog sho" <<-\EOF && + show Z + shown Z + EOF + test_completion "git reflog show sho" "shown " && + test_completion "git reflog shown sho" "shown " +' + test_expect_success 'options with value' ' test_completion "git merge -X diff-algorithm=" <<-\EOF From c689c38bc2dceac3f8fe975472f12c0dbe473537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Justo?= Date: Sat, 2 Mar 2024 16:50:47 +0100 Subject: [PATCH 2/5] completion: reflog show MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's add completion for in "reflog show" so that the user can easily discover uses like: $ git reflog --since=1.day.ago Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 10 ++++++++++ t/t9902-completion.sh | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index ff216f1c65..d4f0e08f58 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2407,6 +2407,16 @@ _git_rebase () _git_reflog () { local subcommands="show delete expire" + local subcommand="$(__git_find_subcommand "$subcommands" "show")" + + case "$subcommand,$cur" in + show,--*) + __gitcomp " + $__git_log_common_options + " + return + ;; + esac __git_complete_refs diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index dbd57e6a28..04f3620e5b 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -2626,7 +2626,10 @@ test_expect_success 'git reflog show' ' shown Z EOF test_completion "git reflog show sho" "shown " && - test_completion "git reflog shown sho" "shown " + test_completion "git reflog shown sho" "shown " && + test_completion "git reflog --unt" "--until=" && + test_completion "git reflog show --unt" "--until=" && + test_completion "git reflog shown --unt" "--until=" ' test_expect_success 'options with value' ' From 3fec482b5f7f2f13c7465cf79062440a84233d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Justo?= Date: Sat, 2 Mar 2024 16:51:08 +0100 Subject: [PATCH 3/5] completion: introduce __git_find_subcommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's have a function to get the current subcommand when completing commands that follow the syntax: git As a convenience, let's allow an optional "default subcommand" to be returned if none is found. Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index d4f0e08f58..dc5f73a9f3 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -554,6 +554,26 @@ __gitcomp_file () true } +# Find the current subcommand for commands that follow the syntax: +# +# git +# +# 1: List of possible subcommands. +# 2: Optional subcommand to return when none is found. +__git_find_subcommand () +{ + local subcommand subcommands="$1" default_subcommand="$2" + + for subcommand in $subcommands; do + if [ "$subcommand" = "${words[__git_cmd_idx+1]}" ]; then + echo $subcommand + return + fi + done + + echo $default_subcommand +} + # Execute 'git ls-files', unless the --committable option is specified, in # which case it runs 'git diff-index' to find out the files that can be # committed. It return paths relative to the directory specified in the first From 476a236e72d7ad0d2a5237faeaa439b1054e80a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Justo?= Date: Sat, 2 Mar 2024 16:52:03 +0100 Subject: [PATCH 4/5] completion: factor out __git_resolve_builtins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're going to use the result of "git xxx --git-completion-helper" not only for feeding COMPREPLY. Therefore, factor out the execution and the caching of its results in __gitcomp_builtin, to a new function __git_resolve_builtins. While we're here, move an important comment we have in the function to its header, so it gains visibility. Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 31 +++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index dc5f73a9f3..f9fbf1f703 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -452,16 +452,18 @@ fi # This function is equivalent to # -# __gitcomp "$(git xxx --git-completion-helper) ..." +# ___git_resolved_builtins=$(git xxx --git-completion-helper) # -# except that the output is cached. Accept 1-3 arguments: +# except that the result of the execution is cached. +# +# Accept 1-3 arguments: # 1: the git command to execute, this is also the cache key +# (use "_" when the command contains spaces, e.g. "remote add" +# becomes "remote_add") # 2: extra options to be added on top (e.g. negative forms) # 3: options to be excluded -__gitcomp_builtin () +__git_resolve_builtins () { - # spaces must be replaced with underscore for multi-word - # commands, e.g. "git remote add" becomes remote_add. local cmd="$1" local incl="${2-}" local excl="${3-}" @@ -487,7 +489,24 @@ __gitcomp_builtin () eval "$var=\"$options\"" fi - __gitcomp "$options" + ___git_resolved_builtins="$options" +} + +# This function is equivalent to +# +# __gitcomp "$(git xxx --git-completion-helper) ..." +# +# except that the output is cached. Accept 1-3 arguments: +# 1: the git command to execute, this is also the cache key +# (use "_" when the command contains spaces, e.g. "remote add" +# becomes "remote_add") +# 2: extra options to be added on top (e.g. negative forms) +# 3: options to be excluded +__gitcomp_builtin () +{ + __git_resolve_builtins "$1" "$2" "$3" + + __gitcomp "$___git_resolved_builtins" } # Variation of __gitcomp_nl () that appends to the existing list of From 1284f9cc11be4b656492938f68befbe4c87d915f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Justo?= Date: Sat, 2 Mar 2024 16:52:24 +0100 Subject: [PATCH 5/5] completion: reflog subcommands and options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make generic the completion for reflog subcommands and its options. Note that we still need to special case the options for "show". Signed-off-by: Rubén Justo Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index f9fbf1f703..c5c9e9de2d 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2445,8 +2445,12 @@ _git_rebase () _git_reflog () { - local subcommands="show delete expire" - local subcommand="$(__git_find_subcommand "$subcommands" "show")" + local subcommands subcommand + + __git_resolve_builtins "reflog" + + subcommands="$___git_resolved_builtins" + subcommand="$(__git_find_subcommand "$subcommands" "show")" case "$subcommand,$cur" in show,--*) @@ -2455,6 +2459,10 @@ _git_reflog () " return ;; + $subcommand,--*) + __gitcomp_builtin "reflog_$subcommand" + return + ;; esac __git_complete_refs