On Wed, Feb 02, 2022 at 12:15:10PM +0100, Ævar Arnfjörð Bjarmason wrote: > Add a GIT_COMPLETION_SHOW_ALL_COMMANDS=1 configuration setting to go > with the existing GIT_COMPLETION_SHOW_ALL=1 added in > c099f579b98 (completion: add GIT_COMPLETION_SHOW_ALL env var, > 2020-08-19). > > This will include plumbing commands such as "cat-file" in "git <TAB>" > and "git c<TAB>" completion. I've tried this a couple of times in the last dozen years or so... and ended up hating it every single time, because it too often made completion of frequently used porcelain commands more cumbersome, and quickly reverted it. Since 6532f3740b (completion: allow to customize the completable command list, 2018-05-20) it is possible to include and exclude certain commands from the list offered for 'git <TAB>'. So if you use some plumbing command frequently, then you can add them to the 'completion.commands' config variable, and they will show up for 'git <TAB>', too, without any of the other plumbing commands to get annoying. To complete only rarely used plumbing commands in a non-intrusive way, in my experience, it's best to first attempt to complete only porcelains and aliases, and fall back to complete all commands, plumbing included, only when no porcelains match the current word to be completed. E.g.: $ git d<TAB> describe diff difftool $ git diff-<TAB> diff-files diff-index diff-tree $ git p<TAB> prune pull push $ git pa<TAB> pack-objects pack-redundant pack-refs patch-id --- >8 --- Subject: [PATCH] completion: list all git commands as fallback --- contrib/completion/git-completion.bash | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 3edd1cade6..67978e6f22 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -3465,6 +3465,9 @@ __git_main () __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST" else __gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)" + if [ ${#COMPREPLY[@]} -eq 0 ]; then + __gitcomp "$(__git --list-cmds=main,others,nohelpers,alias,list-complete,config)" + fi fi ;; esac -- 2.35.1.482.g3282949ee0 --- 8< --- I've been using 'completion.commands' and the patch above for a few years now, and this combination worked out the best so far. > Without/with this I have 134 and 243 > completion with git <TAB>, respectively. Those numbers include all your aliases and additional 'git-foo' commands in your PATH; I only get 74 without this patch. To show the effect of this patch I think it would be more relevant to count only Git's commands. > It was already possible to do this by tweaking > GIT_TESTING_PORCELAIN_COMMAND_LIST= from the outside, that testing > variable was added in 84a97131065 (completion: let git provide the > completable command list, 2018-05-20). Doing this before loading > git-completion.bash worked: > > export GIT_TESTING_PORCELAIN_COMMAND_LIST="$(git --list-cmds=builtins,main,list-mainporcelain,others,nohelpers,alias,list-complete,config)" > > But such testing variables are not meant to be used from the outside, > and we make no guarantees that those internal won't change. So let's > expose this as a dedicated configuration knob. > > It would be better to teach --list-cmds=* a new category which would > include all of these groups, but that's a larger change that we can > leave for some other time. > > 1. https://lore.kernel.org/git/CAGP6POJ9gwp+t-eP3TPkivBLLbNb2+qj=61Mehcj=1BgrVOSLA@xxxxxxxxxxxxxx/ > > Reported-by: Hongyi Zhao <hongyi.zhao@xxxxxxxxx> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> > --- > contrib/completion/git-completion.bash | 13 ++++++++++- > t/t9902-completion.sh | 31 ++++++++++++++++++++++++++ > 2 files changed, 43 insertions(+), 1 deletion(-) > > diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash > index 377d6c5494a..2436b8eb6b9 100644 > --- a/contrib/completion/git-completion.bash > +++ b/contrib/completion/git-completion.bash > @@ -49,6 +49,11 @@ > # and git-switch completion (e.g., completing "foo" when "origin/foo" > # exists). > # > +# GIT_COMPLETION_SHOW_ALL_COMMANDS > +# > +# When set to "1" suggest all commands, including plumbing commands > +# which are hidden by default (e.g. "cat-file" on "git ca<TAB>"). > +# > # GIT_COMPLETION_SHOW_ALL > # > # When set to "1" suggest all options, including options which are > @@ -3455,7 +3460,13 @@ __git_main () > then > __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST" > else > - __gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)" > + local list_cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config > + > + if test "${GIT_COMPLETION_SHOW_ALL_COMMANDS-}" = "1" > + then > + list_cmds=builtins,$list_cmds > + fi > + __gitcomp "$(__git --list-cmds=$list_cmds)" > fi > ;; > esac > diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh > index c9805f2147d..c6d6d6ef896 100755 > --- a/t/t9902-completion.sh > +++ b/t/t9902-completion.sh > @@ -2440,6 +2440,37 @@ test_expect_success 'option aliases are shown with GIT_COMPLETION_SHOW_ALL' ' > ) > ' > > +test_expect_success 'plumbing commands are excluded without GIT_COMPLETION_SHOW_ALL_COMMANDS' ' > + ( > + . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" && > + sane_unset GIT_TESTING_PORCELAIN_COMMAND_LIST && > + > + # Just mainporcelain, not plumbing commands > + run_completion "git c" && > + grep checkout out && > + ! grep cat-file out > + ) > +' > + > +test_expect_success 'all commands are shown with GIT_COMPLETION_SHOW_ALL_COMMANDS (also main non-builtin)' ' > + ( > + . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" && > + GIT_COMPLETION_SHOW_ALL_COMMANDS=1 && > + export GIT_COMPLETION_SHOW_ALL_COMMANDS && This variable only affects the completion script itself, but none of the commands invoked by it, so the 'export' is unnecessary. > + sane_unset GIT_TESTING_PORCELAIN_COMMAND_LIST && > + > + # Both mainporcelain and plumbing commands > + run_completion "git c" && > + grep checkout out && > + grep cat-file out && > + > + # Check "gitk", a "main" command, but not a built-in + more plumbing > + run_completion "git g" && > + grep gitk out && > + grep get-tar-commit-id out > + ) > +' > + > test_expect_success '__git_complete' ' > unset -f __git_wrap__git_main && > > -- > 2.35.0.913.g12b4baa2536 >