On Fri, Feb 09 2018, Nguyễn Thái Ngọc Duy jotted: > By default, some option names (mostly --force, scripting related or for > internal use) are not completable for various reasons. When > GIT_COMPLETION_OPTIONS is set to all, all options (except hidden ones) > are completable. > > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> > --- > contrib/completion/git-completion.bash | 6 +++++- > parse-options.c | 11 +++++++---- > 2 files changed, 12 insertions(+), 5 deletions(-) > > diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash > index 0ddf40063b..0cfa489a8e 100644 > --- a/contrib/completion/git-completion.bash > +++ b/contrib/completion/git-completion.bash > @@ -36,6 +36,10 @@ > # > # When set to "1", do not include "DWIM" suggestions in git-checkout > # completion (e.g., completing "foo" when "origin/foo" exists). > +# > +# GIT_COMPLETION_OPTIONS > +# > +# When set to "all", complete all possible options I was going to suggest some wording like: When set to "all", include options considered unsafe such as --force in the completion. However per your cover letter it's not just used for that: 10 --force 4 --rerere-autoupdate 1 --unsafe-paths 1 --thin 1 --overwrite-ignore 1 --open-files-in-pager 1 --null 1 --ext-grep 1 --exit-code 1 --auto I wonder if we shouldn't just make this only about --force, I don't see why "git grep --o<TAB>" should only show --or but not --open-files-in-pager, and e.g. "git grep --<TAB>" is already verbose so we're not saving much by excluding those. Then this could just become: GIT_COMPLETION_SHOWUNSAFEOPTIONS=1 Or other similar boolean variable, for consistency with all the "*SHOW* variables already in git-completion.bash. > case "$COMP_WORDBREAKS" in > *:*) : great ;; > @@ -303,7 +307,7 @@ __gitcomp_builtin () > if [ -z "$options" ]; then > # leading and trailing spaces are significant to make > # option removal work correctly. > - options=" $(__git ${cmd/_/ } --git-completion-helper) $incl " > + options=" $(__git ${cmd/_/ } --git-completion-helper=$GIT_COMPLETION_OPTIONS) $incl " > for i in $excl; do > options="${options/ $i / }" > done > diff --git a/parse-options.c b/parse-options.c > index 979577ba2c..5b8b2b376e 100644 > --- a/parse-options.c > +++ b/parse-options.c > @@ -430,14 +430,17 @@ void parse_options_start(struct parse_opt_ctx_t *ctx, > * many options that do not suppress it properly. > */ > static int show_gitcomp(struct parse_opt_ctx_t *ctx, > - const struct option *opts) > + const struct option *opts, > + const char *arg) > { > for (; opts->type != OPTION_END; opts++) { > const char *suffix = ""; > > if (!opts->long_name) > continue; > - if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE)) > + if (opts->flags & PARSE_OPT_HIDDEN) > + continue; > + if ((opts->flags & PARSE_OPT_NOCOMPLETE) && strcmp(arg, "all")) > continue; > > switch (opts->type) { > @@ -498,8 +501,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, > goto show_usage; > > /* lone --git-completion-helper is asked by git-completion.bash */ > - if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper")) > - return show_gitcomp(ctx, options); > + if (ctx->total == 1 && skip_prefix(arg + 1, "-git-completion-helper=", &arg)) > + return show_gitcomp(ctx, options, arg); > > if (arg[1] != '-') { > ctx->opt = arg + 1;