Skip to contentSkip to conversation

Automate updating git-completion.bash a bit

PATCH Superseded Nguyễn Thái Ngọc Duy 5 participants 127 messages Jan 31, 2018 – Dec 12, 2018

lore
Share & tools
lore
#0 lore raw

v2 cover Automate updating git-completion.bash a bit

I posted a proof of concept a while back [1]. This is the full version.

This series lets "git" binary help git-completion.bash to complete --<stuff> so that when a new option is added, we don't have to update git-completion.bash manually too (people often forget it). As a side effect, about 180 more options are now completable.

parse-options is updated to allow developers to flag certain options not to be completable if they want finer control over it. But by default, new non-hidden options are completable. Negative forms must be handled manually. That's for the next step.

The number of patches is high, but changes after the first four patches and 33/41 are quite simple. I still need some eyeballs though to make sure I have not accidentally allowed completion of dangerous options. Details are broken down per command in each commit message.

If people want to play with this, I have a script [2] that shows all completable options for most commands (I ignore some that are shell-based because I don't touch them in this series). You can then do a "diff" to see new/old options.

There's a small conflict with 'pu' because --prune-tags is added in git-completion.bash. The solution is simple and beautiful: ignore those changes, --prune-tags will be completable anyway :)

[1] https://public-inbox.org/git/%[email protected]%3E/
[2] https://gist.github.com/pclouds/f337d4393b5cfab813909b8eea2eaa40

Nguyễn Thái Ngọc Duy (41):
parse-options: support --git-completion-helper
parse-options: add OPT_xxx_F() variants
parse-options: let OPT__FORCE take optional flags argument git-completion.bash: introduce __gitcomp_builtin
completion: use __gitcomp_builtin in _git_add
completion: use __gitcomp_builtin in _git_am
completion: use __gitcomp_builtin in _git_apply
completion: use __gitcomp_builtin in _git_branch
completion: use __gitcomp_builtin in _git_checkout
completion: use __gitcomp_builtin in _git_cherry_pick
completion: use __gitcomp_builtin in _git_clean
completion: use __gitcomp_builtin in _git_clone
completion: use __gitcomp_builtin in _git_commit
completion: use __gitcomp_builtin in _git_config
completion: use __gitcomp_builtin in _git_describe
completion: use __gitcomp_builtin in _git_difftool
completion: use __gitcomp_builtin in _git_fetch
completion: use __gitcomp_builtin in _git_fsck
completion: use __gitcomp_builtin in _git_gc
completion: use __gitcomp_builtin in _git_grep
completion: use __gitcomp_builtin in _git_help
completion: use __gitcomp_builtin in _git_init
completion: use __gitcomp_builtin in _git_ls_files
completion: use __gitcomp_builtin in _git_ls_remote
completion: use __gitcomp_builtin in _git_merge
completion: use __gitcomp_builtin in _git_merge_base
completion: use __gitcomp_builtin in _git_mv
completion: use __gitcomp_builtin in _git_name_rev
completion: use __gitcomp_builtin in _git_notes
completion: use __gitcomp_builtin in _git_pull
completion: use __gitcomp_builtin in _git_push
completion: use __gitcomp_builtin in _git_remote
remote: force completing --mirror= instead of --mirror
completion: use __gitcomp_builtin in _git_replace
completion: use __gitcomp_builtin in _git_reset
completion: use __gitcomp_builtin in _git_revert
completion: use __gitcomp_builtin in _git_rm
completion: use __gitcomp_builtin in _git_show_branch
completion: use __gitcomp_builtin in _git_status
completion: use __gitcomp_builtin in _git_tag
completion: use __gitcomp_builtin in _git_worktree

 apply.c                                |   5 +-
 builtin/add.c                          |   2 +-
 builtin/am.c                           |  16 +-
 builtin/branch.c                       |   2 +-
 builtin/checkout-index.c               |   2 +-
 builtin/checkout.c                     |   7 +-
 builtin/clean.c                        |   2 +-
 builtin/fetch.c                        |   2 +-
 builtin/gc.c                           |   7 +-
 builtin/grep.c                         |  13 +-
 builtin/ls-remote.c                    |   5 +-
 builtin/mv.c                           |   3 +-
 builtin/notes.c                        |   4 +-
 builtin/pull.c                         |   2 +-
 builtin/push.c                         |   2 +-
 builtin/remote.c                       |   2 +-
 builtin/replace.c                      |   3 +-
 builtin/revert.c                       |  12 +-
 builtin/rm.c                           |   2 +-
 builtin/tag.c                          |   2 +-
 builtin/update-server-info.c           |   2 +-
 builtin/worktree.c                     |   4 +-
 contrib/completion/git-completion.bash | 276 +++++++++----------------
 parse-options.c                        |  46 +++++
 parse-options.h                        |  40 ++--
 rerere.h                               |   3 +-
 t/t9902-completion.sh                  |  12 +-
 27 files changed, 236 insertions(+), 242 deletions(-)
Signature · 1 line
2.16.1.205.g271f633410
#1 lore raw

PATCH v2 1/41 parse-options: support --git-completion-helper

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

---
 parse-options.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 parse-options.h |  5 ++++-
 2 files changed, 48 insertions(+), 1 deletion(-)
parse-options.c +44 -0
index fca7159646..29f4defdd6 100644
@@ -425,6 +425,46 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
 	parse_options_check(options);
 }
 
+/*
+ * TODO: we are not completing the --no-XXX form yet because there are
+ * many options that do not suppress it properly.
+ */
+static int show_gitcomp(struct parse_opt_ctx_t *ctx,
+			const struct option *opts)
+{
+	for (; opts->type != OPTION_END; opts++) {
+		const char *suffix = "";
+
+		if (!opts->long_name)
+			continue;
+		if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+			continue;
+
+		switch (opts->type) {
+		case OPTION_GROUP:
+			continue;
+		case OPTION_STRING:
+		case OPTION_FILENAME:
+		case OPTION_INTEGER:
+		case OPTION_MAGNITUDE:
+		case OPTION_CALLBACK:
+			if (opts->flags & PARSE_OPT_NOARG)
+				break;
+			if (opts->flags & PARSE_OPT_OPTARG)
+				break;
+			if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
+				break;
+			suffix = "=";
+			break;
+		default:
+			break;
+		}
+		printf(" --%s%s", opts->long_name, suffix);
+	}
+	fputc('\n', stdout);
+	exit(0);
+}
+
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
 				       const char * const *,
 				       const struct option *, int, int);
@@ -455,6 +495,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 		if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
 			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 (arg[1] != '-') {
 			ctx->opt = arg + 1;
 			switch (parse_short_opt(ctx, options)) {
parse-options.h +4 -1
index af711227ae..983de27cf0 100644
@@ -38,7 +38,8 @@ enum parse_opt_option_flags {
 	PARSE_OPT_LASTARG_DEFAULT = 16,
 	PARSE_OPT_NODASH = 32,
 	PARSE_OPT_LITERAL_ARGHELP = 64,
-	PARSE_OPT_SHELL_EVAL = 256
+	PARSE_OPT_SHELL_EVAL = 256,
+	PARSE_OPT_NOCOMPLETE = 512
 };
 
 struct option;
@@ -89,6 +90,8 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
  *   PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets
  *				(i.e. '<argh>') in the help message.
  *				Useful for options with multiple parameters.
+ *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
+ *			   git-completion.bash. This option suppresses that.
  *
  * `callback`::
  *   pointer to the callback to use for OPTION_CALLBACK or
Signature · 1 line
2.16.1.205.g271f633410
#2 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 17 lines · Nguyễn Thái Ngọc Duy

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

---

parse-options.h typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx, · line 91

Quoted 2 lines
parse-options.h +2 -0
@@ -89,6 +90,8 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
+ *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
+ *                        git-completion.bash. This option suppresses that.

s/git-/by &/

#3 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

In reply to Nguyễn Thái Ngọc Duy
Quoted 5 lines · Nguyễn Thái Ngọc Duy

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

Quoted 7 lines

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

I wonder if this option should be named DANGEROUS rather than NOCOMPLETE to better reflect its intention. The reason I ask is that it is easy to imagine git-completion.bash some day growing a new configuration option to allow people to complete these "dangerous" options, as well, rather than us imposing, with no escape hatch, our idea of what should and should not complete.

It's not uncommon for "bug reports" to be sent to the list stating that such-and-such option (say, --force) does not autocomplete. Our stock answer is "oh, that's a dangerous option, so you'll have to type it manually". If git-completion.bash gains new configuration to allow dangerous options, then our answer can become "oh, that's a dangerous option, if you really want it to complete, then enable GIT_COMPLETION_DANGEROUS" (or whatever).

author
#4 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 9 lines · Eric Sunshine
Quoted 8 lines · Nguyễn Thái Ngọc Duy

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

Quoted 7 lines
Quoted 4 lines
    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

I wonder if this option should be named DANGEROUS rather than NOCOMPLETE to better reflect its intention.

It's not only for dangerous options (I forgot to mention this in the commit message, I will in v3). The --continue|--abort|--skip should only show up when you are in a middle of rebase/am/cherry-pick. git-completion.bash handles this case separately and only put them in the completion list when appropriate. --git-completion-helper must not include these or the trick done by git-completion.bash becomes useless.

Quoted 6 lines

The reason I ask is that
it is easy to imagine git-completion.bash some day growing a new configuration option to allow people to complete these "dangerous" options, as well, rather than us imposing, with no escape hatch, our idea of what should and should not complete.

Quoted 7 lines

It's not uncommon for "bug reports" to be sent to the list stating that such-and-such option (say, --force) does not autocomplete. Our stock answer is "oh, that's a dangerous option, so you'll have to type it manually". If git-completion.bash gains new configuration to allow dangerous options, then our answer can become "oh, that's a dangerous option, if you really want it to complete, then enable GIT_COMPLETION_DANGEROUS" (or whatever).

Interesting. So we now have two classes of "no complete". One can't be configurable (--continue|--abort|--skip) and one can. I'll use two separate flags for these, though I'm not adding the configuration option right now. It's easy to do and can way until someone actually asks for it.

Signature · 1 line
Duy
#5 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 16 lines · Duy Nguyen
Quoted 6 lines · Eric Sunshine
Quoted 2 lines · Nguyễn Thái Ngọc Duy

Dangerous/Unpopular
options could be hidden with the new "NOCOMPLETE" flag.

I wonder if this option should be named DANGEROUS rather than NOCOMPLETE to better reflect its intention.

It's not only for dangerous options (I forgot to mention this in the commit message, I will in v3). The --continue|--abort|--skip should only show up when you are in a middle of rebase/am/cherry-pick. git-completion.bash handles this case separately and only put them in the completion list when appropriate. --git-completion-helper must not include these or the trick done by git-completion.bash becomes useless.

Quoted 4 lines

Interesting. So we now have two classes of "no complete". One can't be configurable (--continue|--abort|--skip) and one can. I'll use two separate flags for these, though I'm not adding the configuration option right now.

I don't see that as convincing argument for two classes of "no complete". Since git-completion.bash already special-cases rebase/am/cherry-pick for --continue|--abort|--skip, it is not far fetched that that special-case treatment can be extended slightly to also filter out those three options from the list returned by --git-completion-helper.

So, if that special case is handled entirely by the completion script, then that leaves only the "dangerous" options, which requires only a single flag.

author
#6 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 22 lines · Eric Sunshine
Quoted 16 lines · Duy Nguyen
Quoted 6 lines · Eric Sunshine
Quoted 2 lines · Nguyễn Thái Ngọc Duy

Dangerous/Unpopular
options could be hidden with the new "NOCOMPLETE" flag.

I wonder if this option should be named DANGEROUS rather than NOCOMPLETE to better reflect its intention.

It's not only for dangerous options (I forgot to mention this in the commit message, I will in v3). The --continue|--abort|--skip should only show up when you are in a middle of rebase/am/cherry-pick. git-completion.bash handles this case separately and only put them in the completion list when appropriate. --git-completion-helper must not include these or the trick done by git-completion.bash becomes useless.

Quoted 4 lines

Interesting. So we now have two classes of "no complete". One can't be configurable (--continue|--abort|--skip) and one can. I'll use two separate flags for these, though I'm not adding the configuration option right now.

Quoted 6 lines

I don't see that as convincing argument for two classes of "no complete". Since git-completion.bash already special-cases rebase/am/cherry-pick for --continue|--abort|--skip, it is not far fetched that that special-case treatment can be extended slightly to also filter out those three options from the list returned by --git-completion-helper.

I agree that is possible, but it's a bit tricky to do the filtering right in bash (all options are sent back as one line instead of one per line, which is easier to process by command line tools).

On top of that, I think we want git-completion.bash to be fast, the more commands we execute there, the unhappier Windows users are. It is too possible to do this kind of filtering just once, before caching. It does not fit well to how I designed __gitcomp_builtin so I need to sit back and see how to sort that out.

Long term though, I think we would want more and more completion logic built in. One of those things I have in mind is to let --git-completion-helper (or some other new option) to provide completion for possible option values (e.g. true/false, values for "git merge --strategy=", "git status --untrack-files="....). That may also include completion of --continue|--abort|.. in C code, something like this roughly

# separate command blocks because we still need to cache them in shell
if [ -f .git/rebase-apply ]; then
    __gitcomp $(git $cmd --git-completion-helper=in-progress)
else
    __gitcomp $(git $cmd --git-completion-helper)
fi

which means eventually we have to flag these options differently.

Having said all that, these are the things I imagine we _might_ do. I have not really thought it through and nor do I have a clear plan forward at this point, so they may end up being just rubbish thoughts.

Quoted 3 lines

So, if that special case is handled entirely by the completion script, then that leaves only the "dangerous" options, which requires only a single flag.

Signature · 1 line
Duy
#7 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 11 lines · Duy Nguyen
Quoted 6 lines · Eric Sunshine

I don't see that as convincing argument for two classes of "no complete". Since git-completion.bash already special-cases rebase/am/cherry-pick for --continue|--abort|--skip, it is not far fetched that that special-case treatment can be extended slightly to also filter out those three options from the list returned by --git-completion-helper.

I agree that is possible, but it's a bit tricky to do the filtering right in bash (all options are sent back as one line instead of one per line, which is easier to process by command line tools).

Perhaps I'm missing something, but wouldn't filtering out those options directly in Bash require only this?

    % x='--foo --bar --snoo'
    % echo ${x/--bar}
    --foo --snoo
Quoted 5 lines

On top of that, I think we want git-completion.bash to be fast, the more commands we execute there, the unhappier Windows users are. It is too possible to do this kind of filtering just once, before caching. It does not fit well to how I designed __gitcomp_builtin so I need to sit back and see how to sort that out.

The filtering as illustrated above using builtin Bash functionality seems unlikely to be a source of noticeable slow down on Windows.

And, if you're concerned about it not fitting the design of __gitcomp_builtin, it's almost certainly cheap enough to do the filtering each time its needed rather than worrying about caching the filtered list. (It's hard to imagine anyone noticing a slow down of three extra ${x/} substitutions.)

author
#8 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 13 lines · Eric Sunshine
Quoted 11 lines · Duy Nguyen
Quoted 6 lines · Eric Sunshine

I don't see that as convincing argument for two classes of "no complete". Since git-completion.bash already special-cases rebase/am/cherry-pick for --continue|--abort|--skip, it is not far fetched that that special-case treatment can be extended slightly to also filter out those three options from the list returned by --git-completion-helper.

I agree that is possible, but it's a bit tricky to do the filtering right in bash (all options are sent back as one line instead of one per line, which is easier to process by command line tools).

Quoted 6 lines

Perhaps I'm missing something, but wouldn't filtering out those options directly in Bash require only this?

    % x='--foo --bar --snoo'
    % echo ${x/--bar}
    --foo --snoo

OK how about some thing like this fixup patch? __gitcomp_builtin now allows to add extra options as well as remove some.

-- 8< --
Subject: [PATCH] fixup! git-completion.bash: introduce __gitcomp_builtin

---
 contrib/completion/git-completion.bash | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
contrib/completion/git-completion.bash +12 -5
index cfd24c5764..ecd5896064 100644
@@ -284,24 +284,31 @@ __gitcomp ()
 #
 #    __gitcomp "$(git xxx --git-completion-helper) ..."
 #
-# except that the value from $(git) is cached
+# except that the output is cached. Accept 1-3 arguments:
+# 1: the git command to execute, this is also the cache key
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
 __gitcomp_builtin ()
 {
 	# spaces must be replaced with underscore for multi-word
 	# commands, e.g. "git remote add" becomes remote_add.
 	local cmd="$1"
-	shift
+	local incl="$2"
+	local excl="$3"
 
 	local var=__gitcomp_builtin_"${cmd/-/_}"
 	local options
 	eval "options=\$$var"
 
 	if [ -z "$options" ]; then
-		declare -g "$var=$(__git ${cmd/_/ } --git-completion-helper)"
-		eval "options=\$$var"
+		options="$(__git ${cmd/_/ } --git-completion-helper) $incl "
+		for i in $excl; do
+			options="${options/$i /}"
+		done
+		eval "$var=\"$options\""
 	fi
 
-	__gitcomp "$options $*"
+	__gitcomp "$options"
 }
 
 # Variation of __gitcomp_nl () that appends to the existing list of
Signature · 7 lines
2.16.1.207.gedba492059

-- 8< --

Usage would be something like this

-- 8< --
contrib/completion/git-completion.bash +4 -2
index ecd5896064..049bfc3320 100644
@@ -1103,12 +1103,13 @@ __git_count_arguments ()
 }
 
 __git_whitespacelist="nowarn warn error error-all fix"
+__git_am_inprogress_options="--skip --continue --resolved --abort"
 
 _git_am ()
 {
 	__git_find_repo_path
 	if [ -d "$__git_repo_path"/rebase-apply ]; then
-		__gitcomp "--skip --continue --resolved --abort"
+		__gitcomp "$__git_am_inprogress_options"
 		return
 	fi
 	case "$cur" in
@@ -1117,7 +1118,8 @@ _git_am ()
 		return
 		;;
 	--*)
-		__gitcomp_builtin am "--no-utf8"
+		__gitcomp_builtin am "--no-utf8" \
+			"$__git_am_inprogress_options"
 		return
 	esac
 }

-- 8< --

I think I'm keeping the flag name PARSE_OPT_NOCOMPLETE for now though. There are a few options that don't fit in "dangerous" category, e.g.

- "gc --auto" is hidden because it does not make sense to type it directly. Same story for "push --thin".

- "grep --ext-grep" is no-op

- --null, --exit-code and others are for scripting and not that often typed.
--
Duy

#9 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 27 lines · Duy Nguyen
Quoted 13 lines · Eric Sunshine
Quoted 11 lines · Duy Nguyen
Quoted 6 lines · Eric Sunshine

I don't see that as convincing argument for two classes of "no complete". Since git-completion.bash already special-cases rebase/am/cherry-pick for --continue|--abort|--skip, it is not far fetched that that special-case treatment can be extended slightly to also filter out those three options from the list returned by --git-completion-helper.

I agree that is possible, but it's a bit tricky to do the filtering right in bash (all options are sent back as one line instead of one per line, which is easier to process by command line tools).

Quoted 6 lines

Perhaps I'm missing something, but wouldn't filtering out those options directly in Bash require only this?

    % x='--foo --bar --snoo'
    % echo ${x/--bar}
    --foo --snoo

OK how about some thing like this fixup patch? __gitcomp_builtin now allows to add extra options as well as remove some.

-- 8< --
__gitcomp_builtin ()
{

contrib/completion/git-completion.bash __gitcomp () · line 306

Quoted 5 lines
contrib/completion/git-completion.bash +5 -0
+       local incl="$2"
+       local excl="$3"
+               options="$(__git ${cmd/_/ } --git-completion-helper) $incl "
+               for i in $excl; do
+                       options="${options/$i /}"

Is 'options' guaranteed to end with a space? If not, then this expulsion will fail for the very last option. I'd think you can get by fine with just "${options/$i}".

#10 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 13 lines

contrib/completion/git-completion.bash __gitcomp () · line 306

Quoted 12 lines

OK how about some thing like this fixup patch? __gitcomp_builtin now allows to add extra options as well as remove some.

-- 8< --
__gitcomp_builtin ()
{

contrib/completion/git-completion.bash +5 -0
+       local incl="$2"
+       local excl="$3"
+               options="$(__git ${cmd/_/ } --git-completion-helper) $incl "
+               for i in $excl; do
+                       options="${options/$i /}"
Quoted 1 line

Is 'options' guaranteed to end with a space?

It is, note the space before the closing double quote in:

  options="$(__git ${cmd/_/ } --git-completion-helper) $incl "
Quoted 3 lines

If not, then this
expulsion will fail for the very last option. I'd think you can get by fine with just "${options/$i}".

I would prefer a space both at the beginning and at the end of the pattern. Please excuse the contrived corner case, but it could still fail if the option to be excluded is a suffix of an other option:

  $ o="$(echo --foo--bar --baz --bar) "
  $ echo "'${o/--bar /}'"       # exclude '--bar'
  '--foo--baz --bar '

Maybe we'll never have --opt--ions with a doubledash in them[1], but still...

  $ o=" $(echo --foo--bar --baz --bar) "
  $ echo "'${o/ --bar / }'"
  ' --foo--bar --baz '

[1] - Interestingly, grep shows that the German translation does contain a '--reset--author'.

#11 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

In reply to Eric Sunshine

On Wed, Jan 31 2018, Eric Sunshine jotted:

Quoted 21 lines · Nguyễn Thái Ngọc Duy
Quoted 5 lines

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

Quoted 7 lines

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

I wonder if this option should be named DANGEROUS rather than NOCOMPLETE to better reflect its intention. The reason I ask is that it is easy to imagine git-completion.bash some day growing a new configuration option to allow people to complete these "dangerous" options, as well, rather than us imposing, with no escape hatch, our idea of what should and should not complete.

Quoted 7 lines

It's not uncommon for "bug reports" to be sent to the list stating that such-and-such option (say, --force) does not autocomplete. Our stock answer is "oh, that's a dangerous option, so you'll have to type it manually". If git-completion.bash gains new configuration to allow dangerous options, then our answer can become "oh, that's a dangerous option, if you really want it to complete, then enable GIT_COMPLETION_DANGEROUS" (or whatever).

I think we should just drop this idea of dangerous and complete things like --force. On the same systems people use this on this will complete --force:

    rm / --recurse --for<TAB>

So it's odd UI to be inconsistent with that. But if others disagree and want to keep the current behavior I'd definitely turn the "complete 'dangerous'" option.

author
#12 lore raw

Re: [PATCH v2 01/41] parse-options: support --git-completion-helper

Quoted 36 lines · Ævar Arnfjörð Bjarmason

On Wed, Jan 31 2018, Eric Sunshine jotted:

Quoted 21 lines · Nguyễn Thái Ngọc Duy
Quoted 5 lines

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

Quoted 7 lines

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

I wonder if this option should be named DANGEROUS rather than NOCOMPLETE to better reflect its intention. The reason I ask is that it is easy to imagine git-completion.bash some day growing a new configuration option to allow people to complete these "dangerous" options, as well, rather than us imposing, with no escape hatch, our idea of what should and should not complete.

Quoted 7 lines

It's not uncommon for "bug reports" to be sent to the list stating that such-and-such option (say, --force) does not autocomplete. Our stock answer is "oh, that's a dangerous option, so you'll have to type it manually". If git-completion.bash gains new configuration to allow dangerous options, then our answer can become "oh, that's a dangerous option, if you really want it to complete, then enable GIT_COMPLETION_DANGEROUS" (or whatever).

I think we should just drop this idea of dangerous and complete things like --force. On the same systems people use this on this will complete --force:

Quoted 5 lines
    rm / --recurse --for<TAB>

So it's odd UI to be inconsistent with that. But if others disagree and want to keep the current behavior I'd definitely turn the "complete 'dangerous'" option.

Personally I like completing all options too (and will be happier if plumbing commands are completable; it seems much less work to do that now). But I don't know git-completion.bash history and don't want to revisit why some options are filtered out or the inconsistency.

Signature · 1 line
Duy
#13 lore raw

PATCH v2 2/41 parse-options: add OPT_xxx_F() variants

In reply to Nguyễn Thái Ngọc Duy

These macros allow us to add extra parse-options flag, the main one in my mind is PARSE_OPT_NOCOMPLETE to hide certain options from --git-completion-helper.

---
 parse-options.h | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
parse-options.h +16 -9
index 983de27cf0..bc41b99d3b 100644
@@ -115,23 +115,30 @@ struct option {
 	intptr_t defval;
 };
 
+#define OPT_BIT_F(s, l, v, h, b, f) { OPTION_BIT, (s), (l), (v), NULL, (h), \
+				      PARSE_OPT_NOARG|(f), NULL, (b) }
+#define OPT_COUNTUP_F(s, l, v, h, f) { OPTION_COUNTUP, (s), (l), (v), NULL, \
+				       (h), PARSE_OPT_NOARG|(f) }
+#define OPT_SET_INT_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \
+					  (h), PARSE_OPT_NOARG | (f), NULL, (i) }
+#define OPT_BOOL_F(s, l, v, h, f)   OPT_SET_INT_F(s, l, v, h, 1, f)
+#define OPT_CMDMODE_F(s, l, v, h, i, f) { OPTION_CMDMODE, (s), (l), (v), NULL, \
+					  (h), PARSE_OPT_NOARG|PARSE_OPT_NONEG|(f), \
+					  NULL, (i) }
+
 #define OPT_END()                   { OPTION_END }
 #define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
 				      (h), PARSE_OPT_NOARG}
 #define OPT_GROUP(h)                { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
-#define OPT_BIT(s, l, v, h, b)      { OPTION_BIT, (s), (l), (v), NULL, (h), \
-				      PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_BIT(s, l, v, h, b)      OPT_BIT_F(s, l, v, h, b, 0)
 #define OPT_NEGBIT(s, l, v, h, b)   { OPTION_NEGBIT, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG, NULL, (b) }
-#define OPT_COUNTUP(s, l, v, h)     { OPTION_COUNTUP, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG }
-#define OPT_SET_INT(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG, NULL, (i) }
-#define OPT_BOOL(s, l, v, h)        OPT_SET_INT(s, l, v, h, 1)
+#define OPT_COUNTUP(s, l, v, h)     OPT_COUNTUP_F(s, l, v, h, 0)
+#define OPT_SET_INT(s, l, v, h, i)  OPT_SET_INT_F(s, l, v, h, i, 0)
+#define OPT_BOOL(s, l, v, h)        OPT_BOOL_F(s, l, v, h, 0)
 #define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
-#define OPT_CMDMODE(s, l, v, h, i)  { OPTION_CMDMODE, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) }
+#define OPT_CMDMODE(s, l, v, h, i)  OPT_CMDMODE_F(s, l, v, h, i, 0)
 #define OPT_INTEGER(s, l, v, h)     { OPTION_INTEGER, (s), (l), (v), N_("n"), (h) }
 #define OPT_MAGNITUDE(s, l, v, h)   { OPTION_MAGNITUDE, (s), (l), (v), \
 				      N_("n"), (h), PARSE_OPT_NONEG }
Signature · 1 line
2.16.1.205.g271f633410
#14 lore raw

PATCH v2 3/41 parse-options: let OPT__FORCE take optional flags argument

In reply to Nguyễn Thái Ngọc Duy

--force option is most likely hidden from command line completion for safety reasons. This is done by adding an extra flag PARSE_OPT_NOCOMPLETE. Update OPT__FORCE() to accept additional flags. Actual flag change comes later depending on individual commands.

---
 builtin/add.c                | 2 +-
 builtin/branch.c             | 2 +-
 builtin/checkout-index.c     | 2 +-
 builtin/checkout.c           | 2 +-
 builtin/clean.c              | 2 +-
 builtin/fetch.c              | 2 +-
 builtin/mv.c                 | 2 +-
 builtin/notes.c              | 4 ++--
 builtin/pull.c               | 2 +-
 builtin/rm.c                 | 2 +-
 builtin/tag.c                | 2 +-
 builtin/update-server-info.c | 2 +-
 builtin/worktree.c           | 4 +++-
 parse-options.h              | 2 +-
 14 files changed, 17 insertions(+), 15 deletions(-)
builtin/add.c +1 -1
index bf01d89e28..ac7c1c3277 100644
@@ -294,7 +294,7 @@ static struct option builtin_add_options[] = {
 	OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
 	OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
 	OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
-	OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
+	OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
 	OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
 	OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
 	OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
builtin/branch.c +1 -1
index 8dcc2ed058..b5b62c08ba 100644
@@ -615,7 +615,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_BOOL('l', "create-reflog", &reflog, N_("create the branch's reflog")),
 		OPT_BOOL(0, "edit-description", &edit_description,
 			 N_("edit the description for the branch")),
-		OPT__FORCE(&force, N_("force creation, move/rename, deletion")),
+		OPT__FORCE(&force, N_("force creation, move/rename, deletion"), 0),
 		OPT_MERGED(&filter, N_("print only branches that are merged")),
 		OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
builtin/checkout-index.c +1 -1
index b0e78b819d..a730f6a1aa 100644
@@ -157,7 +157,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
 	struct option builtin_checkout_index_options[] = {
 		OPT_BOOL('a', "all", &all,
 			N_("check out all files in the index")),
-		OPT__FORCE(&force, N_("force overwrite of existing files")),
+		OPT__FORCE(&force, N_("force overwrite of existing files"), 0),
 		OPT__QUIET(&quiet,
 			N_("no warning for existing files and files not in index")),
 		OPT_BOOL('n', "no-create", &not_new,
builtin/checkout.c +1 -1
index c54c78df54..2a96358eb7 100644
@@ -1118,7 +1118,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			    2),
 		OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
 			    3),
-		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)")),
+		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"), 0),
 		OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
 		OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
 		OPT_STRING(0, "conflict", &conflict_style, N_("style"),
builtin/clean.c +1 -1
index 189e20628c..3c4ca9a2ff 100644
@@ -909,7 +909,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__QUIET(&quiet, N_("do not print names of files removed")),
 		OPT__DRY_RUN(&dry_run, N_("dry run")),
-		OPT__FORCE(&force, N_("force")),
+		OPT__FORCE(&force, N_("force"), 0),
 		OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")),
 		OPT_BOOL('d', NULL, &remove_directories,
 				N_("remove whole directories")),
builtin/fetch.c +1 -1
index 7bbcd26faf..6a603174fb 100644
@@ -115,7 +115,7 @@ static struct option builtin_fetch_options[] = {
 		 N_("append to .git/FETCH_HEAD instead of overwriting")),
 	OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
 		   N_("path to upload pack on remote end")),
-	OPT__FORCE(&force, N_("force overwrite of local branch")),
+	OPT__FORCE(&force, N_("force overwrite of local branch"), 0),
 	OPT_BOOL('m', "multiple", &multiple,
 		 N_("fetch from multiple remotes")),
 	OPT_SET_INT('t', "tags", &tags,
builtin/mv.c +1 -1
index cf3684d907..b88023a733 100644
@@ -122,7 +122,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 	struct option builtin_mv_options[] = {
 		OPT__VERBOSE(&verbose, N_("be verbose")),
 		OPT__DRY_RUN(&show_only, N_("dry run")),
-		OPT__FORCE(&force, N_("force move/rename even if target exists")),
+		OPT__FORCE(&force, N_("force move/rename even if target exists"), 0),
 		OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
 		OPT_END(),
 	};
builtin/notes.c +2 -2
index 7c81761645..b52e71c73e 100644
@@ -413,7 +413,7 @@ static int add(int argc, const char **argv, const char *prefix)
 			parse_reuse_arg},
 		OPT_BOOL(0, "allow-empty", &allow_empty,
 			N_("allow storing empty note")),
-		OPT__FORCE(&force, N_("replace existing notes")),
+		OPT__FORCE(&force, N_("replace existing notes"), 0),
 		OPT_END()
 	};
 
@@ -484,7 +484,7 @@ static int copy(int argc, const char **argv, const char *prefix)
 	struct notes_tree *t;
 	const char *rewrite_cmd = NULL;
 	struct option options[] = {
-		OPT__FORCE(&force, N_("replace existing notes")),
+		OPT__FORCE(&force, N_("replace existing notes"), 0),
 		OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")),
 		OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"),
 			   N_("load rewriting config for <command> (implies "
builtin/pull.c +1 -1
index 511dbbe0f6..652239aae9 100644
@@ -193,7 +193,7 @@ static struct option pull_options[] = {
 	OPT_PASSTHRU(0, "upload-pack", &opt_upload_pack, N_("path"),
 		N_("path to upload pack on remote end"),
 		0),
-	OPT__FORCE(&opt_force, N_("force overwrite of local branch")),
+	OPT__FORCE(&opt_force, N_("force overwrite of local branch"), 0),
 	OPT_PASSTHRU('t', "tags", &opt_tags, NULL,
 		N_("fetch all tags and associated objects"),
 		PARSE_OPT_NOARG),
builtin/rm.c +1 -1
index 4a2fcca27b..6e0c7f5ac6 100644
@@ -242,7 +242,7 @@ static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__QUIET(&quiet, N_("do not list removed files")),
 	OPT_BOOL( 0 , "cached",         &index_only, N_("only remove from the index")),
-	OPT__FORCE(&force, N_("override the up-to-date check")),
+	OPT__FORCE(&force, N_("override the up-to-date check"), 0),
 	OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
 	OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
 				N_("exit with a zero status even if nothing matched")),
builtin/tag.c +1 -1
index a7e6a5b0f2..98d3956bbe 100644
@@ -391,7 +391,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 			N_("how to strip spaces and #comments from message")),
 		OPT_STRING('u', "local-user", &keyid, N_("key-id"),
 					N_("use another key to sign the tag")),
-		OPT__FORCE(&force, N_("replace the tag if exists")),
+		OPT__FORCE(&force, N_("replace the tag if exists"), 0),
 		OPT_BOOL(0, "create-reflog", &create_reflog, N_("create a reflog")),
 
 		OPT_GROUP(N_("Tag listing options")),
builtin/update-server-info.c +1 -1
index 873070e517..4321a34456 100644
@@ -12,7 +12,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix)
 {
 	int force = 0;
 	struct option options[] = {
-		OPT__FORCE(&force, N_("update the info files from scratch")),
+		OPT__FORCE(&force, N_("update the info files from scratch"), 0),
 		OPT_END()
 	};
 
builtin/worktree.c +3 -1
index 7cef5b120b..4d3422f62e 100644
@@ -365,7 +365,9 @@ static int add(int ac, const char **av, const char *prefix)
 	const char *branch;
 	const char *opt_track = NULL;
 	struct option options[] = {
-		OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
+		OPT__FORCE(&opts.force,
+			   N_("checkout <branch> even if already checked out in other worktree"),
+			   0),
 		OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
 			   N_("create a new branch")),
 		OPT_STRING('B', NULL, &new_branch_force, N_("branch"),
parse-options.h +1 -1
index bc41b99d3b..23c912b842 100644
@@ -250,7 +250,7 @@ extern int parse_opt_passthru_argv(const struct option *, const char *, int);
 	{ OPTION_CALLBACK, 'q', "quiet", (var), NULL, N_("be more quiet"), \
 	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
 #define OPT__DRY_RUN(var, h)  OPT_BOOL('n', "dry-run", (var), (h))
-#define OPT__FORCE(var, h)    OPT_COUNTUP('f', "force",   (var), (h))
+#define OPT__FORCE(var, h, f) OPT_COUNTUP_F('f', "force",   (var), (h), (f))
 #define OPT__ABBREV(var)  \
 	{ OPTION_CALLBACK, 0, "abbrev", (var), N_("n"),	\
 	  N_("use <n> digits to display SHA-1s"),	\
Signature · 1 line
2.16.1.205.g271f633410
#15 lore raw

PATCH v2 4/41 git-completion.bash: introduce __gitcomp_builtin

In reply to Nguyễn Thái Ngọc Duy

This is a __gitcomp wrapper that will execute

    git ... --git-completion-helper

to get the list of completable options. The call will be made only once and cached to avoid performance issues, especially on Windows.

---
 contrib/completion/git-completion.bash | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
contrib/completion/git-completion.bash +24 -0
index 3683c772c5..2d8d3434c6 100644
@@ -280,6 +280,30 @@ __gitcomp ()
 	esac
 }
 
+# This function is equivalent to
+#
+#    __gitcomp "$(git xxx --git-completion-helper) ..."
+#
+# except that the value from $(git) is cached
+__gitcomp_builtin ()
+{
+	# spaces must be replaced with underscore for multi-word
+	# commands, e.g. "git remote add" becomes remote_add.
+	local cmd="$1"
+	shift
+
+	local var=__gitcomp_builtin_"${cmd/-/_}"
+	local options
+	eval "options=\$$var"
+
+	if [ -z "$options" ]; then
+		declare -g "$var=$(__git ${cmd/_/ } --git-completion-helper)"
+		eval "options=\$$var"
+	fi
+
+	__gitcomp "$options $*"
+}
+
 # Variation of __gitcomp_nl () that appends to the existing list of
 # completion candidates, COMPREPLY.
 __gitcomp_nl_append ()
Signature · 1 line
2.16.1.205.g271f633410
#16 lore raw

PATCH v2 5/41 completion: use __gitcomp_builtin in _git_add

In reply to Nguyễn Thái Ngọc Duy

The new completable options are

--all
--ignore-missing
--ignore-removal
--renormalize
--verbose

---
 contrib/completion/git-completion.bash | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
contrib/completion/git-completion.bash +1 -4
index 2d8d3434c6..9aa3aa241b 100644
@@ -1144,10 +1144,7 @@ _git_add ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--interactive --refresh --patch --update --dry-run
-			--ignore-errors --intent-to-add --force --edit --chmod=
-			"
+		__gitcomp_builtin add
 		return
 	esac
 
Signature · 1 line
2.16.1.205.g271f633410
#17 lore raw

PATCH v2 6/41 completion: use __gitcomp_builtin in _git_am

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--directory
--exclude
--gpg-sign
--include
--keep-cr
--keep-non-patch
--message-id
--no-keep-cr
--patch-format
--quiet
--reject
--resolvemsg=

---
 builtin/am.c                           | 16 ++++++++--------
 contrib/completion/git-completion.bash |  7 +------
 parse-options.h                        |  4 ++--
 rerere.h                               |  3 ++-
 4 files changed, 13 insertions(+), 17 deletions(-)
builtin/am.c +8 -8
index acfe9d3c8c..d42832dc0b 100644
@@ -2237,18 +2237,18 @@ int cmd_am(int argc, const char **argv, const char *prefix)
 			PARSE_OPT_NOARG),
 		OPT_STRING(0, "resolvemsg", &state.resolvemsg, NULL,
 			N_("override error message when patch failure occurs")),
-		OPT_CMDMODE(0, "continue", &resume,
+		OPT_CMDMODE_F(0, "continue", &resume,
 			N_("continue applying patches after resolving a conflict"),
-			RESUME_RESOLVED),
-		OPT_CMDMODE('r', "resolved", &resume,
+			RESUME_RESOLVED, PARSE_OPT_NOCOMPLETE),
+		OPT_CMDMODE_F('r', "resolved", &resume,
 			N_("synonyms for --continue"),
-			RESUME_RESOLVED),
-		OPT_CMDMODE(0, "skip", &resume,
+			RESUME_RESOLVED, PARSE_OPT_NOCOMPLETE),
+		OPT_CMDMODE_F(0, "skip", &resume,
 			N_("skip the current patch"),
-			RESUME_SKIP),
-		OPT_CMDMODE(0, "abort", &resume,
+			RESUME_SKIP, PARSE_OPT_NOCOMPLETE),
+		OPT_CMDMODE_F(0, "abort", &resume,
 			N_("restore the original branch and abort the patching operation."),
-			RESUME_ABORT),
+			RESUME_ABORT, PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "committer-date-is-author-date",
 			&state.committer_date_is_author_date,
 			N_("lie about committer date")),
contrib/completion/git-completion.bash +1 -6
index 9aa3aa241b..ce53b78c81 100644
@@ -1110,12 +1110,7 @@ _git_am ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--3way --committer-date-is-author-date --ignore-date
-			--ignore-whitespace --ignore-space-change
-			--interactive --keep --no-utf8 --signoff --utf8
-			--whitespace= --scissors
-			"
+		__gitcomp_builtin am "--no-utf8"
 		return
 	esac
 }
parse-options.h +2 -2
index 23c912b842..fa75df17b4 100644
@@ -146,8 +146,8 @@ struct option {
 #define OPT_STRING_LIST(s, l, v, a, h) \
 				    { OPTION_CALLBACK, (s), (l), (v), (a), \
 				      (h), 0, &parse_opt_string_list }
-#define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
+#define OPT_UYN(s, l, v, h, f)      { OPTION_CALLBACK, (s), (l), (v), NULL, \
+				      (h), PARSE_OPT_NOARG|(f), &parse_opt_tertiary }
 #define OPT_DATE(s, l, v, h) \
 	{ OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,	\
 	  parse_opt_approxidate_cb }
rerere.h +2 -1
index c2961feaaa..5e5a312e4c 100644
@@ -37,6 +37,7 @@ extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
 
 #define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \
-	N_("update the index with reused conflict resolution if possible"))
+	N_("update the index with reused conflict resolution if possible"), \
+	PARSE_OPT_NOCOMPLETE)
 
 #endif
Signature · 1 line
2.16.1.205.g271f633410
#18 lore raw

PATCH v2 7/41 completion: use __gitcomp_builtin in _git_apply

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--3way
--allow-overlap
--build-fake-ancestor=
--directory
--exclude
--include

--index-info is no longer completable but that's because it's renamed to --build-fake-ancestor in 26b2800768 (apply: get rid of --index-info in favor of --build-fake-ancestor - 2007-09-17)

---
 apply.c                                | 5 +++--
 contrib/completion/git-completion.bash | 9 +--------
 2 files changed, 4 insertions(+), 10 deletions(-)
apply.c +3 -2
index 321a9fa68d..65eb37e6a4 100644
@@ -4943,8 +4943,9 @@ int apply_parse_options(int argc, const char **argv,
 			N_("make sure the patch is applicable to the current index")),
 		OPT_BOOL(0, "cached", &state->cached,
 			N_("apply a patch without touching the working tree")),
-		OPT_BOOL(0, "unsafe-paths", &state->unsafe_paths,
-			N_("accept a patch that touches outside the working area")),
+		OPT_BOOL_F(0, "unsafe-paths", &state->unsafe_paths,
+			   N_("accept a patch that touches outside the working area"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "apply", force_apply,
 			N_("also apply the patch (use with --stat/--summary/--check)")),
 		OPT_BOOL('3', "3way", &state->threeway,
contrib/completion/git-completion.bash +1 -8
index ce53b78c81..6f763c524e 100644
@@ -1123,14 +1123,7 @@ _git_apply ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--stat --numstat --summary --check --index
-			--cached --index-info --reverse --reject --unidiff-zero
-			--apply --no-add --exclude=
-			--ignore-whitespace --ignore-space-change
-			--whitespace= --inaccurate-eof --verbose
-			--recount --directory=
-			"
+		__gitcomp_builtin apply
 		return
 	esac
 }
Signature · 1 line
2.16.1.205.g271f633410
#19 lore raw

PATCH v2 8/41 completion: use __gitcomp_builtin in _git_branch

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--all
--create-reflog
--format=
--ignore-case
--quiet

---
 builtin/branch.c                       | 2 +-
 contrib/completion/git-completion.bash | 8 ++------
 2 files changed, 3 insertions(+), 7 deletions(-)
builtin/branch.c +1 -1
index b5b62c08ba..6d0cea9d4b 100644
@@ -615,7 +615,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_BOOL('l', "create-reflog", &reflog, N_("create the branch's reflog")),
 		OPT_BOOL(0, "edit-description", &edit_description,
 			 N_("edit the description for the branch")),
-		OPT__FORCE(&force, N_("force creation, move/rename, deletion"), 0),
+		OPT__FORCE(&force, N_("force creation, move/rename, deletion"), PARSE_OPT_NOCOMPLETE),
 		OPT_MERGED(&filter, N_("print only branches that are merged")),
 		OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
contrib/completion/git-completion.bash +2 -6
index 6f763c524e..4a2858f09c 100644
@@ -1209,12 +1209,8 @@ _git_branch ()
 		__git_complete_refs --cur="${cur##--set-upstream-to=}"
 		;;
 	--*)
-		__gitcomp "
-			--color --no-color --verbose --abbrev= --no-abbrev
-			--track --no-track --contains --no-contains --merged --no-merged
-			--set-upstream-to= --edit-description --list
-			--unset-upstream --delete --move --copy --remotes
-			--column --no-column --sort= --points-at
+		__gitcomp_builtin branch "--no-color --no-abbrev
+			--no-track --no-column
 			"
 		;;
 	*)
Signature · 1 line
2.16.1.205.g271f633410
#20 lore raw

PATCH v2 9/41 completion: use __gitcomp_builtin in _git_checkout

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--ignore-other-worktrees
--progress

---
 builtin/checkout.c                     |  7 +++++--
 contrib/completion/git-completion.bash |  6 +-----
 t/t9902-completion.sh                  | 12 +++++++-----
 3 files changed, 13 insertions(+), 12 deletions(-)
builtin/checkout.c +5 -2
index 2a96358eb7..a6218024a6 100644
@@ -1118,9 +1118,12 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			    2),
 		OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
 			    3),
-		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"), 0),
+		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
-		OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
+		OPT_BOOL_F(0, "overwrite-ignore", &opts.overwrite_ignore,
+			   N_("update ignored files (default)"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_STRING(0, "conflict", &conflict_style, N_("style"),
 			   N_("conflict style (merge or diff3)")),
 		OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
contrib/completion/git-completion.bash +1 -5
index 4a2858f09c..61880275ed 100644
@@ -1252,11 +1252,7 @@ _git_checkout ()
 		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
 		;;
 	--*)
-		__gitcomp "
-			--quiet --ours --theirs --track --no-track --merge
-			--conflict= --orphan --patch --detach --ignore-skip-worktree-bits
-			--recurse-submodules --no-recurse-submodules
-			"
+		__gitcomp_builtin checkout "--no-track --no-recurse-submodules"
 		;;
 	*)
 		# check if --track, --no-track, or --no-guess was specified
t/t9902-completion.sh +7 -5
index fc614dcbfa..e6485feb0a 100755
@@ -1237,17 +1237,19 @@ test_expect_success 'double dash "git" itself' '
 test_expect_success 'double dash "git checkout"' '
 	test_completion "git checkout --" <<-\EOF
 	--quiet Z
+	--detach Z
+	--track Z
+	--orphan=Z
 	--ours Z
 	--theirs Z
-	--track Z
-	--no-track Z
 	--merge Z
-	--conflict=
-	--orphan Z
+	--conflict=Z
 	--patch Z
-	--detach Z
 	--ignore-skip-worktree-bits Z
+	--ignore-other-worktrees Z
 	--recurse-submodules Z
+	--progress Z
+	--no-track Z
 	--no-recurse-submodules Z
 	EOF
 '
Signature · 1 line
2.16.1.205.g271f633410
#21 lore raw

PATCH v2 10/41 completion: use __gitcomp_builtin in _git_cherry_pick

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--allow-empty
--allow-empty-message
--ff
--gpg-sign
--keep-redundant-commits
--strategy-option

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 61880275ed..1b2e510cf6 100644
@@ -1281,7 +1281,7 @@ _git_cherry_pick ()
 	fi
 	case "$cur" in
 	--*)
-		__gitcomp "--edit --no-commit --signoff --strategy= --mainline"
+		__gitcomp_builtin cherry-pick
 		;;
 	*)
 		__git_complete_refs
Signature · 1 line
2.16.1.205.g271f633410
#22 lore raw

PATCH v2 11/41 completion: use __gitcomp_builtin in _git_clean

In reply to Nguyễn Thái Ngọc Duy

The new completable options are --exclude and --interactive

---
 builtin/clean.c                        | 2 +-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
builtin/clean.c +1 -1
index 3c4ca9a2ff..fad533a0a7 100644
@@ -909,7 +909,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__QUIET(&quiet, N_("do not print names of files removed")),
 		OPT__DRY_RUN(&dry_run, N_("dry run")),
-		OPT__FORCE(&force, N_("force"), 0),
+		OPT__FORCE(&force, N_("force"), PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")),
 		OPT_BOOL('d', NULL, &remove_directories,
 				N_("remove whole directories")),
contrib/completion/git-completion.bash +1 -1
index 1b2e510cf6..c0f6f76c3c 100644
@@ -1293,7 +1293,7 @@ _git_clean ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--dry-run --quiet"
+		__gitcomp_builtin clean
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#23 lore raw

PATCH v2 12/41 completion: use __gitcomp_builtin in _git_clone

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--config
--dissociate
--ipv4
--ipv6
--jobs=
--progress
--reference-if-able
--separate-git-dir=
--shallow-exclude
--shallow-since=
--verbose

---
 contrib/completion/git-completion.bash | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)
contrib/completion/git-completion.bash +1 -20
index c0f6f76c3c..393f86619d 100644
@@ -1306,26 +1306,7 @@ _git_clone ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--local
-			--no-hardlinks
-			--shared
-			--reference
-			--quiet
-			--no-checkout
-			--bare
-			--mirror
-			--origin
-			--upload-pack
-			--template=
-			--depth
-			--single-branch
-			--no-tags
-			--branch
-			--recurse-submodules
-			--no-single-branch
-			--shallow-submodules
-			"
+		__gitcomp_builtin clone "--no-single-branch"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#24 lore raw

PATCH v2 13/41 completion: use __gitcomp_builtin in _git_commit

In reply to Nguyễn Thái Ngọc Duy

The new comletable options are:

--branch
--gpg-sign
--long
--no-post-rewrite
--null
--porcelain
--status

--allow-empty is no longer completable because it's a hidden option since 4741edd549 (Remove deprecated OPTION_BOOLEAN for parsing arguments
- 2013-08-03)

---
 contrib/completion/git-completion.bash | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
contrib/completion/git-completion.bash +1 -10
index 393f86619d..8bbe94a94f 100644
@@ -1339,16 +1339,7 @@ _git_commit ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--all --author= --signoff --verify --no-verify
-			--edit --no-edit
-			--amend --include --only --interactive
-			--dry-run --reuse-message= --reedit-message=
-			--reset-author --file= --message= --template=
-			--cleanup= --untracked-files --untracked-files=
-			--verbose --quiet --fixup= --squash=
-			--patch --short --date --allow-empty
-			"
+		__gitcomp_builtin commit "--no-edit --verify"
 		return
 	esac
 
Signature · 1 line
2.16.1.205.g271f633410
#25 lore raw

Re: [PATCH v2 13/41] completion: use __gitcomp_builtin in _git_commit

Quoted 1 line · Nguyễn Thái Ngọc Duy

The new comletable options are:

s/comletable/completable/

Quoted 13 lines

--branch
--gpg-sign
--long
--no-post-rewrite
--null
--porcelain
--status

--allow-empty is no longer completable because it's a hidden option since 4741edd549 (Remove deprecated OPTION_BOOLEAN for parsing arguments
- 2013-08-03)

#26 lore raw

PATCH v2 14/41 completion: use __gitcomp_builtin in _git_config

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--blob=
--bool
--bool-or-int
--edit
--expiry-date
--get-color
--get-colorbool
--get-urlmatch
--includes
--int
--null
--path
--show-origin

---
 contrib/completion/git-completion.bash | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
contrib/completion/git-completion.bash +1 -8
index 8bbe94a94f..1713a583cf 100644
@@ -2238,14 +2238,7 @@ _git_config ()
 	esac
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--system --global --local --file=
-			--list --replace-all
-			--get --get-all --get-regexp
-			--add --unset --unset-all
-			--remove-section --rename-section
-			--name-only
-			"
+		__gitcomp_builtin config
 		return
 		;;
 	branch.*.*)
Signature · 1 line
2.16.1.205.g271f633410
#27 lore raw

PATCH v2 15/41 completion: use __gitcomp_builtin in _git_describe

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
contrib/completion/git-completion.bash +1 -5
index 1713a583cf..450d8e488e 100644
@@ -1355,11 +1355,7 @@ _git_describe ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--all --tags --contains --abbrev= --candidates=
-			--exact-match --debug --long --match --always --first-parent
-			--exclude --dirty --broken
-			"
+		__gitcomp_builtin describe
 		return
 	esac
 	__git_complete_refs
Signature · 1 line
2.16.1.205.g271f633410
#28 lore raw

PATCH v2 16/41 completion: use __gitcomp_builtin in _git_difftool

In reply to Nguyễn Thái Ngọc Duy

Since we can't automatically extract diff options for completion yet, difftool will take all options from $__git_diff_common_options. This brings _a lot_ more completable options to difftool.

--ignore-submodules is added to $__git_diff_common_options to avoid regression in difftool. But it's a good thing anyway even for other diff commands.

---
 contrib/completion/git-completion.bash | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
contrib/completion/git-completion.bash +6 -6
index 450d8e488e..255d60f12d 100644
@@ -1380,7 +1380,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
 			--dirstat --dirstat= --dirstat-by-file
 			--dirstat-by-file= --cumulative
 			--diff-algorithm=
-			--submodule --submodule=
+			--submodule --submodule= --ignore-submodules
 "
 
 _git_diff ()
@@ -1421,11 +1421,11 @@ _git_difftool ()
 		return
 		;;
 	--*)
-		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
-			--base --ours --theirs
-			--no-renames --diff-filter= --find-copies-harder
-			--relative --ignore-submodules
-			--tool="
+		__gitcomp_builtin difftool "$__git_diff_common_options
+					--base --cached --ours --theirs
+					--pickaxe-all --pickaxe-regex
+					--relative --staged
+					"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#29 lore raw

PATCH v2 17/41 completion: use __gitcomp_builtin in _git_fetch

In reply to Nguyễn Thái Ngọc Duy

New completable options:

--deepen=
--ipv4
--ipv6
--jobs=
--multiple
--progress
--refmap=
--shallow-exclude=
--shallow-since=
--update-head-ok

Since _git_pull() needs fetch options too, $__git_fetch_options remains. This variable will soon be gone after _git_pull() is updated.

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 255d60f12d..316dac84e0 100644
@@ -1448,7 +1448,7 @@ _git_fetch ()
 		return
 		;;
 	--*)
-		__gitcomp "$__git_fetch_options"
+		__gitcomp_builtin fetch "--no-tags"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#30 lore raw

PATCH v2 18/41 completion: use __gitcomp_builtin in _git_fsck

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--connectivity-only
--dangling
--progress
--reflogs

---
 contrib/completion/git-completion.bash | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
contrib/completion/git-completion.bash +1 -4
index 316dac84e0..4d25cfa047 100644
@@ -1485,10 +1485,7 @@ _git_fsck ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--tags --root --unreachable --cache --no-reflogs --full
-			--strict --verbose --lost-found --name-objects
-			"
+		__gitcomp_builtin fsck "--no-reflogs"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#31 lore raw

PATCH v2 19/41 completion: use __gitcomp_builtin in _git_gc

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --quiet.

---
 builtin/gc.c                           | 7 +++++--
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)
builtin/gc.c +5 -2
index 3c5eae0edf..7fc5c16254 100644
@@ -360,8 +360,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 			N_("prune unreferenced objects"),
 			PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
 		OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
-		OPT_BOOL(0, "auto", &auto_gc, N_("enable auto-gc mode")),
-		OPT_BOOL(0, "force", &force, N_("force running gc even if there may be another gc running")),
+		OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"),
+			   PARSE_OPT_NOCOMPLETE),
+		OPT_BOOL_F(0, "force", &force,
+			   N_("force running gc even if there may be another gc running"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
 
contrib/completion/git-completion.bash +1 -1
index 4d25cfa047..f694331cfc 100644
@@ -1495,7 +1495,7 @@ _git_gc ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--prune --aggressive"
+		__gitcomp_builtin gc
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#32 lore raw

PATCH v2 20/41 completion: use __gitcomp_builtin in _git_grep

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--after-context=
--before-context=
--color
--context
--exclude-standard
--quiet
--recurse-submodules
--textconv

---
 builtin/grep.c                         | 13 ++++++++-----
 contrib/completion/git-completion.bash | 16 +---------------
 2 files changed, 9 insertions(+), 20 deletions(-)
builtin/grep.c +8 -5
index 3ca4ac80d8..496f33336e 100644
@@ -832,8 +832,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		OPT_BOOL('L', "files-without-match",
 			&opt.unmatch_name_only,
 			N_("show only the names of files without match")),
-		OPT_BOOL('z', "null", &opt.null_following_name,
-			N_("print NUL after filenames")),
+		OPT_BOOL_F('z', "null", &opt.null_following_name,
+			   N_("print NUL after filenames"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('c', "count", &opt.count,
 			N_("show the number of matches instead of matching lines")),
 		OPT__COLOR(&opt.color, N_("highlight matches")),
@@ -884,9 +885,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		OPT_GROUP(""),
 		{ OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
 			N_("pager"), N_("show matching files in the pager"),
-			PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },
-		OPT_BOOL(0, "ext-grep", &external_grep_allowed__ignored,
-			 N_("allow calling of grep(1) (ignored by this build)")),
+			PARSE_OPT_OPTARG | PARSE_OPT_NOCOMPLETE,
+			NULL, (intptr_t)default_pager },
+		OPT_BOOL_F(0, "ext-grep", &external_grep_allowed__ignored,
+			   N_("allow calling of grep(1) (ignored by this build)"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
 
contrib/completion/git-completion.bash +1 -15
index f694331cfc..6e78737a13 100644
@@ -1551,21 +1551,7 @@ _git_grep ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--cached
-			--text --ignore-case --word-regexp --invert-match
-			--full-name --line-number
-			--extended-regexp --basic-regexp --fixed-strings
-			--perl-regexp
-			--threads
-			--files-with-matches --name-only
-			--files-without-match
-			--max-depth
-			--count
-			--and --or --not --all-match
-			--break --heading --show-function --function-context
-			--untracked --no-index
-			"
+		__gitcomp_builtin grep
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#33 lore raw

PATCH v2 21/41 completion: use __gitcomp_builtin in _git_help

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 6e78737a13..1e3cb39fde 100644
@@ -1569,7 +1569,7 @@ _git_help ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--all --guides --info --man --web"
+		__gitcomp_builtin help
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#34 lore raw

PATCH v2 22/41 completion: use __gitcomp_builtin in _git_init

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --separate-git-dir=.

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 1e3cb39fde..3e0973a562 100644
@@ -1592,7 +1592,7 @@ _git_init ()
 		return
 		;;
 	--*)
-		__gitcomp "--quiet --bare --template= --shared --shared="
+		__gitcomp_builtin init
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#35 lore raw

PATCH v2 23/41 completion: use __gitcomp_builtin in _git_ls_files

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--debug
--empty-directory
--eol
--recurse-submodules
--resolve-undo

---
 contrib/completion/git-completion.bash | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
contrib/completion/git-completion.bash +1 -7
index 3e0973a562..e65e71760f 100644
@@ -1602,13 +1602,7 @@ _git_ls_files ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--cached --deleted --modified --others --ignored
-			--stage --directory --no-empty-directory --unmerged
-			--killed --exclude= --exclude-from=
-			--exclude-per-directory= --exclude-standard
-			--error-unmatch --with-tree= --full-name
-			--abbrev --ignored --exclude-per-directory
-			"
+		__gitcomp_builtin ls-files "--no-empty-directory"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#36 lore raw

PATCH v2 24/41 completion: use __gitcomp_builtin in _git_ls_remote

In reply to Nguyễn Thái Ngọc Duy

The new completable options are --quiet and --upload-pack=.

---
 builtin/ls-remote.c                    | 5 +++--
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)
builtin/ls-remote.c +3 -2
index c4be98ab9e..540d56429f 100644
@@ -60,8 +60,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 		OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
 		OPT_BOOL(0, "get-url", &get_url,
 			 N_("take url.<base>.insteadOf into account")),
-		OPT_SET_INT(0, "exit-code", &status,
-			    N_("exit with exit code 2 if no matching refs are found"), 2),
+		OPT_SET_INT_F(0, "exit-code", &status,
+			      N_("exit with exit code 2 if no matching refs are found"),
+			      2, PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "symref", &show_symref_target,
 			 N_("show underlying ref in addition to the object pointed by it")),
 		OPT_END()
contrib/completion/git-completion.bash +1 -1
index e65e71760f..f1eb37fbff 100644
@@ -1616,7 +1616,7 @@ _git_ls_remote ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--heads --tags --refs --get-url --symref"
+		__gitcomp_builtin ls-remote
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#37 lore raw

PATCH v2 25/41 completion: use __gitcomp_builtin in _git_merge

In reply to Nguyễn Thái Ngọc Duy

New completable options are:

--allow-unrelated-histories
--message=
--overwrite-ignore
--signoff
--strategy-option=
--summary
--verify

The variable $__git_merge_options remains because _git_pull() still needs it. It will soon be gone after _git_pull() is updated.

---
 contrib/completion/git-completion.bash | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
contrib/completion/git-completion.bash +7 -2
index f1eb37fbff..52baa7869f 100644
@@ -1754,8 +1754,13 @@ _git_merge ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "$__git_merge_options
-			--rerere-autoupdate --no-rerere-autoupdate --abort --continue"
+		__gitcomp_builtin merge "--rerere-autoupdate
+				--no-rerere-autoupdate
+				--no-commit --no-edit --no-ff
+				--no-log --no-progress
+				--no-squash --no-stat
+				--no-verify-signatures
+				"
 		return
 	esac
 	__git_complete_refs
Signature · 1 line
2.16.1.205.g271f633410
#38 lore raw

PATCH v2 26/41 completion: use __gitcomp_builtin in _git_merge_base

In reply to Nguyễn Thái Ngọc Duy

The new completion option is --all.

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 52baa7869f..1bf1728b95 100644
@@ -1784,7 +1784,7 @@ _git_merge_base ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--octopus --independent --is-ancestor --fork-point"
+		__gitcomp_builtin merge-base
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#39 lore raw

PATCH v2 27/41 completion: use __gitcomp_builtin in _git_mv

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --verbose.

---
 builtin/mv.c                           | 3 ++-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
builtin/mv.c +2 -1
index b88023a733..e3e308d282 100644
@@ -122,7 +122,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 	struct option builtin_mv_options[] = {
 		OPT__VERBOSE(&verbose, N_("be verbose")),
 		OPT__DRY_RUN(&show_only, N_("dry run")),
-		OPT__FORCE(&force, N_("force move/rename even if target exists"), 0),
+		OPT__FORCE(&force, N_("force move/rename even if target exists"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
 		OPT_END(),
 	};
contrib/completion/git-completion.bash +1 -1
index 1bf1728b95..0e36190a19 100644
@@ -1795,7 +1795,7 @@ _git_mv ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--dry-run"
+		__gitcomp_builtin mv
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#40 lore raw

PATCH v2 28/41 completion: use __gitcomp_builtin in _git_name_rev

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--always
--exclude
--name-only
--refs
--undefined

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 0e36190a19..391074a772 100644
@@ -1811,7 +1811,7 @@ _git_mv ()
 
 _git_name_rev ()
 {
-	__gitcomp "--tags --all --stdin"
+	__gitcomp_builtin name-rev
 }
 
 _git_notes ()
Signature · 1 line
2.16.1.205.g271f633410
#41 lore raw

PATCH v2 29/41 completion: use __gitcomp_builtin in _git_notes

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--allow-empty (notes add and notes append)
--for-rewrite= (notes copy)

---
 builtin/notes.c                        |  4 ++--
 contrib/completion/git-completion.bash | 14 ++++++++------
 2 files changed, 10 insertions(+), 8 deletions(-)
builtin/notes.c +2 -2
index b52e71c73e..6990683bd4 100644
@@ -413,7 +413,7 @@ static int add(int argc, const char **argv, const char *prefix)
 			parse_reuse_arg},
 		OPT_BOOL(0, "allow-empty", &allow_empty,
 			N_("allow storing empty note")),
-		OPT__FORCE(&force, N_("replace existing notes"), 0),
+		OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
 
@@ -484,7 +484,7 @@ static int copy(int argc, const char **argv, const char *prefix)
 	struct notes_tree *t;
 	const char *rewrite_cmd = NULL;
 	struct option options[] = {
-		OPT__FORCE(&force, N_("replace existing notes"), 0),
+		OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")),
 		OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"),
 			   N_("load rewriting config for <command> (implies "
contrib/completion/git-completion.bash +8 -6
index 391074a772..14af9457af 100644
@@ -1821,7 +1821,7 @@ _git_notes ()
 
 	case "$subcommand,$cur" in
 	,--*)
-		__gitcomp '--ref'
+		__gitcomp_builtin notes
 		;;
 	,*)
 		case "$prev" in
@@ -1837,15 +1837,17 @@ _git_notes ()
 	add,--reedit-message=*|append,--reedit-message=*)
 		__git_complete_refs --cur="${cur#*=}"
 		;;
-	add,--*|append,--*)
-		__gitcomp '--file= --message= --reedit-message=
-				--reuse-message='
+	add,--*)
+		__gitcomp_builtin notes_add
+		;;
+	append,--*)
+		__gitcomp_builtin notes_append
 		;;
 	copy,--*)
-		__gitcomp '--stdin'
+		__gitcomp_builtin notes_copy
 		;;
 	prune,--*)
-		__gitcomp '--dry-run --verbose'
+		__gitcomp_builtin notes_prune
 		;;
 	prune,*)
 		;;
Signature · 1 line
2.16.1.205.g271f633410
#42 lore raw

PATCH v2 30/41 completion: use __gitcomp_builtin in _git_pull

In reply to Nguyễn Thái Ngọc Duy

This is really nice. Since pull_options[] already declares all passthru options to 'merge' or 'fetch', a single

    git pull --git-completion-helper

would provide all completable options (--no- variants are a separate issue). Dead shell variables can now be deleted.

New completable options are:

--allow-unrelated-histories
--ipv4
--ipv6
--jobs
--refmap=
--signoff
--strategy-option=

---
 contrib/completion/git-completion.bash | 25 +++++--------------------
 1 file changed, 5 insertions(+), 20 deletions(-)
contrib/completion/git-completion.bash +5 -20
index 14af9457af..225507b751 100644
@@ -1434,12 +1434,6 @@ _git_difftool ()
 
 __git_fetch_recurse_submodules="yes on-demand no"
 
-__git_fetch_options="
-	--quiet --verbose --append --upload-pack --force --keep --depth=
-	--tags --no-tags --all --prune --dry-run --recurse-submodules=
-	--unshallow --update-shallow
-"
-
 _git_fetch ()
 {
 	case "$cur" in
@@ -1740,14 +1734,6 @@ _git_log ()
 	__git_complete_revlist
 }
 
-# Common merge options shared by git-merge(1) and git-pull(1).
-__git_merge_options="
-	--no-commit --no-stat --log --no-log --squash --strategy
-	--commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
-	--verify-signatures --no-verify-signatures --gpg-sign
-	--quiet --verbose --progress --no-progress
-"
-
 _git_merge ()
 {
 	__git_complete_strategy && return
@@ -1873,12 +1859,11 @@ _git_pull ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--rebase --no-rebase
-			--autostash --no-autostash
-			$__git_merge_options
-			$__git_fetch_options
-		"
+		__gitcomp_builtin pull "--no-autostash --no-commit --no-edit
+					--no-ff --no-log --no-progress --no-rebase
+					--no-squash --no-stat --no-tags
+					--no-verify-signatures"
+
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#43 lore raw

PATCH v2 31/41 completion: use __gitcomp_builtin in _git_push

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--atomic
--exec=
--ipv4
--ipv6
--no-verify
--porcelain
--progress
--push-option
--signed

---
 builtin/push.c                         | 2 +-
 contrib/completion/git-completion.bash | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)
builtin/push.c +1 -1
index 1c28427d82..013c20d616 100644
@@ -548,7 +548,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		{ OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, "check|on-demand|no",
 			N_("control recursive pushing of submodules"),
 			PARSE_OPT_OPTARG, option_parse_recurse_submodules },
-		OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")),
+		OPT_BOOL_F( 0 , "thin", &thin, N_("use thin pack"), PARSE_OPT_NOCOMPLETE),
 		OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
 		OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
 		OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
contrib/completion/git-completion.bash +1 -6
index 225507b751..8233dede74 100644
@@ -1914,12 +1914,7 @@ _git_push ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--all --mirror --tags --dry-run --force --verbose
-			--quiet --prune --delete --follow-tags
-			--receive-pack= --repo= --set-upstream
-			--force-with-lease --force-with-lease= --recurse-submodules=
-		"
+		__gitcomp_builtin push
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#44 lore raw

PATCH v2 32/41 completion: use __gitcomp_builtin in _git_remote

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
contrib/completion/git-completion.bash +8 -8
index 8233dede74..7431ffc750 100644
@@ -2598,7 +2598,7 @@ _git_remote ()
 	if [ -z "$subcommand" ]; then
 		case "$cur" in
 		--*)
-			__gitcomp "--verbose"
+			__gitcomp_builtin remote
 			;;
 		*)
 			__gitcomp "$subcommands"
@@ -2609,33 +2609,33 @@ _git_remote ()
 
 	case "$subcommand,$cur" in
 	add,--*)
-		__gitcomp "--track --master --fetch --tags --no-tags --mirror="
+		__gitcomp_builtin remote_add "--no-tags"
 		;;
 	add,*)
 		;;
 	set-head,--*)
-		__gitcomp "--auto --delete"
+		__gitcomp_builtin remote_set-head
 		;;
 	set-branches,--*)
-		__gitcomp "--add"
+		__gitcomp_builtin remote_set-branches
 		;;
 	set-head,*|set-branches,*)
 		__git_complete_remote_or_refspec
 		;;
 	update,--*)
-		__gitcomp "--prune"
+		__gitcomp_builtin remote_update
 		;;
 	update,*)
 		__gitcomp "$(__git_get_config_variables "remotes")"
 		;;
 	set-url,--*)
-		__gitcomp "--push --add --delete"
+		__gitcomp_builtin remote_set-url
 		;;
 	get-url,--*)
-		__gitcomp "--push --all"
+		__gitcomp_builtin remote_get-url
 		;;
 	prune,--*)
-		__gitcomp "--dry-run"
+		__gitcomp_builtin remote_prune
 		;;
 	*)
 		__gitcomp_nl "$(__git_remotes)"
Signature · 1 line
2.16.1.205.g271f633410
#45 lore raw

PATCH v2 33/41 remote: force completing --mirror= instead of --mirror

In reply to Nguyễn Thái Ngọc Duy

"git remote --mirror" is a special case. Technically it is possible to specify --mirror without any argument. But we will get a "dangerous, deprecated!" warning in that case.

This new parse-opt flag allows --git-completion-helper to always complete --mirror=, ignoring the dangerous use case.

---
 builtin/remote.c | 2 +-
 parse-options.c  | 2 ++
 parse-options.h  | 6 +++++-
 3 files changed, 8 insertions(+), 2 deletions(-)
builtin/remote.c +1 -1
index d95bf904c3..fce9e5c0f6 100644
@@ -168,7 +168,7 @@ static int add(int argc, const char **argv)
 		OPT_STRING('m', "master", &master, N_("branch"), N_("master branch")),
 		{ OPTION_CALLBACK, 0, "mirror", &mirror, N_("push|fetch"),
 			N_("set up remote as a mirror to push to or fetch from"),
-			PARSE_OPT_OPTARG, parse_mirror_opt },
+			PARSE_OPT_OPTARG | PARSE_OPT_COMP_ARG, parse_mirror_opt },
 		OPT_END()
 	};
 
parse-options.c +2 -0
index 29f4defdd6..979577ba2c 100644
@@ -459,6 +459,8 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 		default:
 			break;
 		}
+		if (opts->flags & PARSE_OPT_COMP_ARG)
+			suffix = "=";
 		printf(" --%s%s", opts->long_name, suffix);
 	}
 	fputc('\n', stdout);
parse-options.h +5 -1
index fa75df17b4..f63151fbda 100644
@@ -39,7 +39,8 @@ enum parse_opt_option_flags {
 	PARSE_OPT_NODASH = 32,
 	PARSE_OPT_LITERAL_ARGHELP = 64,
 	PARSE_OPT_SHELL_EVAL = 256,
-	PARSE_OPT_NOCOMPLETE = 512
+	PARSE_OPT_NOCOMPLETE = 512,
+	PARSE_OPT_COMP_ARG = 1024
 };
 
 struct option;
@@ -92,6 +93,9 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
  *				Useful for options with multiple parameters.
  *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
  *			   git-completion.bash. This option suppresses that.
+ *   PARSE_OPT_COMP_ARG: this option forces to git-completion.bash to
+ *			 complete an option as --name= not --name even if
+ *			 the option takes optional argument.
  *
  * `callback`::
  *   pointer to the callback to use for OPTION_CALLBACK or
Signature · 1 line
2.16.1.205.g271f633410
#46 lore raw

PATCH v2 34/41 completion: use __gitcomp_builtin in _git_replace

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --raw.

---
 builtin/replace.c                      | 3 ++-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
builtin/replace.c +2 -1
index 10078ae371..0c1d8e1b08 100644
@@ -439,7 +439,8 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
 		OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
 		OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
 		OPT_CMDMODE('g', "graft", &cmdmode, N_("change a commit's parents"), MODE_GRAFT),
-		OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")),
+		OPT_BOOL_F('f', "force", &force, N_("replace the ref if it exists"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "raw", &raw, N_("do not pretty-print contents for --edit")),
 		OPT_STRING(0, "format", &format, N_("format"), N_("use this format")),
 		OPT_END()
contrib/completion/git-completion.bash +1 -1
index 7431ffc750..2f3f11451d 100644
@@ -2647,7 +2647,7 @@ _git_replace ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--edit --graft --format= --list --delete"
+		__gitcomp_builtin replace
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#47 lore raw

PATCH v2 35/41 completion: use __gitcomp_builtin in _git_reset

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--intent-to-add
--quiet
--recurse-submodules

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 2f3f11451d..a830c9c854 100644
@@ -2671,7 +2671,7 @@ _git_reset ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "--merge --mixed --hard --soft --patch --keep"
+		__gitcomp_builtin reset
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#48 lore raw

PATCH v2 36/41 completion: use __gitcomp_builtin in _git_revert

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --gpg-sign

---
 builtin/revert.c                       | 12 +++++++++---
 contrib/completion/git-completion.bash |  5 +----
 2 files changed, 10 insertions(+), 7 deletions(-)
builtin/revert.c +9 -3
index b9d927eb09..c8e045911b 100644
@@ -96,9 +96,15 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
 	const char *me = action_name(opts);
 	int cmd = 0;
 	struct option base_options[] = {
-		OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
-		OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
-		OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
+		OPT_CMDMODE_F(0, "quit", &cmd,
+			      N_("end revert or cherry-pick sequence"),
+			      'q', PARSE_OPT_NOCOMPLETE),
+		OPT_CMDMODE_F(0, "continue", &cmd,
+			      N_("resume revert or cherry-pick sequence"),
+			      'c', PARSE_OPT_NOCOMPLETE),
+		OPT_CMDMODE_F(0, "abort", &cmd,
+			      N_("cancel revert or cherry-pick sequence"),
+			      'a', PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")),
 		OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")),
 		OPT_NOOP_NOARG('r', NULL),
contrib/completion/git-completion.bash +1 -4
index a830c9c854..d6215c494e 100644
@@ -2687,10 +2687,7 @@ _git_revert ()
 	fi
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--edit --mainline --no-edit --no-commit --signoff
-			--strategy= --strategy-option=
-			"
+		__gitcomp_builtin revert "--no-edit"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#49 lore raw

PATCH v2 37/41 completion: use __gitcomp_builtin in _git_rm

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 builtin/rm.c                           | 2 +-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
builtin/rm.c +1 -1
index 6e0c7f5ac6..a818efe230 100644
@@ -242,7 +242,7 @@ static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__QUIET(&quiet, N_("do not list removed files")),
 	OPT_BOOL( 0 , "cached",         &index_only, N_("only remove from the index")),
-	OPT__FORCE(&force, N_("override the up-to-date check"), 0),
+	OPT__FORCE(&force, N_("override the up-to-date check"), PARSE_OPT_NOCOMPLETE),
 	OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
 	OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
 				N_("exit with a zero status even if nothing matched")),
contrib/completion/git-completion.bash +1 -1
index d6215c494e..e5a9f7f9b4 100644
@@ -2698,7 +2698,7 @@ _git_rm ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
+		__gitcomp_builtin rm
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#50 lore raw

PATCH v2 38/41 completion: use __gitcomp_builtin in _git_show_branch

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
contrib/completion/git-completion.bash +1 -6
index e5a9f7f9b4..3722c6444a 100644
@@ -2756,12 +2756,7 @@ _git_show_branch ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--all --remotes --topo-order --date-order --current --more=
-			--list --independent --merge-base --no-name
-			--color --no-color
-			--sha1-name --sparse --topics --reflog
-			"
+		__gitcomp_builtin show-branch "--no-color"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#51 lore raw

PATCH v2 39/41 completion: use __gitcomp_builtin in _git_status

In reply to Nguyễn Thái Ngọc Duy

The new completable options are --null and --show-stash.

---
 contrib/completion/git-completion.bash | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
contrib/completion/git-completion.bash +1 -5
index 3722c6444a..ba9438e437 100644
@@ -2052,11 +2052,7 @@ _git_status ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--short --branch --porcelain --long --verbose
-			--untracked-files= --ignore-submodules= --ignored
-			--column= --no-column
-			"
+		__gitcomp_builtin status "--no-column"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.205.g271f633410
#52 lore raw

PATCH v2 40/41 completion: use __gitcomp_builtin in _git_tag

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--color
--format=
--ignore-case

---
 contrib/completion/git-completion.bash | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
contrib/completion/git-completion.bash +1 -5
index ba9438e437..179ddd8c44 100644
@@ -2985,11 +2985,7 @@ _git_tag ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--list --delete --verify --annotate --message --file
-			--sign --cleanup --local-user --force --column --sort=
-			--contains --no-contains --points-at --merged --no-merged --create-reflog
-			"
+		__gitcomp_builtin tag
 		;;
 	esac
 }
Signature · 1 line
2.16.1.205.g271f633410
#53 lore raw

PATCH v2 41/41 completion: use __gitcomp_builtin in _git_worktree

In reply to Nguyễn Thái Ngọc Duy

The new completable options for "worktree add" are:

--checkout
--guess-remote
--lock
--track

---
 builtin/worktree.c                     | 2 +-
 contrib/completion/git-completion.bash | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)
builtin/worktree.c +1 -1
index 4d3422f62e..76dc6b8cb5 100644
@@ -367,7 +367,7 @@ static int add(int ac, const char **av, const char *prefix)
 	struct option options[] = {
 		OPT__FORCE(&opts.force,
 			   N_("checkout <branch> even if already checked out in other worktree"),
-			   0),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
 			   N_("create a new branch")),
 		OPT_STRING('B', NULL, &new_branch_force, N_("branch"),
contrib/completion/git-completion.bash +4 -4
index 179ddd8c44..cfd24c5764 100644
@@ -3004,16 +3004,16 @@ _git_worktree ()
 	else
 		case "$subcommand,$cur" in
 		add,--*)
-			__gitcomp "--detach"
+			__gitcomp_builtin worktree_add
 			;;
 		list,--*)
-			__gitcomp "--porcelain"
+			__gitcomp_builtin worktree_list
 			;;
 		lock,--*)
-			__gitcomp "--reason"
+			__gitcomp_builtin worktree_lock
 			;;
 		prune,--*)
-			__gitcomp "--dry-run --expire --verbose"
+			__gitcomp_builtin worktree_prune
 			;;
 		*)
 			;;
Signature · 1 line
2.16.1.205.g271f633410
#54 lore raw
In reply to Nguyễn Thái Ngọc Duy

On Wed, Jan 31 2018, Nguyễn Thái Ngọc Duy jotted:

Quoted 17 lines

I posted a proof of concept a while back [1]. This is the full version.

This series lets "git" binary help git-completion.bash to complete --<stuff> so that when a new option is added, we don't have to update git-completion.bash manually too (people often forget it). As a side effect, about 180 more options are now completable.

parse-options is updated to allow developers to flag certain options not to be completable if they want finer control over it. But by default, new non-hidden options are completable. Negative forms must be handled manually. That's for the next step.

The number of patches is high, but changes after the first four patches and 33/41 are quite simple. I still need some eyeballs though to make sure I have not accidentally allowed completion of dangerous options. Details are broken down per command in each commit message.

Quoted 4 lines

If people want to play with this, I have a script [2] that shows all completable options for most commands (I ignore some that are shell-based because I don't touch them in this series). You can then do a "diff" to see new/old options.

Thanks, looks great to me, especially caching the result of the completion.

Quoted 3 lines

There's a small conflict with 'pu' because --prune-tags is added in git-completion.bash. The solution is simple and beautiful: ignore those changes, --prune-tags will be completable anyway :)

Yay! Also another good argument for this series, it took me until v3 until I noticed I'd forgotten the bash completion:
https://public-inbox.org/git/[email protected]/

Quoted 1 line

parse-options: add OPT_xxx_F() variants

Not directly related to this series, but my own
https://public-inbox.org/git/[email protected]/
which I've been meaning to clean up and re-submit also added some new macros to this file.

I've been wondering what a good solution is to avoid a combinatorial explosion explosion of these macros in the longer term, but haven't come up with anthing.

#55 lore raw
In reply to Nguyễn Thái Ngọc Duy
Quoted 11 lines · Nguyễn Thái Ngọc Duy

I posted a proof of concept a while back [1]. This is the full version.

This series lets "git" binary help git-completion.bash to complete --<stuff> so that when a new option is added, we don't have to update git-completion.bash manually too (people often forget it). As a side effect, about 180 more options are now completable.

parse-options is updated to allow developers to flag certain options not to be completable if they want finer control over it. But by default, new non-hidden options are completable. Negative forms must be handled manually. That's for the next step.

Everybody seems to be in favour of the approach taken by this series. Is it in a good enough shape that we can merge it to 'next' and then go incremental from now on? Or do we want to keep it in 'pu' to give easier access to volunteer guinea pigs and wait until the way to handle '--no-foo' options are figured out?

author
#56 lore raw
Quoted 9 lines · Junio C Hamano
Quoted 7 lines · Nguyễn Thái Ngọc Duy

I posted a proof of concept a while back [1]. This is the full version.

This series lets "git" binary help git-completion.bash to complete --<stuff> so that when a new option is added, we don't have to update git-completion.bash manually too (people often forget it). As a side effect, about 180 more options are now completable.

Quoted 8 lines
Quoted 4 lines

parse-options is updated to allow developers to flag certain options not to be completable if they want finer control over it. But by default, new non-hidden options are completable. Negative forms must be handled manually. That's for the next step.

Everybody seems to be in favour of the approach taken by this series. Is it in a good enough shape that we can merge it to 'next' and then go incremental from now on?

Not until v3. v2 breaks Mac OS because I used some fancy bash feature. There are some good improvements in __gitcomp_builtin() suggested by Eric and Szeder, which will be in v3 as well.

Quoted 3 lines

Or do we want to keep it in
'pu' to give easier access to volunteer guinea pigs and wait until the way to handle '--no-foo' options are figured out?

Oh the --no-foo thing is definitely not part of this version. Once this series lands though, people can start improving --no-foo per command, even in parallel. "git foo -h" will also benefit from that effort because we will be able to show --no- form only when we mean to allow --no-.

Signature · 1 line
Duy
#57 lore raw

v3 cover Automate updating git-completion.bash a bit

In reply to Nguyễn Thái Ngọc Duy

v3 improves __gitcomp_builtin() function a bit to allows both adding extra options (to complement --git-completion-helper limitations) and removing options.

v3 should also fix Mac OS breakage.

The last change in 42/42 is a new configurable variable in git-completion.bash that allows you to complete _all_ options, including ones that are filtered out by default. For the record there are 22 of them with the following counts:

     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

The first 41 patches should be ok to enter 'next' unless people find something else. 42/42 may be a bit more questionable (e.g. configuration variable name, or how we pass options to --git-completion-helper...) and might have to stay on 'pu' longer.

Interdiff with v2 below. I remove changes that are reverts back to 'master' to reduce the noise a bit.

contrib/completion/git-completion.bash +32 -11
index cfd24c5764..0cfa489a8e 100644
@@ -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
 
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
@@ -284,24 +288,33 @@ __gitcomp ()
 #
 #    __gitcomp "$(git xxx --git-completion-helper) ..."
 #
-# except that the value from $(git) is cached
+# except that the output is cached. Accept 1-3 arguments:
+# 1: the git command to execute, this is also the cache key
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
 __gitcomp_builtin ()
 {
 	# spaces must be replaced with underscore for multi-word
 	# commands, e.g. "git remote add" becomes remote_add.
 	local cmd="$1"
-	shift
+	local incl="$2"
+	local excl="$3"
 
 	local var=__gitcomp_builtin_"${cmd/-/_}"
 	local options
 	eval "options=\$$var"
 
 	if [ -z "$options" ]; then
-		declare -g "$var=$(__git ${cmd/_/ } --git-completion-helper)"
-		eval "options=\$$var"
+		# leading and trailing spaces are significant to make
+		# option removal work correctly.
+		options=" $(__git ${cmd/_/ } --git-completion-helper=$GIT_COMPLETION_OPTIONS) $incl "
+		for i in $excl; do
+			options="${options/ $i / }"
+		done
+		eval "$var=\"$options\""
 	fi
 
-	__gitcomp "$options $*"
+	__gitcomp "$options"
 }
 
 # Variation of __gitcomp_nl () that appends to the existing list of
@@ -1096,12 +1109,13 @@ __git_count_arguments ()
 }
 
 __git_whitespacelist="nowarn warn error error-all fix"
+__git_am_inprogress_options="--skip --continue --resolved --abort"
 
 _git_am ()
 {
 	__git_find_repo_path
 	if [ -d "$__git_repo_path"/rebase-apply ]; then
-		__gitcomp "--skip --continue --resolved --abort"
+		__gitcomp "$__git_am_inprogress_options"
 		return
 	fi
 	case "$cur" in
@@ -1110,7 +1124,8 @@ _git_am ()
 		return
 		;;
 	--*)
-		__gitcomp_builtin am "--no-utf8"
+		__gitcomp_builtin am "--no-utf8" \
+			"$__git_am_inprogress_options"
 		return
 	esac
 }
@@ -1272,16 +1287,19 @@ _git_cherry ()
 	__git_complete_refs
 }
 
+__git_cherry_pick_inprogress_options="--continue --quit --abort"
+
 _git_cherry_pick ()
 {
 	__git_find_repo_path
 	if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then
-		__gitcomp "--continue --quit --abort"
+		__gitcomp "$__git_cherry_pick_inprogress_options"
 		return
 	fi
 	case "$cur" in
 	--*)
-		__gitcomp_builtin cherry-pick
+		__gitcomp_builtin cherry-pick "" \
+			"$__git_cherry_pick_inprogress_options"
 		;;
 	*)
 		__git_complete_refs
@@ -2674,16 +2692,19 @@ _git_reset ()
 	__git_complete_refs
 }
 
+__git_revert_inprogress_options="--continue --quit --abort"
+
 _git_revert ()
 {
 	__git_find_repo_path
 	if [ -f "$__git_repo_path"/REVERT_HEAD ]; then
-		__gitcomp "--continue --quit --abort"
+		__gitcomp "$__git_revert_inprogress_options"
 		return
 	fi
 	case "$cur" in
 	--*)
-		__gitcomp_builtin revert "--no-edit"
+		__gitcomp_builtin revert "--no-edit" \
+			"$__git_revert_inprogress_options"
 		return
 		;;
 	esac
parse-options.c +7 -4
index 979577ba2c..5b8b2b376e 100644
@@ -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;
parse-options.h +1 -1
index f63151fbda..0ba08691e6 100644
@@ -92,7 +92,7 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
  *				(i.e. '<argh>') in the help message.
  *				Useful for options with multiple parameters.
  *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
- *			   git-completion.bash. This option suppresses that.
+ *			   by git-completion.bash. This option suppresses that.
  *   PARSE_OPT_COMP_ARG: this option forces to git-completion.bash to
  *			 complete an option as --name= not --name even if
  *			 the option takes optional argument.
Signature · 1 line
2.16.1.207.gedba492059
#58 lore raw

PATCH v3 1/42 parse-options: support --git-completion-helper

This option is designed to be used by git-completion.bash. For many simple cases, what we do in there is usually

__gitcomp "lots of completion options"

which has to be manually updated when a new user-visible option is added. With support from parse-options, we can write

    __gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular options could be hidden with the new "NOCOMPLETE" flag.

---
 parse-options.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 parse-options.h |  5 ++++-
 2 files changed, 48 insertions(+), 1 deletion(-)
parse-options.c +44 -0
index fca7159646..29f4defdd6 100644
@@ -425,6 +425,46 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
 	parse_options_check(options);
 }
 
+/*
+ * TODO: we are not completing the --no-XXX form yet because there are
+ * many options that do not suppress it properly.
+ */
+static int show_gitcomp(struct parse_opt_ctx_t *ctx,
+			const struct option *opts)
+{
+	for (; opts->type != OPTION_END; opts++) {
+		const char *suffix = "";
+
+		if (!opts->long_name)
+			continue;
+		if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+			continue;
+
+		switch (opts->type) {
+		case OPTION_GROUP:
+			continue;
+		case OPTION_STRING:
+		case OPTION_FILENAME:
+		case OPTION_INTEGER:
+		case OPTION_MAGNITUDE:
+		case OPTION_CALLBACK:
+			if (opts->flags & PARSE_OPT_NOARG)
+				break;
+			if (opts->flags & PARSE_OPT_OPTARG)
+				break;
+			if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
+				break;
+			suffix = "=";
+			break;
+		default:
+			break;
+		}
+		printf(" --%s%s", opts->long_name, suffix);
+	}
+	fputc('\n', stdout);
+	exit(0);
+}
+
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
 				       const char * const *,
 				       const struct option *, int, int);
@@ -455,6 +495,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 		if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
 			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 (arg[1] != '-') {
 			ctx->opt = arg + 1;
 			switch (parse_short_opt(ctx, options)) {
parse-options.h +4 -1
index af711227ae..a5caa0bb1d 100644
@@ -38,7 +38,8 @@ enum parse_opt_option_flags {
 	PARSE_OPT_LASTARG_DEFAULT = 16,
 	PARSE_OPT_NODASH = 32,
 	PARSE_OPT_LITERAL_ARGHELP = 64,
-	PARSE_OPT_SHELL_EVAL = 256
+	PARSE_OPT_SHELL_EVAL = 256,
+	PARSE_OPT_NOCOMPLETE = 512
 };
 
 struct option;
@@ -89,6 +90,8 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
  *   PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in brackets
  *				(i.e. '<argh>') in the help message.
  *				Useful for options with multiple parameters.
+ *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
+ *			   by git-completion.bash. This option suppresses that.
  *
  * `callback`::
  *   pointer to the callback to use for OPTION_CALLBACK or
Signature · 1 line
2.16.1.207.gedba492059
#59 lore raw

Re: [PATCH v3 01/42] parse-options: support --git-completion-helper

parse-options.c void parse_options_start(struct parse_opt_ctx_t *ctx, · line 434

Quoted 3 lines · Nguyễn Thái Ngọc Duy
parse-options.c +3 -0
+static int show_gitcomp(struct parse_opt_ctx_t *ctx,
+			const struct option *opts)
+{

Says it returns 'static int'...

parse-options.c void parse_options_start(struct parse_opt_ctx_t *ctx, · line 465

Quoted 2 lines

[...]

parse-options.c +1 -0
+	exit(0);

Then just exits...

parse-options.c int parse_options_step(struct parse_opt_ctx_t *ctx, · line 500

Quoted 3 lines
parse-options.c +3 -0
+		/* 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);

This return value is never used.

Whine from SunCC (not fatal, also this was in v2.17.0 so no need to fix before 2.20, just saw this now):

"parse-options.c", line 520: warning: Function has no return statement : show_gitcomp

#60 lore raw

PATCH 1/1 parse-options: fix SunCC compiler warning

The compiler reports this because show_gitcomp() never actually returns a value:

"parse-options.c", line 520: warning: Function has no return statement : show_gitcomp

The function calls exit() and will never return. Update and mark it NORETURN.

---
 parse-options.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
parse-options.c +3 -3
index 3b874a83a0..6577e52f63 100644
@@ -474,8 +474,8 @@ static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
 	}
 }
 
-static int show_gitcomp(struct parse_opt_ctx_t *ctx,
-			const struct option *opts)
+static void NORETURN show_gitcomp(struct parse_opt_ctx_t *ctx,
+				  const struct option *opts)
 {
 	const struct option *original_opts = opts;
 	int nr_noopts = 0;
@@ -550,7 +550,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 
 		/* 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);
+			show_gitcomp(ctx, options);
 
 		if (arg[1] != '-') {
 			ctx->opt = arg + 1;
Signature · 1 line
2.20.0.rc2.486.g9832c05c3d
#61 lore raw

Re: [PATCH] parse-options: fix SunCC compiler warning

Quoted 8 lines · Nguyễn Thái Ngọc Duy

The compiler reports this because show_gitcomp() never actually returns a value:

"parse-options.c", line 520: warning: Function has no return statement : show_gitcomp

The function calls exit() and will never return. Update and mark it NORETURN.

Yuck. This should do for now, but I am not impressed by the choice to hook show_gitcomp() call into parse_options_step(), which forces such an abnormal exit deeper in the callchain [*1*]. For readers (not compilers), it would help to have a comment at the caller that says that show_gitcomp() never returns and exits.

side note #1. Perhaps parse_options_start() would have been a better place, instead of parse_options_step() that is repeatedly called in a loop and itself has a loop. ANd worse yet, the check is done inside the loop even though the call is to be made only when the --git-completion-helper option is given as the sole request.

Thanks.

Quoted 30 lines
---
 parse-options.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
parse-options.c +3 -3
index 3b874a83a0..6577e52f63 100644
@@ -474,8 +474,8 @@ static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
 	}
 }
 
-static int show_gitcomp(struct parse_opt_ctx_t *ctx,
-			const struct option *opts)
+static void NORETURN show_gitcomp(struct parse_opt_ctx_t *ctx,
+				  const struct option *opts)
 {
 	const struct option *original_opts = opts;
 	int nr_noopts = 0;
@@ -550,7 +550,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 
 		/* 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);
+			show_gitcomp(ctx, options);
 
 		if (arg[1] != '-') {
 			ctx->opt = arg + 1;
author
#62 lore raw

Re: [PATCH] parse-options: fix SunCC compiler warning

Quoted 17 lines · Junio C Hamano
Quoted 8 lines · Nguyễn Thái Ngọc Duy

The compiler reports this because show_gitcomp() never actually returns a value:

"parse-options.c", line 520: warning: Function has no return statement : show_gitcomp

The function calls exit() and will never return. Update and mark it NORETURN.

Yuck. This should do for now, but I am not impressed by the choice to hook show_gitcomp() call into parse_options_step(), which forces such an abnormal exit deeper in the callchain [*1*]. For readers (not compilers), it would help to have a comment at the caller that says that show_gitcomp() never returns and exits.

Quoted 6 lines

side note #1. Perhaps parse_options_start() would have been a better place, instead of parse_options_step() that is repeatedly called in a loop and itself has a loop. ANd worse yet, the check is done inside the loop even though the call is to be made only when the --git-completion-helper option is given as the sole request.

The reason it's in parse_options_step() is because -h is also handled in there. Although -h does not bury exit() deep in the call chain. So how about this as a replacement?

-- 8< --

parse-options.c +3 -1
index 3b874a83a0..6932eaff61 100644
@@ -516,7 +516,7 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 	show_negated_gitcomp(original_opts, -1);
 	show_negated_gitcomp(original_opts, nr_noopts);
 	fputc('\n', stdout);
-	exit(0);
+	return PARSE_OPT_COMPLETE;
 }
 
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
@@ -638,6 +638,8 @@ int parse_options(int argc, const char **argv, const char *prefix,
 	case PARSE_OPT_HELP:
 	case PARSE_OPT_ERROR:
 		exit(129);
+	case PARSE_OPT_COMPLETE:
+		exit(0);
 	case PARSE_OPT_NON_OPTION:
 	case PARSE_OPT_DONE:
 		break;
parse-options.h +1 -0
index 6c4fe2016d..a650a7d220 100644
@@ -208,6 +208,7 @@ extern int opterror(const struct option *opt, const char *reason, int flags);
 /*----- incremental advanced APIs -----*/
 
 enum {
+	PARSE_OPT_COMPLETE = -2,
 	PARSE_OPT_HELP = -1,
 	PARSE_OPT_DONE,
 	PARSE_OPT_NON_OPTION,

-- 8< --

#63 lore raw

Re: [PATCH] parse-options: fix SunCC compiler warning

Quoted 3 lines · Duy Nguyen

The reason it's in parse_options_step() is because -h is also handled in there. Although -h does not bury exit() deep in the call chain. So how about this as a replacement?

So just like -h returns PARSE_OPT_HELP and causes the calling parse_options() to exit(129), the new _COMPLETE can be used to trigger an early & successful return?

We'd also have to cover builtin/{blame,shortlog,update-index}.c where they switch() on the return value from parse_options_step(), but other than that, it probably is a better approach. The users of parse_options_step() that avoid parse_options() want to handle the various "we stopped by hitting a non-option" cases in their own ways, so treating this special action the same way as -h is treated would be sensible. We _might_ want to standardize some of the case arms in these custom switch statements that appear in these three built-in command implementations, but that can be done more easily if this step is done like you showed below, I think.

Quoted 36 lines

-- 8< --

parse-options.c +3 -1
index 3b874a83a0..6932eaff61 100644
@@ -516,7 +516,7 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 	show_negated_gitcomp(original_opts, -1);
 	show_negated_gitcomp(original_opts, nr_noopts);
 	fputc('\n', stdout);
-	exit(0);
+	return PARSE_OPT_COMPLETE;
 }
 
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
@@ -638,6 +638,8 @@ int parse_options(int argc, const char **argv, const char *prefix,
 	case PARSE_OPT_HELP:
 	case PARSE_OPT_ERROR:
 		exit(129);
+	case PARSE_OPT_COMPLETE:
+		exit(0);
 	case PARSE_OPT_NON_OPTION:
 	case PARSE_OPT_DONE:
 		break;
parse-options.h +1 -1
index 6c4fe2016d..a650a7d220 100644
@@ -208,6 +208,7 @@ extern int opterror(const struct option *opt, const char *reason, int flags);
 /*----- incremental advanced APIs -----*/
 
 enum {
+	PARSE_OPT_COMPLETE = -2,
 	PARSE_OPT_HELP = -1,
 	PARSE_OPT_DONE,
 	PARSE_OPT_NON_OPTION,
-- 8< --
author
#64 lore raw

Re: [PATCH] parse-options: fix SunCC compiler warning

Quoted 11 lines · Junio C Hamano
Quoted 3 lines · Duy Nguyen

The reason it's in parse_options_step() is because -h is also handled in there. Although -h does not bury exit() deep in the call chain. So how about this as a replacement?

So just like -h returns PARSE_OPT_HELP and causes the calling parse_options() to exit(129), the new _COMPLETE can be used to trigger an early & successful return?

Quoted 7 lines

We'd also have to cover builtin/{blame,shortlog,update-index}.c where they switch() on the return value from parse_options_step(), but other than that, it probably is a better approach. The users of parse_options_step() that avoid parse_options() want to handle the various "we stopped by hitting a non-option" cases in their own ways, so treating this special action the same way as -h is treated would be sensible.

Yeah, I saw that shortly after sending the patch.

Quoted 4 lines

We _might_ want to standardize some of the case
arms in these custom switch statements that appear in these three built-in command implementations, but that can be done more easily if this step is done like you showed below, I think.

I have a better plan: stop exposing parse-options loop to outside. What all these commands need is the ability to deal with unknown options (or non-options in update-index case). They could register callbacks to deal with those and keep calling parse_options() instead. I'm converting rev-list to use parse_options() and as an intermediate step, this callback idea should work well. The end game though is a single parse_options() call that covers everything in, say, git-log. But we will see.

Signature · 1 line
Duy
#65 lore raw

Re: [PATCH] parse-options: fix SunCC compiler warning

Quoted 8 lines · Duy Nguyen

I have a better plan: stop exposing parse-options loop to outside. What all these commands need is the ability to deal with unknown options (or non-options in update-index case). They could register callbacks to deal with those and keep calling parse_options() instead. I'm converting rev-list to use parse_options() and as an intermediate step, this callback idea should work well. The end game though is a single parse_options() call that covers everything in, say, git-log. But we will see.

Sounds like a good plan.

Thanks.

#66 lore raw

PATCH v2 1/1 parse-options: fix SunCC compiler warning

In reply to Nguyễn Thái Ngọc Duy

The compiler reports this because show_gitcomp() never actually returns a value:

"parse-options.c", line 520: warning: Function has no return statement : show_gitcomp

We could shut the compiler up. But instead let's not bury exit() too deep. Do the same as internal -h handling, return a special error code and handle the exit() in parse_options() (and other parse_options_step() callers) instead.

---
 builtin/blame.c        | 2 ++
 builtin/shortlog.c     | 2 ++
 builtin/update-index.c | 2 ++
 parse-options.c        | 4 +++-
 parse-options.h        | 1 +
 5 files changed, 10 insertions(+), 1 deletion(-)
builtin/blame.c +2 -0
index 06a7163ffe..6d798f9939 100644
@@ -850,6 +850,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 		case PARSE_OPT_HELP:
 		case PARSE_OPT_ERROR:
 			exit(129);
+		case PARSE_OPT_COMPLETE:
+			exit(0);
 		case PARSE_OPT_DONE:
 			if (ctx.argv[0])
 				dashdash_pos = ctx.cpidx;
builtin/shortlog.c +2 -0
index 88f88e97b2..65cd41392c 100644
@@ -287,6 +287,8 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
 		case PARSE_OPT_HELP:
 		case PARSE_OPT_ERROR:
 			exit(129);
+		case PARSE_OPT_COMPLETE:
+			exit(0);
 		case PARSE_OPT_DONE:
 			goto parse_done;
 		}
builtin/update-index.c +2 -0
index 31e7cce301..e19da77edc 100644
@@ -1086,6 +1086,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 		case PARSE_OPT_HELP:
 		case PARSE_OPT_ERROR:
 			exit(129);
+		case PARSE_OPT_COMPLETE:
+			exit(0);
 		case PARSE_OPT_NON_OPTION:
 		case PARSE_OPT_DONE:
 		{
parse-options.c +3 -1
index 3b874a83a0..6932eaff61 100644
@@ -516,7 +516,7 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 	show_negated_gitcomp(original_opts, -1);
 	show_negated_gitcomp(original_opts, nr_noopts);
 	fputc('\n', stdout);
-	exit(0);
+	return PARSE_OPT_COMPLETE;
 }
 
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
@@ -638,6 +638,8 @@ int parse_options(int argc, const char **argv, const char *prefix,
 	case PARSE_OPT_HELP:
 	case PARSE_OPT_ERROR:
 		exit(129);
+	case PARSE_OPT_COMPLETE:
+		exit(0);
 	case PARSE_OPT_NON_OPTION:
 	case PARSE_OPT_DONE:
 		break;
parse-options.h +1 -0
index 6c4fe2016d..a650a7d220 100644
@@ -208,6 +208,7 @@ extern int opterror(const struct option *opt, const char *reason, int flags);
 /*----- incremental advanced APIs -----*/
 
 enum {
+	PARSE_OPT_COMPLETE = -2,
 	PARSE_OPT_HELP = -1,
 	PARSE_OPT_DONE,
 	PARSE_OPT_NON_OPTION,
Signature · 1 line
2.20.0.481.gca8ed29094
#67 lore raw

PATCH v3 2/42 parse-options: add OPT_xxx_F() variants

In reply to Nguyễn Thái Ngọc Duy

These macros allow us to add extra parse-options flag, the main one in my mind is PARSE_OPT_NOCOMPLETE to hide certain options from --git-completion-helper.

---
 parse-options.h | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
parse-options.h +12 -7
index a5caa0bb1d..05a6839019 100644
@@ -115,19 +115,24 @@ struct option {
 	intptr_t defval;
 };
 
+#define OPT_BIT_F(s, l, v, h, b, f) { OPTION_BIT, (s), (l), (v), NULL, (h), \
+				      PARSE_OPT_NOARG|(f), NULL, (b) }
+#define OPT_COUNTUP_F(s, l, v, h, f) { OPTION_COUNTUP, (s), (l), (v), NULL, \
+				       (h), PARSE_OPT_NOARG|(f) }
+#define OPT_SET_INT_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \
+					  (h), PARSE_OPT_NOARG | (f), NULL, (i) }
+#define OPT_BOOL_F(s, l, v, h, f)   OPT_SET_INT_F(s, l, v, h, 1, f)
+
 #define OPT_END()                   { OPTION_END }
 #define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
 				      (h), PARSE_OPT_NOARG}
 #define OPT_GROUP(h)                { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
-#define OPT_BIT(s, l, v, h, b)      { OPTION_BIT, (s), (l), (v), NULL, (h), \
-				      PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_BIT(s, l, v, h, b)      OPT_BIT_F(s, l, v, h, b, 0)
 #define OPT_NEGBIT(s, l, v, h, b)   { OPTION_NEGBIT, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG, NULL, (b) }
-#define OPT_COUNTUP(s, l, v, h)     { OPTION_COUNTUP, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG }
-#define OPT_SET_INT(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG, NULL, (i) }
-#define OPT_BOOL(s, l, v, h)        OPT_SET_INT(s, l, v, h, 1)
+#define OPT_COUNTUP(s, l, v, h)     OPT_COUNTUP_F(s, l, v, h, 0)
+#define OPT_SET_INT(s, l, v, h, i)  OPT_SET_INT_F(s, l, v, h, i, 0)
+#define OPT_BOOL(s, l, v, h)        OPT_BOOL_F(s, l, v, h, 0)
 #define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
 #define OPT_CMDMODE(s, l, v, h, i)  { OPTION_CMDMODE, (s), (l), (v), NULL, \
Signature · 1 line
2.16.1.207.gedba492059
#68 lore raw

PATCH v3 3/42 parse-options: let OPT__FORCE take optional flags argument

In reply to Nguyễn Thái Ngọc Duy

--force option is most likely hidden from command line completion for safety reasons. This is done by adding an extra flag PARSE_OPT_NOCOMPLETE. Update OPT__FORCE() to accept additional flags. Actual flag change comes later depending on individual commands.

---
 builtin/add.c                | 2 +-
 builtin/branch.c             | 2 +-
 builtin/checkout-index.c     | 2 +-
 builtin/checkout.c           | 2 +-
 builtin/clean.c              | 2 +-
 builtin/fetch.c              | 2 +-
 builtin/mv.c                 | 2 +-
 builtin/notes.c              | 4 ++--
 builtin/pull.c               | 2 +-
 builtin/rm.c                 | 2 +-
 builtin/tag.c                | 2 +-
 builtin/update-server-info.c | 2 +-
 builtin/worktree.c           | 4 +++-
 parse-options.h              | 2 +-
 14 files changed, 17 insertions(+), 15 deletions(-)
builtin/add.c +1 -1
index bf01d89e28..ac7c1c3277 100644
@@ -294,7 +294,7 @@ static struct option builtin_add_options[] = {
 	OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
 	OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
 	OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
-	OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
+	OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0),
 	OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
 	OPT_BOOL(0, "renormalize", &add_renormalize, N_("renormalize EOL of tracked files (implies -u)")),
 	OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
builtin/branch.c +1 -1
index 8dcc2ed058..b5b62c08ba 100644
@@ -615,7 +615,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_BOOL('l', "create-reflog", &reflog, N_("create the branch's reflog")),
 		OPT_BOOL(0, "edit-description", &edit_description,
 			 N_("edit the description for the branch")),
-		OPT__FORCE(&force, N_("force creation, move/rename, deletion")),
+		OPT__FORCE(&force, N_("force creation, move/rename, deletion"), 0),
 		OPT_MERGED(&filter, N_("print only branches that are merged")),
 		OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
builtin/checkout-index.c +1 -1
index b0e78b819d..a730f6a1aa 100644
@@ -157,7 +157,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
 	struct option builtin_checkout_index_options[] = {
 		OPT_BOOL('a', "all", &all,
 			N_("check out all files in the index")),
-		OPT__FORCE(&force, N_("force overwrite of existing files")),
+		OPT__FORCE(&force, N_("force overwrite of existing files"), 0),
 		OPT__QUIET(&quiet,
 			N_("no warning for existing files and files not in index")),
 		OPT_BOOL('n', "no-create", &not_new,
builtin/checkout.c +1 -1
index c54c78df54..2a96358eb7 100644
@@ -1118,7 +1118,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			    2),
 		OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
 			    3),
-		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)")),
+		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"), 0),
 		OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
 		OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
 		OPT_STRING(0, "conflict", &conflict_style, N_("style"),
builtin/clean.c +1 -1
index 189e20628c..3c4ca9a2ff 100644
@@ -909,7 +909,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__QUIET(&quiet, N_("do not print names of files removed")),
 		OPT__DRY_RUN(&dry_run, N_("dry run")),
-		OPT__FORCE(&force, N_("force")),
+		OPT__FORCE(&force, N_("force"), 0),
 		OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")),
 		OPT_BOOL('d', NULL, &remove_directories,
 				N_("remove whole directories")),
builtin/fetch.c +1 -1
index 7bbcd26faf..6a603174fb 100644
@@ -115,7 +115,7 @@ static struct option builtin_fetch_options[] = {
 		 N_("append to .git/FETCH_HEAD instead of overwriting")),
 	OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
 		   N_("path to upload pack on remote end")),
-	OPT__FORCE(&force, N_("force overwrite of local branch")),
+	OPT__FORCE(&force, N_("force overwrite of local branch"), 0),
 	OPT_BOOL('m', "multiple", &multiple,
 		 N_("fetch from multiple remotes")),
 	OPT_SET_INT('t', "tags", &tags,
builtin/mv.c +1 -1
index cf3684d907..b88023a733 100644
@@ -122,7 +122,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 	struct option builtin_mv_options[] = {
 		OPT__VERBOSE(&verbose, N_("be verbose")),
 		OPT__DRY_RUN(&show_only, N_("dry run")),
-		OPT__FORCE(&force, N_("force move/rename even if target exists")),
+		OPT__FORCE(&force, N_("force move/rename even if target exists"), 0),
 		OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
 		OPT_END(),
 	};
builtin/notes.c +2 -2
index 7c81761645..b52e71c73e 100644
@@ -413,7 +413,7 @@ static int add(int argc, const char **argv, const char *prefix)
 			parse_reuse_arg},
 		OPT_BOOL(0, "allow-empty", &allow_empty,
 			N_("allow storing empty note")),
-		OPT__FORCE(&force, N_("replace existing notes")),
+		OPT__FORCE(&force, N_("replace existing notes"), 0),
 		OPT_END()
 	};
 
@@ -484,7 +484,7 @@ static int copy(int argc, const char **argv, const char *prefix)
 	struct notes_tree *t;
 	const char *rewrite_cmd = NULL;
 	struct option options[] = {
-		OPT__FORCE(&force, N_("replace existing notes")),
+		OPT__FORCE(&force, N_("replace existing notes"), 0),
 		OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")),
 		OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"),
 			   N_("load rewriting config for <command> (implies "
builtin/pull.c +1 -1
index 511dbbe0f6..652239aae9 100644
@@ -193,7 +193,7 @@ static struct option pull_options[] = {
 	OPT_PASSTHRU(0, "upload-pack", &opt_upload_pack, N_("path"),
 		N_("path to upload pack on remote end"),
 		0),
-	OPT__FORCE(&opt_force, N_("force overwrite of local branch")),
+	OPT__FORCE(&opt_force, N_("force overwrite of local branch"), 0),
 	OPT_PASSTHRU('t', "tags", &opt_tags, NULL,
 		N_("fetch all tags and associated objects"),
 		PARSE_OPT_NOARG),
builtin/rm.c +1 -1
index 4a2fcca27b..6e0c7f5ac6 100644
@@ -242,7 +242,7 @@ static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__QUIET(&quiet, N_("do not list removed files")),
 	OPT_BOOL( 0 , "cached",         &index_only, N_("only remove from the index")),
-	OPT__FORCE(&force, N_("override the up-to-date check")),
+	OPT__FORCE(&force, N_("override the up-to-date check"), 0),
 	OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
 	OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
 				N_("exit with a zero status even if nothing matched")),
builtin/tag.c +1 -1
index a7e6a5b0f2..98d3956bbe 100644
@@ -391,7 +391,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 			N_("how to strip spaces and #comments from message")),
 		OPT_STRING('u', "local-user", &keyid, N_("key-id"),
 					N_("use another key to sign the tag")),
-		OPT__FORCE(&force, N_("replace the tag if exists")),
+		OPT__FORCE(&force, N_("replace the tag if exists"), 0),
 		OPT_BOOL(0, "create-reflog", &create_reflog, N_("create a reflog")),
 
 		OPT_GROUP(N_("Tag listing options")),
builtin/update-server-info.c +1 -1
index 873070e517..4321a34456 100644
@@ -12,7 +12,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix)
 {
 	int force = 0;
 	struct option options[] = {
-		OPT__FORCE(&force, N_("update the info files from scratch")),
+		OPT__FORCE(&force, N_("update the info files from scratch"), 0),
 		OPT_END()
 	};
 
builtin/worktree.c +3 -1
index 7cef5b120b..4d3422f62e 100644
@@ -365,7 +365,9 @@ static int add(int ac, const char **av, const char *prefix)
 	const char *branch;
 	const char *opt_track = NULL;
 	struct option options[] = {
-		OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
+		OPT__FORCE(&opts.force,
+			   N_("checkout <branch> even if already checked out in other worktree"),
+			   0),
 		OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
 			   N_("create a new branch")),
 		OPT_STRING('B', NULL, &new_branch_force, N_("branch"),
parse-options.h +1 -1
index 05a6839019..3c32401736 100644
@@ -248,7 +248,7 @@ extern int parse_opt_passthru_argv(const struct option *, const char *, int);
 	{ OPTION_CALLBACK, 'q', "quiet", (var), NULL, N_("be more quiet"), \
 	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
 #define OPT__DRY_RUN(var, h)  OPT_BOOL('n', "dry-run", (var), (h))
-#define OPT__FORCE(var, h)    OPT_COUNTUP('f', "force",   (var), (h))
+#define OPT__FORCE(var, h, f) OPT_COUNTUP_F('f', "force",   (var), (h), (f))
 #define OPT__ABBREV(var)  \
 	{ OPTION_CALLBACK, 0, "abbrev", (var), N_("n"),	\
 	  N_("use <n> digits to display SHA-1s"),	\
Signature · 1 line
2.16.1.207.gedba492059
#69 lore raw

PATCH v3 4/42 git-completion.bash: introduce __gitcomp_builtin

In reply to Nguyễn Thái Ngọc Duy

This is a __gitcomp wrapper that will execute

    git ... --git-completion-helper

to get the list of completable options. The call will be made only once and cached to avoid performance issues, especially on Windows.

__gitcomp_builtin() allows callers to change its output a bit by adding some more options, or removing some.

- Current --git-completion-helper for example does not output --no-foo form, this has to be added manually by __gitcomp_builtin() callers when necessary

- Some options from --git-completion-helper should only be available in certain conditions (e.g. --continue and friends). __gitcomp_builtin() callers can remove them if the conditions are not met.

---
 contrib/completion/git-completion.bash | 33 ++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
contrib/completion/git-completion.bash +33 -0
index 3683c772c5..85e7f26328 100644
@@ -280,6 +280,39 @@ __gitcomp ()
 	esac
 }
 
+# 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
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
+__gitcomp_builtin ()
+{
+	# 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"
+
+	local var=__gitcomp_builtin_"${cmd/-/_}"
+	local options
+	eval "options=\$$var"
+
+	if [ -z "$options" ]; then
+		# leading and trailing spaces are significant to make
+		# option removal work correctly.
+		options=" $(__git ${cmd/_/ } --git-completion-helper) $incl "
+		for i in $excl; do
+			options="${options/ $i / }"
+		done
+		eval "$var=\"$options\""
+	fi
+
+	__gitcomp "$options"
+}
+
 # Variation of __gitcomp_nl () that appends to the existing list of
 # completion candidates, COMPREPLY.
 __gitcomp_nl_append ()
Signature · 1 line
2.16.1.207.gedba492059
#70 lore raw

Re: [PATCH v3 04/42] git-completion.bash: introduce __gitcomp_builtin

contrib/completion/git-completion.bash __gitcomp () · line 290

Quoted 8 lines · Nguyễn Thái Ngọc Duy
contrib/completion/git-completion.bash +8 -0
+# 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
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded

The options="${options/ $i / }" substitution in a loop is cute. The third argument to this helper is an IFS separated list of regular expressions to match options that we do not want to see in the completion, so

	__gitcomp_builtin foo '' '--a[^ ]*'

presumably would exclude all options whose names begin with 'a' ;-).

Quoted 16 lines
contrib/completion/git-completion.bash +13 -0
+	if [ -z "$options" ]; then
+		# leading and trailing spaces are significant to make
+		# option removal work correctly.
+		options=" $(__git ${cmd/_/ } --git-completion-helper) $incl "
+		for i in $excl; do
+			options="${options/ $i / }"
+		done
+		eval "$var=\"$options\""
+	fi
+
+	__gitcomp "$options"
+}
+
 # Variation of __gitcomp_nl () that appends to the existing list of
 # completion candidates, COMPREPLY.
 __gitcomp_nl_append ()
#71 lore raw

Re: [PATCH v3 04/42] git-completion.bash: introduce __gitcomp_builtin

In reply to Nguyễn Thái Ngọc Duy

Thanks for working on this. I anticipated that the completion script lack some options, but wow, I didn't expect that there are so many missing.

Quoted 6 lines · Nguyễn Thái Ngọc Duy

This is a __gitcomp wrapper that will execute

    git ... --git-completion-helper

to get the list of completable options. The call will be made only once and cached to avoid performance issues, especially on Windows.

Nit: the call will be made every time; 'git ... --git-completion-helper' will be executed only once.

Quoted 23 lines

__gitcomp_builtin() allows callers to change its output a bit by adding some more options, or removing some.

- Current --git-completion-helper for example does not output --no-foo form, this has to be added manually by __gitcomp_builtin() callers when necessary

- Some options from --git-completion-helper should only be available in certain conditions (e.g. --continue and friends). __gitcomp_builtin() callers can remove them if the conditions are not met.

---
 contrib/completion/git-completion.bash | 33 ++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
contrib/completion/git-completion.bash +0 -0
index 3683c772c5..85e7f26328 100644
@@ -280,6 +280,39 @@ __gitcomp ()
        esac
 }

contrib/completion/git-completion.bash __gitcomp () · line 291

Quoted 10 lines
contrib/completion/git-completion.bash +9 -0
 
+# 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
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
+__gitcomp_builtin ()

Please excuse the bikeshed at v3, but I don't like the name of this function. It indicates that it completes builtins, but it completes options of builtins, and even then only the options of those using parse options. Furthermore, the '__gitcomp' prefix is usually used for functions that merely put words into COMPREPLY, but this function does a whole lot more (getting the options from builtins, include and exclude options, caching).

Alas I don't have any great name; __git_complete_options is better, because it uses the right function name prefix, but only slightly better, because it can't generally be used to complete options, as it won't work with scripts or with builtins not using parse options (though with time more scripts will be turned into builtins and more builtins will use parse options). I'm not sure it's that match better to make it worth changing fourty-odd patches.

contrib/completion/git-completion.bash __gitcomp () · line 295

Quoted 4 lines
contrib/completion/git-completion.bash +4 -0
+{
+       # spaces must be replaced with underscore for multi-word
+       # commands, e.g. "git remote add" becomes remote_add.
+       local cmd="$1"

The alternative would be 'command subcommand', i.e. keeping that space, and in that case we could spare the ${cmd/_/ } in this function, and could even say '__gitcomp "$(git $1 --git-completion-helper)" in the equivalent example above; OTOH we would need quoting on all callsites with subcommands. Again, I'm not sure it's worth it.

Quoted 26 lines
contrib/completion/git-completion.bash +20 -1
+       local incl="$2"
+       local excl="$3"
+
+       local var=__gitcomp_builtin_"${cmd/-/_}"
+       local options
+       eval "options=\$$var"
+
+       if [ -z "$options" ]; then
+               # leading and trailing spaces are significant to make
+               # option removal work correctly.
+               options=" $(__git ${cmd/_/ } --git-completion-helper) $incl "
+               for i in $excl; do
+                       options="${options/ $i / }"
+               done
+               eval "$var=\"$options\""
+       fi
+
+       __gitcomp "$options"
+}
+
 # Variation of __gitcomp_nl () that appends to the existing list of
 # completion candidates, COMPREPLY.
 __gitcomp_nl_append ()
--

2.16.1.207.gedba492059

author
#72 lore raw

Re: [PATCH v3 04/42] git-completion.bash: introduce __gitcomp_builtin

Quoted 10 lines · SZEDER Gábor
Quoted 1 line

+__gitcomp_builtin ()

Please excuse the bikeshed at v3, but I don't like the name of this function. It indicates that it completes builtins, but it completes options of builtins, and even then only the options of those using parse options. Furthermore, the '__gitcomp' prefix is usually used for functions that merely put words into COMPREPLY, but this function does a whole lot more (getting the options from builtins, include and exclude options, caching).

Quoted 7 lines

Alas I don't have any great name; __git_complete_options is better, because it uses the right function name prefix, but only slightly better, because it can't generally be used to complete options, as it won't work with scripts or with builtins not using parse options (though with time more scripts will be turned into builtins and more builtins will use parse options). I'm not sure it's that match better to make it worth changing fourty-odd patches.

Since it's still on 'pu', renaming is still an option. I don't mind renaming (and I'll need to check every patch anyway when I make --rerere-autoupdate completable). Say "do" and I will.

Signature · 1 line
Duy
#73 lore raw

PATCH v3 5/42 completion: use __gitcomp_builtin in _git_add

In reply to Nguyễn Thái Ngọc Duy

The new completable options are

--all
--ignore-missing
--ignore-removal
--renormalize
--verbose

---
 contrib/completion/git-completion.bash | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
contrib/completion/git-completion.bash +1 -4
index 85e7f26328..1e0bd835fe 100644
@@ -1153,10 +1153,7 @@ _git_add ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--interactive --refresh --patch --update --dry-run
-			--ignore-errors --intent-to-add --force --edit --chmod=
-			"
+		__gitcomp_builtin add
 		return
 	esac
 
Signature · 1 line
2.16.1.207.gedba492059
#74 lore raw

PATCH v3 6/42 completion: use __gitcomp_builtin in _git_am

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--directory
--exclude
--gpg-sign
--include
--keep-cr
--keep-non-patch
--message-id
--no-keep-cr
--patch-format
--quiet
--reject
--resolvemsg=

In-progress options like --continue will be part of --git-completion-helper then filtered out by _git_am() unless the operation is in progress. This helps keep marking of these operations in just one place.

---
 contrib/completion/git-completion.bash | 11 ++++-------
 parse-options.h                        |  4 ++--
 rerere.h                               |  3 ++-
 3 files changed, 8 insertions(+), 10 deletions(-)
contrib/completion/git-completion.bash +4 -7
index 1e0bd835fe..eba482eb9c 100644
@@ -1105,12 +1105,13 @@ __git_count_arguments ()
 }
 
 __git_whitespacelist="nowarn warn error error-all fix"
+__git_am_inprogress_options="--skip --continue --resolved --abort"
 
 _git_am ()
 {
 	__git_find_repo_path
 	if [ -d "$__git_repo_path"/rebase-apply ]; then
-		__gitcomp "--skip --continue --resolved --abort"
+		__gitcomp "$__git_am_inprogress_options"
 		return
 	fi
 	case "$cur" in
@@ -1119,12 +1120,8 @@ _git_am ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--3way --committer-date-is-author-date --ignore-date
-			--ignore-whitespace --ignore-space-change
-			--interactive --keep --no-utf8 --signoff --utf8
-			--whitespace= --scissors
-			"
+		__gitcomp_builtin am "--no-utf8" \
+			"$__git_am_inprogress_options"
 		return
 	esac
 }
parse-options.h +2 -2
index 3c32401736..009cd863e5 100644
@@ -144,8 +144,8 @@ struct option {
 #define OPT_STRING_LIST(s, l, v, a, h) \
 				    { OPTION_CALLBACK, (s), (l), (v), (a), \
 				      (h), 0, &parse_opt_string_list }
-#define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
-				      (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
+#define OPT_UYN(s, l, v, h, f)      { OPTION_CALLBACK, (s), (l), (v), NULL, \
+				      (h), PARSE_OPT_NOARG|(f), &parse_opt_tertiary }
 #define OPT_DATE(s, l, v, h) \
 	{ OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,	\
 	  parse_opt_approxidate_cb }
rerere.h +2 -1
index c2961feaaa..5e5a312e4c 100644
@@ -37,6 +37,7 @@ extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
 
 #define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \
-	N_("update the index with reused conflict resolution if possible"))
+	N_("update the index with reused conflict resolution if possible"), \
+	PARSE_OPT_NOCOMPLETE)
 
 #endif
Signature · 1 line
2.16.1.207.gedba492059
#75 lore raw

Re: [PATCH v3 06/42] completion: use __gitcomp_builtin in _git_am

Quoted 65 lines · Nguyễn Thái Ngọc Duy

The new completable options are:

--directory
--exclude
--gpg-sign
--include
--keep-cr
--keep-non-patch
--message-id
--no-keep-cr
--patch-format
--quiet
--reject
--resolvemsg=

In-progress options like --continue will be part of --git-completion-helper then filtered out by _git_am() unless the operation is in progress. This helps keep marking of these operations in just one place.

---
 contrib/completion/git-completion.bash | 11 ++++-------
 parse-options.h                        |  4 ++--
 rerere.h                               |  3 ++-
 3 files changed, 8 insertions(+), 10 deletions(-)
contrib/completion/git-completion.bash +4 -7
index 1e0bd835fe..eba482eb9c 100644
@@ -1105,12 +1105,13 @@ __git_count_arguments ()
 }
 
 __git_whitespacelist="nowarn warn error error-all fix"
+__git_am_inprogress_options="--skip --continue --resolved --abort"
 
 _git_am ()
 {
        __git_find_repo_path
        if [ -d "$__git_repo_path"/rebase-apply ]; then
-               __gitcomp "--skip --continue --resolved --abort"
+               __gitcomp "$__git_am_inprogress_options"
                return
        fi
        case "$cur" in
@@ -1119,12 +1120,8 @@ _git_am ()
                return
                ;;
        --*)
-               __gitcomp "
-                       --3way --committer-date-is-author-date --ignore-date
-                       --ignore-whitespace --ignore-space-change
-                       --interactive --keep --no-utf8 --signoff --utf8
-                       --whitespace= --scissors
-                       "
+               __gitcomp_builtin am "--no-utf8" \
+                       "$__git_am_inprogress_options"
                return
        esac
 }
parse-options.h +0 -0
index 3c32401736..009cd863e5 100644

parse-options.h struct option { · line 151

Quoted 10 lines
parse-options.h +2 -2
@@ -144,8 +144,8 @@ struct option {
 #define OPT_STRING_LIST(s, l, v, a, h) \
                                    { OPTION_CALLBACK, (s), (l), (v), (a), \
                                      (h), 0, &parse_opt_string_list }
-#define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
-                                     (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
+#define OPT_UYN(s, l, v, h, f)      { OPTION_CALLBACK, (s), (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG|(f), &parse_opt_tertiary }
 #define OPT_DATE(s, l, v, h) \
        { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,    \
          parse_opt_approxidate_cb }

Shouldn't this hunk go into a commit of its own? Or at least it would deserve a mention in the commit message.

Quoted 16 lines
rerere.h +2 -2
index c2961feaaa..5e5a312e4c 100644
@@ -37,6 +37,7 @@ extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
 
 #define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \
-       N_("update the index with reused conflict resolution if possible"))
+       N_("update the index with reused conflict resolution if possible"), \
+       PARSE_OPT_NOCOMPLETE)
 
 #endif
--

2.16.1.207.gedba492059

author
#76 lore raw

Re: [PATCH v3 06/42] completion: use __gitcomp_builtin in _git_am

Quoted 71 lines · SZEDER Gábor
Quoted 70 lines · Nguyễn Thái Ngọc Duy

The new completable options are:

--directory
--exclude
--gpg-sign
--include
--keep-cr
--keep-non-patch
--message-id
--no-keep-cr
--patch-format
--quiet
--reject
--resolvemsg=

In-progress options like --continue will be part of --git-completion-helper then filtered out by _git_am() unless the operation is in progress. This helps keep marking of these operations in just one place.

---
 contrib/completion/git-completion.bash | 11 ++++-------
 parse-options.h                        |  4 ++--
 rerere.h                               |  3 ++-
 3 files changed, 8 insertions(+), 10 deletions(-)
contrib/completion/git-completion.bash +4 -7
index 1e0bd835fe..eba482eb9c 100644
@@ -1105,12 +1105,13 @@ __git_count_arguments ()
 }
 
 __git_whitespacelist="nowarn warn error error-all fix"
+__git_am_inprogress_options="--skip --continue --resolved --abort"
 
 _git_am ()
 {
        __git_find_repo_path
        if [ -d "$__git_repo_path"/rebase-apply ]; then
-               __gitcomp "--skip --continue --resolved --abort"
+               __gitcomp "$__git_am_inprogress_options"
                return
        fi
        case "$cur" in
@@ -1119,12 +1120,8 @@ _git_am ()
                return
                ;;
        --*)
-               __gitcomp "
-                       --3way --committer-date-is-author-date --ignore-date
-                       --ignore-whitespace --ignore-space-change
-                       --interactive --keep --no-utf8 --signoff --utf8
-                       --whitespace= --scissors
-                       "
+               __gitcomp_builtin am "--no-utf8" \
+                       "$__git_am_inprogress_options"
                return
        esac
 }
parse-options.h +0 -2
index 3c32401736..009cd863e5 100644
@@ -144,8 +144,8 @@ struct option {
 #define OPT_STRING_LIST(s, l, v, a, h) \
                                    { OPTION_CALLBACK, (s), (l), (v), (a), \
                                      (h), 0, &parse_opt_string_list }
-#define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
-                                     (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
Quoted 8 lines

parse-options.h struct option { · line 151

Quoted 5 lines
parse-options.h +2 -0
+#define OPT_UYN(s, l, v, h, f)      { OPTION_CALLBACK, (s), (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG|(f), &parse_opt_tertiary }
 #define OPT_DATE(s, l, v, h) \
        { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,    \
          parse_opt_approxidate_cb }

Shouldn't this hunk go into a commit of its own? Or at least it would deserve a mention in the commit message.

It's not a standalone change. It is used by the OPT_RERERE_AUTOUPDATE below, which in turn is used by git-add. Together, --rerere-autoupdate is removed from the completion list of git-add (and also a few more commands).

Now that you mention it, the only command that completes --rerere-autoupdate is git-merge. Since this is "auto" I don't think people want to type manually. Maybe I should separate these changes _and_ remove --rerere-autoupdate from _git_merge() too? At least that it will be consistent that way.

Quoted 16 lines
Quoted 16 lines
rerere.h +2 -2
index c2961feaaa..5e5a312e4c 100644
@@ -37,6 +37,7 @@ extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
 
 #define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \
-       N_("update the index with reused conflict resolution if possible"))
+       N_("update the index with reused conflict resolution if possible"), \
+       PARSE_OPT_NOCOMPLETE)
 
 #endif
--

2.16.1.207.gedba492059

Signature · 1 line
Duy
#77 lore raw

Re: [PATCH v3 06/42] completion: use __gitcomp_builtin in _git_am

Quoted 3 lines · Duy Nguyen

Now that you mention it, the only command that completes --rerere-autoupdate is git-merge. Since this is "auto" I don't think people want to type manually.

Sorry, but I do not quite get the connection between "since this is 'auto'" and the rest of the sentence. Is it just it is so lengthy that people do not want to type and are likely to use completion?

Quoted 3 lines

Maybe I should separate these changes
_and_ remove --rerere-autoupdate from _git_merge() too? At least that it will be consistent that way.

Hmmmm. Why not complete this option? Is it because the current completion script does not and we are trying to preserve the behaviour? I do not have a strong opinion either way, but just trying to understand the reasoning behind the choice.

Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
rerere.h +2 -2
index c2961feaaa..5e5a312e4c 100644
@@ -37,6 +37,7 @@ extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
 
 #define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \
-       N_("update the index with reused conflict resolution if possible"))
+       N_("update the index with reused conflict resolution if possible"), \
+       PARSE_OPT_NOCOMPLETE)
 
 #endif
--

2.16.1.207.gedba492059

author
#78 lore raw

Re: [PATCH v3 06/42] completion: use __gitcomp_builtin in _git_am

Quoted 9 lines · Junio C Hamano
Quoted 3 lines · Duy Nguyen

Now that you mention it, the only command that completes --rerere-autoupdate is git-merge. Since this is "auto" I don't think people want to type manually.

Sorry, but I do not quite get the connection between "since this is 'auto'" and the rest of the sentence. Is it just it is so lengthy that people do not want to type and are likely to use completion?

Well, if it is to be done automatically, I should not need to tell it manually (by typing the option on command line). Granted it's a weak argument.

Quoted 8 lines
Quoted 3 lines

Maybe I should separate these changes
_and_ remove --rerere-autoupdate from _git_merge() too? At least that it will be consistent that way.

Hmmmm. Why not complete this option? Is it because the current completion script does not and we are trying to preserve the behaviour? I do not have a strong opinion either way, but just trying to understand the reasoning behind the choice.

There's not a strong argument for not completing this option really.

It may belong to the unpopular category and adding it may make people <TAB> more for other options. But I think it's way too early to decide that. And even if that's true, I think we should let the user choose to not complete certain options they don't like.

It's good that this is spotted. I think I'll just keep all --rerere-autoupdate completable. Well, v4's coming (in a few days)...

Signature · 1 line
Duy
#79 lore raw

Re: [PATCH v3 06/42] completion: use __gitcomp_builtin in _git_am

Quoted 7 lines · Duy Nguyen
Quoted 6 lines · Junio C Hamano
Quoted 3 lines · Duy Nguyen

Now that you mention it, the only command that completes --rerere-autoupdate is git-merge. Since this is "auto" I don't think people want to type manually.

Quoted 7 lines
Quoted 3 lines

Sorry, but I do not quite get the connection between "since this is 'auto'" and the rest of the sentence. Is it just it is so lengthy that people do not want to type and are likely to use completion?

Well, if it is to be done automatically, I should not need to tell it manually (by typing the option on command line). Granted it's a weak argument.

Perhaps I am not reading what the option does correctly, but my understanding is that merge operations:

- always allow rerere to intervene and auto-resolve in the working tree, as long as rerere is enabled;

- by default they however do not add the rerere-resolved result to the index, so that the combined diff output from "git diff" can be used as a way to sanity check the result; but

- if the user says --rerere-autoupdate, they add the rerere-resolved result to the index, letting the user blindly trust it, so that such a trusting user can even commit the result without looking at it by merely making sure there is no path remaining in the "git ls-files -u" output.

The "autoupdate" could be somewhat dangerous depending on your workflow, and that is why the user can selectively enable it via the command line option (when known to be safe) even if the user does not set rerere.autoupdate to true.

So I am not sure I understand "an option to allow something to be done automatically should not be given manually" as a valid argument at all, whether it is weak or strong.

Or am I grossly confused?

author
#80 lore raw

Re: [PATCH v3 06/42] completion: use __gitcomp_builtin in _git_am

Quoted 38 lines · Junio C Hamano
Quoted 7 lines · Duy Nguyen
Quoted 6 lines · Junio C Hamano
Quoted 3 lines · Duy Nguyen

Now that you mention it, the only command that completes --rerere-autoupdate is git-merge. Since this is "auto" I don't think people want to type manually.

Quoted 7 lines
Quoted 3 lines

Sorry, but I do not quite get the connection between "since this is 'auto'" and the rest of the sentence. Is it just it is so lengthy that people do not want to type and are likely to use completion?

Well, if it is to be done automatically, I should not need to tell it manually (by typing the option on command line). Granted it's a weak argument.

Perhaps I am not reading what the option does correctly, but my understanding is that merge operations:

- always allow rerere to intervene and auto-resolve in the working tree, as long as rerere is enabled;

- by default they however do not add the rerere-resolved result to the index, so that the combined diff output from "git diff" can be used as a way to sanity check the result; but

- if the user says --rerere-autoupdate, they add the rerere-resolved result to the index, letting the user blindly trust it, so that such a trusting user can even commit the result without looking at it by merely making sure there is no path remaining in the "git ls-files -u" output.

The "autoupdate" could be somewhat dangerous depending on your workflow, and that is why the user can selectively enable it via the command line option (when known to be safe) even if the user does not set rerere.autoupdate to true.

Quoted 5 lines

So I am not sure I understand "an option to allow something to be done automatically should not be given manually" as a valid argument at all, whether it is weak or strong.

Or am I grossly confused?

Nope. It's just me not understanding rerere functionality.

Signature · 1 line
Duy
#81 lore raw

PATCH v3 7/42 completion: use __gitcomp_builtin in _git_apply

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--3way
--allow-overlap
--build-fake-ancestor=
--directory
--exclude
--include

--index-info is no longer completable but that's because it's renamed to --build-fake-ancestor in 26b2800768 (apply: get rid of --index-info in favor of --build-fake-ancestor - 2007-09-17)

---
 apply.c                                | 5 +++--
 contrib/completion/git-completion.bash | 9 +--------
 2 files changed, 4 insertions(+), 10 deletions(-)
apply.c +3 -2
index 321a9fa68d..65eb37e6a4 100644
@@ -4943,8 +4943,9 @@ int apply_parse_options(int argc, const char **argv,
 			N_("make sure the patch is applicable to the current index")),
 		OPT_BOOL(0, "cached", &state->cached,
 			N_("apply a patch without touching the working tree")),
-		OPT_BOOL(0, "unsafe-paths", &state->unsafe_paths,
-			N_("accept a patch that touches outside the working area")),
+		OPT_BOOL_F(0, "unsafe-paths", &state->unsafe_paths,
+			   N_("accept a patch that touches outside the working area"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "apply", force_apply,
 			N_("also apply the patch (use with --stat/--summary/--check)")),
 		OPT_BOOL('3', "3way", &state->threeway,
contrib/completion/git-completion.bash +1 -8
index eba482eb9c..2fd3fc999e 100644
@@ -1134,14 +1134,7 @@ _git_apply ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--stat --numstat --summary --check --index
-			--cached --index-info --reverse --reject --unidiff-zero
-			--apply --no-add --exclude=
-			--ignore-whitespace --ignore-space-change
-			--whitespace= --inaccurate-eof --verbose
-			--recount --directory=
-			"
+		__gitcomp_builtin apply
 		return
 	esac
 }
Signature · 1 line
2.16.1.207.gedba492059
#82 lore raw

PATCH v3 8/42 completion: use __gitcomp_builtin in _git_branch

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--all
--create-reflog
--format=
--ignore-case
--quiet

---
 builtin/branch.c                       | 2 +-
 contrib/completion/git-completion.bash | 8 ++------
 2 files changed, 3 insertions(+), 7 deletions(-)
builtin/branch.c +1 -1
index b5b62c08ba..6d0cea9d4b 100644
@@ -615,7 +615,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_BOOL('l', "create-reflog", &reflog, N_("create the branch's reflog")),
 		OPT_BOOL(0, "edit-description", &edit_description,
 			 N_("edit the description for the branch")),
-		OPT__FORCE(&force, N_("force creation, move/rename, deletion"), 0),
+		OPT__FORCE(&force, N_("force creation, move/rename, deletion"), PARSE_OPT_NOCOMPLETE),
 		OPT_MERGED(&filter, N_("print only branches that are merged")),
 		OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
contrib/completion/git-completion.bash +2 -6
index 2fd3fc999e..d926518fb7 100644
@@ -1220,12 +1220,8 @@ _git_branch ()
 		__git_complete_refs --cur="${cur##--set-upstream-to=}"
 		;;
 	--*)
-		__gitcomp "
-			--color --no-color --verbose --abbrev= --no-abbrev
-			--track --no-track --contains --no-contains --merged --no-merged
-			--set-upstream-to= --edit-description --list
-			--unset-upstream --delete --move --copy --remotes
-			--column --no-column --sort= --points-at
+		__gitcomp_builtin branch "--no-color --no-abbrev
+			--no-track --no-column
 			"
 		;;
 	*)
Signature · 1 line
2.16.1.207.gedba492059
#83 lore raw

PATCH v3 9/42 completion: use __gitcomp_builtin in _git_checkout

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--ignore-other-worktrees
--progress

---
 builtin/checkout.c                     |  7 +++++--
 contrib/completion/git-completion.bash |  6 +-----
 t/t9902-completion.sh                  | 12 +++++++-----
 3 files changed, 13 insertions(+), 12 deletions(-)
builtin/checkout.c +5 -2
index 2a96358eb7..a6218024a6 100644
@@ -1118,9 +1118,12 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 			    2),
 		OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
 			    3),
-		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"), 0),
+		OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
-		OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
+		OPT_BOOL_F(0, "overwrite-ignore", &opts.overwrite_ignore,
+			   N_("update ignored files (default)"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_STRING(0, "conflict", &conflict_style, N_("style"),
 			   N_("conflict style (merge or diff3)")),
 		OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
contrib/completion/git-completion.bash +1 -5
index d926518fb7..7e312f95e9 100644
@@ -1263,11 +1263,7 @@ _git_checkout ()
 		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
 		;;
 	--*)
-		__gitcomp "
-			--quiet --ours --theirs --track --no-track --merge
-			--conflict= --orphan --patch --detach --ignore-skip-worktree-bits
-			--recurse-submodules --no-recurse-submodules
-			"
+		__gitcomp_builtin checkout "--no-track --no-recurse-submodules"
 		;;
 	*)
 		# check if --track, --no-track, or --no-guess was specified
t/t9902-completion.sh +7 -5
index fc614dcbfa..e6485feb0a 100755
@@ -1237,17 +1237,19 @@ test_expect_success 'double dash "git" itself' '
 test_expect_success 'double dash "git checkout"' '
 	test_completion "git checkout --" <<-\EOF
 	--quiet Z
+	--detach Z
+	--track Z
+	--orphan=Z
 	--ours Z
 	--theirs Z
-	--track Z
-	--no-track Z
 	--merge Z
-	--conflict=
-	--orphan Z
+	--conflict=Z
 	--patch Z
-	--detach Z
 	--ignore-skip-worktree-bits Z
+	--ignore-other-worktrees Z
 	--recurse-submodules Z
+	--progress Z
+	--no-track Z
 	--no-recurse-submodules Z
 	EOF
 '
Signature · 1 line
2.16.1.207.gedba492059
#84 lore raw

PATCH v3 10/42 completion: use __gitcomp_builtin in _git_cherry_pick

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--allow-empty
--allow-empty-message
--ff
--gpg-sign
--keep-redundant-commits
--strategy-option

In-progress options like --continue will be part of --git-completion-helper then filtered out by _git_cherry_pick() unless the operation is in progress. This helps keep marking of these operations in just one place.

---
 contrib/completion/git-completion.bash | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
contrib/completion/git-completion.bash +5 -2
index 7e312f95e9..068def9f6b 100644
@@ -1283,16 +1283,19 @@ _git_cherry ()
 	__git_complete_refs
 }
 
+__git_cherry_pick_inprogress_options="--continue --quit --abort"
+
 _git_cherry_pick ()
 {
 	__git_find_repo_path
 	if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then
-		__gitcomp "--continue --quit --abort"
+		__gitcomp "$__git_cherry_pick_inprogress_options"
 		return
 	fi
 	case "$cur" in
 	--*)
-		__gitcomp "--edit --no-commit --signoff --strategy= --mainline"
+		__gitcomp_builtin cherry-pick "" \
+			"$__git_cherry_pick_inprogress_options"
 		;;
 	*)
 		__git_complete_refs
Signature · 1 line
2.16.1.207.gedba492059
#85 lore raw

PATCH v3 11/42 completion: use __gitcomp_builtin in _git_clean

In reply to Nguyễn Thái Ngọc Duy

The new completable options are --exclude and --interactive

---
 builtin/clean.c                        | 2 +-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
builtin/clean.c +1 -1
index 3c4ca9a2ff..fad533a0a7 100644
@@ -909,7 +909,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__QUIET(&quiet, N_("do not print names of files removed")),
 		OPT__DRY_RUN(&dry_run, N_("dry run")),
-		OPT__FORCE(&force, N_("force"), 0),
+		OPT__FORCE(&force, N_("force"), PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")),
 		OPT_BOOL('d', NULL, &remove_directories,
 				N_("remove whole directories")),
contrib/completion/git-completion.bash +1 -1
index 068def9f6b..b7de381876 100644
@@ -1307,7 +1307,7 @@ _git_clean ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--dry-run --quiet"
+		__gitcomp_builtin clean
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#86 lore raw

PATCH v3 12/42 completion: use __gitcomp_builtin in _git_clone

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--config
--dissociate
--ipv4
--ipv6
--jobs=
--progress
--reference-if-able
--separate-git-dir=
--shallow-exclude
--shallow-since=
--verbose

---
 contrib/completion/git-completion.bash | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)
contrib/completion/git-completion.bash +1 -20
index b7de381876..6afab02a4c 100644
@@ -1320,26 +1320,7 @@ _git_clone ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--local
-			--no-hardlinks
-			--shared
-			--reference
-			--quiet
-			--no-checkout
-			--bare
-			--mirror
-			--origin
-			--upload-pack
-			--template=
-			--depth
-			--single-branch
-			--no-tags
-			--branch
-			--recurse-submodules
-			--no-single-branch
-			--shallow-submodules
-			"
+		__gitcomp_builtin clone "--no-single-branch"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#87 lore raw

PATCH v3 13/42 completion: use __gitcomp_builtin in _git_commit

In reply to Nguyễn Thái Ngọc Duy

The new comletable options are:

--branch
--gpg-sign
--long
--no-post-rewrite
--null
--porcelain
--status

--allow-empty is no longer completable because it's a hidden option since 4741edd549 (Remove deprecated OPTION_BOOLEAN for parsing arguments
- 2013-08-03)

---
 contrib/completion/git-completion.bash | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)
contrib/completion/git-completion.bash +1 -10
index 6afab02a4c..0350350079 100644
@@ -1353,16 +1353,7 @@ _git_commit ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--all --author= --signoff --verify --no-verify
-			--edit --no-edit
-			--amend --include --only --interactive
-			--dry-run --reuse-message= --reedit-message=
-			--reset-author --file= --message= --template=
-			--cleanup= --untracked-files --untracked-files=
-			--verbose --quiet --fixup= --squash=
-			--patch --short --date --allow-empty
-			"
+		__gitcomp_builtin commit "--no-edit --verify"
 		return
 	esac
 
Signature · 1 line
2.16.1.207.gedba492059
#88 lore raw

PATCH v3 14/42 completion: use __gitcomp_builtin in _git_config

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--blob=
--bool
--bool-or-int
--edit
--expiry-date
--get-color
--get-colorbool
--get-urlmatch
--includes
--int
--null
--path
--show-origin

---
 contrib/completion/git-completion.bash | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
contrib/completion/git-completion.bash +1 -8
index 0350350079..6e17caf8d7 100644
@@ -2252,14 +2252,7 @@ _git_config ()
 	esac
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--system --global --local --file=
-			--list --replace-all
-			--get --get-all --get-regexp
-			--add --unset --unset-all
-			--remove-section --rename-section
-			--name-only
-			"
+		__gitcomp_builtin config
 		return
 		;;
 	branch.*.*)
Signature · 1 line
2.16.1.207.gedba492059
#89 lore raw

PATCH v3 15/42 completion: use __gitcomp_builtin in _git_describe

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
contrib/completion/git-completion.bash +1 -5
index 6e17caf8d7..7a98f01067 100644
@@ -1369,11 +1369,7 @@ _git_describe ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--all --tags --contains --abbrev= --candidates=
-			--exact-match --debug --long --match --always --first-parent
-			--exclude --dirty --broken
-			"
+		__gitcomp_builtin describe
 		return
 	esac
 	__git_complete_refs
Signature · 1 line
2.16.1.207.gedba492059
#90 lore raw

PATCH v3 16/42 completion: use __gitcomp_builtin in _git_difftool

In reply to Nguyễn Thái Ngọc Duy

Since we can't automatically extract diff options for completion yet, difftool will take all options from $__git_diff_common_options. This brings _a lot_ more completable options to difftool.

--ignore-submodules is added to $__git_diff_common_options to avoid regression in difftool. But it's a good thing anyway even for other diff commands.

---
 contrib/completion/git-completion.bash | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
contrib/completion/git-completion.bash +6 -6
index 7a98f01067..7763f88347 100644
@@ -1394,7 +1394,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
 			--dirstat --dirstat= --dirstat-by-file
 			--dirstat-by-file= --cumulative
 			--diff-algorithm=
-			--submodule --submodule=
+			--submodule --submodule= --ignore-submodules
 "
 
 _git_diff ()
@@ -1435,11 +1435,11 @@ _git_difftool ()
 		return
 		;;
 	--*)
-		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
-			--base --ours --theirs
-			--no-renames --diff-filter= --find-copies-harder
-			--relative --ignore-submodules
-			--tool="
+		__gitcomp_builtin difftool "$__git_diff_common_options
+					--base --cached --ours --theirs
+					--pickaxe-all --pickaxe-regex
+					--relative --staged
+					"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#91 lore raw

PATCH v3 17/42 completion: use __gitcomp_builtin in _git_fetch

In reply to Nguyễn Thái Ngọc Duy

New completable options:

--deepen=
--ipv4
--ipv6
--jobs=
--multiple
--progress
--refmap=
--shallow-exclude=
--shallow-since=
--update-head-ok

Since _git_pull() needs fetch options too, $__git_fetch_options remains. This variable will soon be gone after _git_pull() is updated.

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 7763f88347..4275307c3d 100644
@@ -1462,7 +1462,7 @@ _git_fetch ()
 		return
 		;;
 	--*)
-		__gitcomp "$__git_fetch_options"
+		__gitcomp_builtin fetch "--no-tags"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#92 lore raw

PATCH v3 18/42 completion: use __gitcomp_builtin in _git_fsck

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--connectivity-only
--dangling
--progress
--reflogs

---
 contrib/completion/git-completion.bash | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
contrib/completion/git-completion.bash +1 -4
index 4275307c3d..340e2414ff 100644
@@ -1499,10 +1499,7 @@ _git_fsck ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--tags --root --unreachable --cache --no-reflogs --full
-			--strict --verbose --lost-found --name-objects
-			"
+		__gitcomp_builtin fsck "--no-reflogs"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#93 lore raw

PATCH v3 19/42 completion: use __gitcomp_builtin in _git_gc

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --quiet.

---
 builtin/gc.c                           | 7 +++++--
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)
builtin/gc.c +5 -2
index 3c5eae0edf..7fc5c16254 100644
@@ -360,8 +360,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 			N_("prune unreferenced objects"),
 			PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
 		OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
-		OPT_BOOL(0, "auto", &auto_gc, N_("enable auto-gc mode")),
-		OPT_BOOL(0, "force", &force, N_("force running gc even if there may be another gc running")),
+		OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"),
+			   PARSE_OPT_NOCOMPLETE),
+		OPT_BOOL_F(0, "force", &force,
+			   N_("force running gc even if there may be another gc running"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
 
contrib/completion/git-completion.bash +1 -1
index 340e2414ff..79e9f69d52 100644
@@ -1509,7 +1509,7 @@ _git_gc ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--prune --aggressive"
+		__gitcomp_builtin gc
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#94 lore raw

PATCH v3 20/42 completion: use __gitcomp_builtin in _git_grep

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--after-context=
--before-context=
--color
--context
--exclude-standard
--quiet
--recurse-submodules
--textconv

---
 builtin/grep.c                         | 13 ++++++++-----
 contrib/completion/git-completion.bash | 16 +---------------
 2 files changed, 9 insertions(+), 20 deletions(-)
builtin/grep.c +8 -5
index 3ca4ac80d8..496f33336e 100644
@@ -832,8 +832,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		OPT_BOOL('L', "files-without-match",
 			&opt.unmatch_name_only,
 			N_("show only the names of files without match")),
-		OPT_BOOL('z', "null", &opt.null_following_name,
-			N_("print NUL after filenames")),
+		OPT_BOOL_F('z', "null", &opt.null_following_name,
+			   N_("print NUL after filenames"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('c', "count", &opt.count,
 			N_("show the number of matches instead of matching lines")),
 		OPT__COLOR(&opt.color, N_("highlight matches")),
@@ -884,9 +885,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		OPT_GROUP(""),
 		{ OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
 			N_("pager"), N_("show matching files in the pager"),
-			PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },
-		OPT_BOOL(0, "ext-grep", &external_grep_allowed__ignored,
-			 N_("allow calling of grep(1) (ignored by this build)")),
+			PARSE_OPT_OPTARG | PARSE_OPT_NOCOMPLETE,
+			NULL, (intptr_t)default_pager },
+		OPT_BOOL_F(0, "ext-grep", &external_grep_allowed__ignored,
+			   N_("allow calling of grep(1) (ignored by this build)"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
 
contrib/completion/git-completion.bash +1 -15
index 79e9f69d52..60d27253ee 100644
@@ -1565,21 +1565,7 @@ _git_grep ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--cached
-			--text --ignore-case --word-regexp --invert-match
-			--full-name --line-number
-			--extended-regexp --basic-regexp --fixed-strings
-			--perl-regexp
-			--threads
-			--files-with-matches --name-only
-			--files-without-match
-			--max-depth
-			--count
-			--and --or --not --all-match
-			--break --heading --show-function --function-context
-			--untracked --no-index
-			"
+		__gitcomp_builtin grep
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#95 lore raw

PATCH v3 21/42 completion: use __gitcomp_builtin in _git_help

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 60d27253ee..08f024a0ba 100644
@@ -1583,7 +1583,7 @@ _git_help ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--all --guides --info --man --web"
+		__gitcomp_builtin help
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#96 lore raw

PATCH v3 22/42 completion: use __gitcomp_builtin in _git_init

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --separate-git-dir=.

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 08f024a0ba..36ed502ed0 100644
@@ -1606,7 +1606,7 @@ _git_init ()
 		return
 		;;
 	--*)
-		__gitcomp "--quiet --bare --template= --shared --shared="
+		__gitcomp_builtin init
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#97 lore raw

PATCH v3 23/42 completion: use __gitcomp_builtin in _git_ls_files

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--debug
--empty-directory
--eol
--recurse-submodules
--resolve-undo

---
 contrib/completion/git-completion.bash | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
contrib/completion/git-completion.bash +1 -7
index 36ed502ed0..1ea06b6e17 100644
@@ -1616,13 +1616,7 @@ _git_ls_files ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--cached --deleted --modified --others --ignored
-			--stage --directory --no-empty-directory --unmerged
-			--killed --exclude= --exclude-from=
-			--exclude-per-directory= --exclude-standard
-			--error-unmatch --with-tree= --full-name
-			--abbrev --ignored --exclude-per-directory
-			"
+		__gitcomp_builtin ls-files "--no-empty-directory"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#98 lore raw

PATCH v3 24/42 completion: use __gitcomp_builtin in _git_ls_remote

In reply to Nguyễn Thái Ngọc Duy

The new completable options are --quiet and --upload-pack=.

---
 builtin/ls-remote.c                    | 5 +++--
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)
builtin/ls-remote.c +3 -2
index c4be98ab9e..540d56429f 100644
@@ -60,8 +60,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 		OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
 		OPT_BOOL(0, "get-url", &get_url,
 			 N_("take url.<base>.insteadOf into account")),
-		OPT_SET_INT(0, "exit-code", &status,
-			    N_("exit with exit code 2 if no matching refs are found"), 2),
+		OPT_SET_INT_F(0, "exit-code", &status,
+			      N_("exit with exit code 2 if no matching refs are found"),
+			      2, PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "symref", &show_symref_target,
 			 N_("show underlying ref in addition to the object pointed by it")),
 		OPT_END()
contrib/completion/git-completion.bash +1 -1
index 1ea06b6e17..e22ea60bc8 100644
@@ -1630,7 +1630,7 @@ _git_ls_remote ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--heads --tags --refs --get-url --symref"
+		__gitcomp_builtin ls-remote
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#99 lore raw

PATCH v3 25/42 completion: use __gitcomp_builtin in _git_merge

In reply to Nguyễn Thái Ngọc Duy

New completable options are:

--allow-unrelated-histories
--message=
--overwrite-ignore
--signoff
--strategy-option=
--summary
--verify

The variable $__git_merge_options remains because _git_pull() still needs it. It will soon be gone after _git_pull() is updated.

---
 contrib/completion/git-completion.bash | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
contrib/completion/git-completion.bash +7 -2
index e22ea60bc8..4f598820cd 100644
@@ -1768,8 +1768,13 @@ _git_merge ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "$__git_merge_options
-			--rerere-autoupdate --no-rerere-autoupdate --abort --continue"
+		__gitcomp_builtin merge "--rerere-autoupdate
+				--no-rerere-autoupdate
+				--no-commit --no-edit --no-ff
+				--no-log --no-progress
+				--no-squash --no-stat
+				--no-verify-signatures
+				"
 		return
 	esac
 	__git_complete_refs
Signature · 1 line
2.16.1.207.gedba492059
#100 lore raw

PATCH v3 26/42 completion: use __gitcomp_builtin in _git_merge_base

In reply to Nguyễn Thái Ngọc Duy

The new completion option is --all.

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 4f598820cd..b192a5c0a1 100644
@@ -1798,7 +1798,7 @@ _git_merge_base ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--octopus --independent --is-ancestor --fork-point"
+		__gitcomp_builtin merge-base
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#101 lore raw

PATCH v3 27/42 completion: use __gitcomp_builtin in _git_mv

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --verbose.

---
 builtin/mv.c                           | 3 ++-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
builtin/mv.c +2 -1
index b88023a733..e3e308d282 100644
@@ -122,7 +122,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 	struct option builtin_mv_options[] = {
 		OPT__VERBOSE(&verbose, N_("be verbose")),
 		OPT__DRY_RUN(&show_only, N_("dry run")),
-		OPT__FORCE(&force, N_("force move/rename even if target exists"), 0),
+		OPT__FORCE(&force, N_("force move/rename even if target exists"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")),
 		OPT_END(),
 	};
contrib/completion/git-completion.bash +1 -1
index b192a5c0a1..bbf8623e3a 100644
@@ -1809,7 +1809,7 @@ _git_mv ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--dry-run"
+		__gitcomp_builtin mv
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#102 lore raw

PATCH v3 28/42 completion: use __gitcomp_builtin in _git_name_rev

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--always
--exclude
--name-only
--refs
--undefined

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index bbf8623e3a..c7b8b37f19 100644
@@ -1825,7 +1825,7 @@ _git_mv ()
 
 _git_name_rev ()
 {
-	__gitcomp "--tags --all --stdin"
+	__gitcomp_builtin name-rev
 }
 
 _git_notes ()
Signature · 1 line
2.16.1.207.gedba492059
#103 lore raw

PATCH v3 29/42 completion: use __gitcomp_builtin in _git_notes

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--allow-empty (notes add and notes append)
--for-rewrite= (notes copy)

---
 builtin/notes.c                        |  4 ++--
 contrib/completion/git-completion.bash | 14 ++++++++------
 2 files changed, 10 insertions(+), 8 deletions(-)
builtin/notes.c +2 -2
index b52e71c73e..6990683bd4 100644
@@ -413,7 +413,7 @@ static int add(int argc, const char **argv, const char *prefix)
 			parse_reuse_arg},
 		OPT_BOOL(0, "allow-empty", &allow_empty,
 			N_("allow storing empty note")),
-		OPT__FORCE(&force, N_("replace existing notes"), 0),
+		OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
 		OPT_END()
 	};
 
@@ -484,7 +484,7 @@ static int copy(int argc, const char **argv, const char *prefix)
 	struct notes_tree *t;
 	const char *rewrite_cmd = NULL;
 	struct option options[] = {
-		OPT__FORCE(&force, N_("replace existing notes"), 0),
+		OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")),
 		OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"),
 			   N_("load rewriting config for <command> (implies "
contrib/completion/git-completion.bash +8 -6
index c7b8b37f19..60127daebf 100644
@@ -1835,7 +1835,7 @@ _git_notes ()
 
 	case "$subcommand,$cur" in
 	,--*)
-		__gitcomp '--ref'
+		__gitcomp_builtin notes
 		;;
 	,*)
 		case "$prev" in
@@ -1851,15 +1851,17 @@ _git_notes ()
 	add,--reedit-message=*|append,--reedit-message=*)
 		__git_complete_refs --cur="${cur#*=}"
 		;;
-	add,--*|append,--*)
-		__gitcomp '--file= --message= --reedit-message=
-				--reuse-message='
+	add,--*)
+		__gitcomp_builtin notes_add
+		;;
+	append,--*)
+		__gitcomp_builtin notes_append
 		;;
 	copy,--*)
-		__gitcomp '--stdin'
+		__gitcomp_builtin notes_copy
 		;;
 	prune,--*)
-		__gitcomp '--dry-run --verbose'
+		__gitcomp_builtin notes_prune
 		;;
 	prune,*)
 		;;
Signature · 1 line
2.16.1.207.gedba492059
#104 lore raw

Re: [PATCH v3 29/42] completion: use __gitcomp_builtin in _git_notes

Quoted 18 lines · Nguyễn Thái Ngọc Duy
contrib/completion/git-completion.bash +5 -3
index c7b8b37f19..60127daebf 100644
@@ -1851,15 +1851,17 @@ _git_notes ()
        add,--reedit-message=*|append,--reedit-message=*)
                __git_complete_refs --cur="${cur#*=}"
                ;;
-       add,--*|append,--*)
-               __gitcomp '--file= --message= --reedit-message=
-                               --reuse-message='
+       add,--*)
+               __gitcomp_builtin notes_add
+               ;;
+       append,--*)
+               __gitcomp_builtin notes_append
                ;;

contrib/completion/git-completion.bash _git_notes () · line 1867

Quoted 10 lines
contrib/completion/git-completion.bash +2 -2
        copy,--*)
-               __gitcomp '--stdin'
+               __gitcomp_builtin notes_copy
                ;;
        prune,--*)
-               __gitcomp '--dry-run --verbose'
+               __gitcomp_builtin notes_prune
                ;;
        prune,*)
                ;;

This could be simplified to:

add,--*|append,--*|copy,--*|prune,--*)

        __gitcomp_builtin notes_$subcommand
        ;;

And we could even go one step further:

*,--*)

        __gitcomp_builtin notes_$subcommand
        ;;

This would have the benefit that if any of the remaining subcommands learn --options, then they would be completed right away, without the need to add that subcommand to the case arms. Case in point is 'git notes remove', which already accepts two options, but they are not completed because of the missing 'remove,--*)' case arm. The same would also apply to 'git notes merge's options, except that the completion script completely misses the 'merge' subcommand in the first place (blame on me, 2a5da75579 (bash: support more 'git notes' subcommands and their options, 2010-10-10)).

This also applies to the completion functions of other commands with subcommands ('remote', 'worktree').

The downside is that we would run 'git cmd subcmd --git-completion-helper' even if a subcommand doesn't use parse options. I think that's acceptable.

author
#105 lore raw

Re: [PATCH v3 29/42] completion: use __gitcomp_builtin in _git_notes

Quoted 39 lines · SZEDER Gábor
Quoted 18 lines · Nguyễn Thái Ngọc Duy
contrib/completion/git-completion.bash +5 -3
index c7b8b37f19..60127daebf 100644
@@ -1851,15 +1851,17 @@ _git_notes ()
        add,--reedit-message=*|append,--reedit-message=*)
                __git_complete_refs --cur="${cur#*=}"
                ;;
-       add,--*|append,--*)
-               __gitcomp '--file= --message= --reedit-message=
-                               --reuse-message='
+       add,--*)
+               __gitcomp_builtin notes_add
+               ;;
+       append,--*)
+               __gitcomp_builtin notes_append
                ;;

contrib/completion/git-completion.bash _git_notes () · line 1867

Quoted 10 lines
contrib/completion/git-completion.bash +2 -2
        copy,--*)
-               __gitcomp '--stdin'
+               __gitcomp_builtin notes_copy
                ;;
        prune,--*)
-               __gitcomp '--dry-run --verbose'
+               __gitcomp_builtin notes_prune
                ;;
        prune,*)
                ;;

This could be simplified to:

add,--*|append,--*|copy,--*|prune,--*)

        __gitcomp_builtin notes_$subcommand
        ;;

And we could even go one step further:

Quoted 7 lines

*,--*)

        __gitcomp_builtin notes_$subcommand
        ;;

This would have the benefit that if any of the remaining subcommands learn --options, then they would be completed right away, without the need to add that subcommand to the case arms.

You read my mind ;-) We won't do this in this series though (but I will simplify the code as suggested). parse-options.c does not have any concept about these subcommands. So a bit more work and can (and will) be done separately.

Signature · 1 line
Duy
author
#106 lore raw

Re: [PATCH v3 29/42] completion: use __gitcomp_builtin in _git_notes

Quoted 7 lines · Duy Nguyen
Quoted 6 lines · SZEDER Gábor

And we could even go one step further:

*,--*)

        __gitcomp_builtin notes_$subcommand
        ;;
Quoted 8 lines
Quoted 3 lines

This would have the benefit that if any of the remaining subcommands learn --options, then they would be completed right away, without the need to add that subcommand to the case arms.

You read my mind ;-) We won't do this in this series though (but I will simplify the code as suggested). parse-options.c does not have any concept about these subcommands. So a bit more work and can (and will) be done separately.

Actually I misread you. This is not about completing subcommands but subcommand's options, so it should work nicely. As long as we make sure we handle error cases correctly (e.g. the user try to complete options of a non-existing subcommand)

Signature · 1 line
Duy
#107 lore raw

Re: [PATCH v3 29/42] completion: use __gitcomp_builtin in _git_notes

In reply to Nguyễn Thái Ngọc Duy

contrib/completion/git-completion.bash _git_notes () · line 1841

Quoted 13 lines · Nguyễn Thái Ngọc Duy
contrib/completion/git-completion.bash +1 -1
index c7b8b37f19..60127daebf 100644
@@ -1835,7 +1835,7 @@ _git_notes ()
 
        case "$subcommand,$cur" in
        ,--*)
-               __gitcomp '--ref'
+               __gitcomp_builtin notes
                ;;
        ,*)
                case "$prev" in

Hmm, after this patch is applied, this part of _git_notes() looks like this:

        case "$subcommand,$cur" in
        <skip>
        ,*)
                case "$prev" in
                --ref)
                        __git_complete_refs
                        ;;
                *)
                        __gitcomp "$subcommands --ref"
                        ;;
                esac
                ;;

Note that '--ref' option passed to __gitcomp() along with the subcommands.

It would be great if that option could come from parse options as well, but we can't rely on $__gitcomp_builtin_notes being already initialized at this point and the current __gitcomp_builtin function tightly couples initializing that variable and completing options.

It would be even greater, if all the subcommands could come from parse options as well, but not sure how that would fit into parse options, because subcommands are, well, not --options.

There are only a few commands with subcommands whose main command accepts an --option, too; I could only find 'notes', 'remote', 'stash' and 'submodule'. The latter two are scripts, and for 'remote' we don't offer its '--verbose' option along with its subcommands, but perhaps we should. Anyway, considering that there are only two such cases at the moment, I think we could live with that two hard-coded options.

author
#108 lore raw

Re: [PATCH v3 29/42] completion: use __gitcomp_builtin in _git_notes

Quoted 32 lines · SZEDER Gábor

contrib/completion/git-completion.bash _git_notes () · line 1841

Quoted 13 lines · Nguyễn Thái Ngọc Duy
contrib/completion/git-completion.bash +1 -1
index c7b8b37f19..60127daebf 100644
@@ -1835,7 +1835,7 @@ _git_notes ()
 
        case "$subcommand,$cur" in
        ,--*)
-               __gitcomp '--ref'
+               __gitcomp_builtin notes
                ;;
        ,*)
                case "$prev" in

Hmm, after this patch is applied, this part of _git_notes() looks like this:

        case "$subcommand,$cur" in
        <skip>
        ,*)
                case "$prev" in
                --ref)
                        __git_complete_refs
                        ;;
                *)
                        __gitcomp "$subcommands --ref"
                        ;;
                esac
                ;;
Quoted 4 lines

Note that '--ref' option passed to __gitcomp() along with the subcommands.

It would be great if that option could come from parse options as well,

Yeah. This is where Eric's option annotation thingy comes in very handy. If we can tell git-completion.bash that "--ref takes a ref", then we can do __git_complete_refs automatically.

I'm not so sure how to fit all things together yet. Just like you said below __gitcomp_builtin is very much completing options, not values. Worst case scenario, --git-completion-helper could generate the whole "case" block to be eval'd here, but that also means non-bash completion is left out.

So I'm not going to do anything about this yet. Not until I study some more (and your notes here are very helpful)

Quoted 3 lines

but we can't rely on $__gitcomp_builtin_notes being already initialized at this point and the current __gitcomp_builtin function tightly couples initializing that variable and completing options.

Signature · 1 line
Duy
#109 lore raw

PATCH v3 30/42 completion: use __gitcomp_builtin in _git_pull

In reply to Nguyễn Thái Ngọc Duy

This is really nice. Since pull_options[] already declares all passthru options to 'merge' or 'fetch', a single

    git pull --git-completion-helper

would provide all completable options (--no- variants are a separate issue). Dead shell variables can now be deleted.

New completable options are:

--allow-unrelated-histories
--ipv4
--ipv6
--jobs
--refmap=
--signoff
--strategy-option=

---
 contrib/completion/git-completion.bash | 25 +++++--------------------
 1 file changed, 5 insertions(+), 20 deletions(-)
contrib/completion/git-completion.bash +5 -20
index 60127daebf..697fca0c4b 100644
@@ -1448,12 +1448,6 @@ _git_difftool ()
 
 __git_fetch_recurse_submodules="yes on-demand no"
 
-__git_fetch_options="
-	--quiet --verbose --append --upload-pack --force --keep --depth=
-	--tags --no-tags --all --prune --dry-run --recurse-submodules=
-	--unshallow --update-shallow
-"
-
 _git_fetch ()
 {
 	case "$cur" in
@@ -1754,14 +1748,6 @@ _git_log ()
 	__git_complete_revlist
 }
 
-# Common merge options shared by git-merge(1) and git-pull(1).
-__git_merge_options="
-	--no-commit --no-stat --log --no-log --squash --strategy
-	--commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
-	--verify-signatures --no-verify-signatures --gpg-sign
-	--quiet --verbose --progress --no-progress
-"
-
 _git_merge ()
 {
 	__git_complete_strategy && return
@@ -1887,12 +1873,11 @@ _git_pull ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--rebase --no-rebase
-			--autostash --no-autostash
-			$__git_merge_options
-			$__git_fetch_options
-		"
+		__gitcomp_builtin pull "--no-autostash --no-commit --no-edit
+					--no-ff --no-log --no-progress --no-rebase
+					--no-squash --no-stat --no-tags
+					--no-verify-signatures"
+
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#110 lore raw

PATCH v3 31/42 completion: use __gitcomp_builtin in _git_push

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--atomic
--exec=
--ipv4
--ipv6
--no-verify
--porcelain
--progress
--push-option
--signed

---
 builtin/push.c                         | 2 +-
 contrib/completion/git-completion.bash | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)
builtin/push.c +1 -1
index 1c28427d82..013c20d616 100644
@@ -548,7 +548,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		{ OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, "check|on-demand|no",
 			N_("control recursive pushing of submodules"),
 			PARSE_OPT_OPTARG, option_parse_recurse_submodules },
-		OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")),
+		OPT_BOOL_F( 0 , "thin", &thin, N_("use thin pack"), PARSE_OPT_NOCOMPLETE),
 		OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
 		OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
 		OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
contrib/completion/git-completion.bash +1 -6
index 697fca0c4b..d8d9e8f0de 100644
@@ -1928,12 +1928,7 @@ _git_push ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--all --mirror --tags --dry-run --force --verbose
-			--quiet --prune --delete --follow-tags
-			--receive-pack= --repo= --set-upstream
-			--force-with-lease --force-with-lease= --recurse-submodules=
-		"
+		__gitcomp_builtin push
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#111 lore raw

PATCH v3 32/42 completion: use __gitcomp_builtin in _git_remote

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
contrib/completion/git-completion.bash +8 -8
index d8d9e8f0de..6e600b7aa3 100644
@@ -2612,7 +2612,7 @@ _git_remote ()
 	if [ -z "$subcommand" ]; then
 		case "$cur" in
 		--*)
-			__gitcomp "--verbose"
+			__gitcomp_builtin remote
 			;;
 		*)
 			__gitcomp "$subcommands"
@@ -2623,33 +2623,33 @@ _git_remote ()
 
 	case "$subcommand,$cur" in
 	add,--*)
-		__gitcomp "--track --master --fetch --tags --no-tags --mirror="
+		__gitcomp_builtin remote_add "--no-tags"
 		;;
 	add,*)
 		;;
 	set-head,--*)
-		__gitcomp "--auto --delete"
+		__gitcomp_builtin remote_set-head
 		;;
 	set-branches,--*)
-		__gitcomp "--add"
+		__gitcomp_builtin remote_set-branches
 		;;
 	set-head,*|set-branches,*)
 		__git_complete_remote_or_refspec
 		;;
 	update,--*)
-		__gitcomp "--prune"
+		__gitcomp_builtin remote_update
 		;;
 	update,*)
 		__gitcomp "$(__git_get_config_variables "remotes")"
 		;;
 	set-url,--*)
-		__gitcomp "--push --add --delete"
+		__gitcomp_builtin remote_set-url
 		;;
 	get-url,--*)
-		__gitcomp "--push --all"
+		__gitcomp_builtin remote_get-url
 		;;
 	prune,--*)
-		__gitcomp "--dry-run"
+		__gitcomp_builtin remote_prune
 		;;
 	*)
 		__gitcomp_nl "$(__git_remotes)"
Signature · 1 line
2.16.1.207.gedba492059
#112 lore raw

PATCH v3 33/42 remote: force completing --mirror= instead of --mirror

In reply to Nguyễn Thái Ngọc Duy

"git remote --mirror" is a special case. Technically it is possible to specify --mirror without any argument. But we will get a "dangerous, deprecated!" warning in that case.

This new parse-opt flag allows --git-completion-helper to always complete --mirror=, ignoring the dangerous use case.

---
 builtin/remote.c | 2 +-
 parse-options.c  | 2 ++
 parse-options.h  | 6 +++++-
 3 files changed, 8 insertions(+), 2 deletions(-)
builtin/remote.c +1 -1
index d95bf904c3..fce9e5c0f6 100644
@@ -168,7 +168,7 @@ static int add(int argc, const char **argv)
 		OPT_STRING('m', "master", &master, N_("branch"), N_("master branch")),
 		{ OPTION_CALLBACK, 0, "mirror", &mirror, N_("push|fetch"),
 			N_("set up remote as a mirror to push to or fetch from"),
-			PARSE_OPT_OPTARG, parse_mirror_opt },
+			PARSE_OPT_OPTARG | PARSE_OPT_COMP_ARG, parse_mirror_opt },
 		OPT_END()
 	};
 
parse-options.c +2 -0
index 29f4defdd6..979577ba2c 100644
@@ -459,6 +459,8 @@ static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 		default:
 			break;
 		}
+		if (opts->flags & PARSE_OPT_COMP_ARG)
+			suffix = "=";
 		printf(" --%s%s", opts->long_name, suffix);
 	}
 	fputc('\n', stdout);
parse-options.h +5 -1
index 009cd863e5..0ba08691e6 100644
@@ -39,7 +39,8 @@ enum parse_opt_option_flags {
 	PARSE_OPT_NODASH = 32,
 	PARSE_OPT_LITERAL_ARGHELP = 64,
 	PARSE_OPT_SHELL_EVAL = 256,
-	PARSE_OPT_NOCOMPLETE = 512
+	PARSE_OPT_NOCOMPLETE = 512,
+	PARSE_OPT_COMP_ARG = 1024
 };
 
 struct option;
@@ -92,6 +93,9 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
  *				Useful for options with multiple parameters.
  *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
  *			   by git-completion.bash. This option suppresses that.
+ *   PARSE_OPT_COMP_ARG: this option forces to git-completion.bash to
+ *			 complete an option as --name= not --name even if
+ *			 the option takes optional argument.
  *
  * `callback`::
  *   pointer to the callback to use for OPTION_CALLBACK or
Signature · 1 line
2.16.1.207.gedba492059
#113 lore raw

PATCH v3 34/42 completion: use __gitcomp_builtin in _git_replace

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --raw.

---
 builtin/replace.c                      | 3 ++-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
builtin/replace.c +2 -1
index 10078ae371..0c1d8e1b08 100644
@@ -439,7 +439,8 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
 		OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
 		OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
 		OPT_CMDMODE('g', "graft", &cmdmode, N_("change a commit's parents"), MODE_GRAFT),
-		OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")),
+		OPT_BOOL_F('f', "force", &force, N_("replace the ref if it exists"),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "raw", &raw, N_("do not pretty-print contents for --edit")),
 		OPT_STRING(0, "format", &format, N_("format"), N_("use this format")),
 		OPT_END()
contrib/completion/git-completion.bash +1 -1
index 6e600b7aa3..18c2ccece9 100644
@@ -2661,7 +2661,7 @@ _git_replace ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--edit --graft --format= --list --delete"
+		__gitcomp_builtin replace
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#114 lore raw

PATCH v3 35/42 completion: use __gitcomp_builtin in _git_reset

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--intent-to-add
--quiet
--recurse-submodules

---
 contrib/completion/git-completion.bash | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
index 18c2ccece9..9aca05d01e 100644
@@ -2685,7 +2685,7 @@ _git_reset ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "--merge --mixed --hard --soft --patch --keep"
+		__gitcomp_builtin reset
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#115 lore raw

PATCH v3 36/42 completion: use __gitcomp_builtin in _git_revert

In reply to Nguyễn Thái Ngọc Duy

The new completable option is --gpg-sign

In-progress options like --continue will be part of --git-completion-helper then filtered out by _git_revert() unless the operation is in progress. This helps keep marking of these operations in just one place.

---
 contrib/completion/git-completion.bash | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
contrib/completion/git-completion.bash +5 -5
index 9aca05d01e..e63f2f2741 100644
@@ -2692,19 +2692,19 @@ _git_reset ()
 	__git_complete_refs
 }
 
+__git_revert_inprogress_options="--continue --quit --abort"
+
 _git_revert ()
 {
 	__git_find_repo_path
 	if [ -f "$__git_repo_path"/REVERT_HEAD ]; then
-		__gitcomp "--continue --quit --abort"
+		__gitcomp "$__git_revert_inprogress_options"
 		return
 	fi
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--edit --mainline --no-edit --no-commit --signoff
-			--strategy= --strategy-option=
-			"
+		__gitcomp_builtin revert "--no-edit" \
+			"$__git_revert_inprogress_options"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#116 lore raw

PATCH v3 37/42 completion: use __gitcomp_builtin in _git_rm

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 builtin/rm.c                           | 2 +-
 contrib/completion/git-completion.bash | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
builtin/rm.c +1 -1
index 6e0c7f5ac6..a818efe230 100644
@@ -242,7 +242,7 @@ static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__QUIET(&quiet, N_("do not list removed files")),
 	OPT_BOOL( 0 , "cached",         &index_only, N_("only remove from the index")),
-	OPT__FORCE(&force, N_("override the up-to-date check"), 0),
+	OPT__FORCE(&force, N_("override the up-to-date check"), PARSE_OPT_NOCOMPLETE),
 	OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
 	OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
 				N_("exit with a zero status even if nothing matched")),
contrib/completion/git-completion.bash +1 -1
index e63f2f2741..30a51c5015 100644
@@ -2715,7 +2715,7 @@ _git_rm ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
+		__gitcomp_builtin rm
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#117 lore raw

PATCH v3 38/42 completion: use __gitcomp_builtin in _git_show_branch

In reply to Nguyễn Thái Ngọc Duy

No new completable options!

---
 contrib/completion/git-completion.bash | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
contrib/completion/git-completion.bash +1 -6
index 30a51c5015..7d58969efb 100644
@@ -2773,12 +2773,7 @@ _git_show_branch ()
 {
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--all --remotes --topo-order --date-order --current --more=
-			--list --independent --merge-base --no-name
-			--color --no-color
-			--sha1-name --sparse --topics --reflog
-			"
+		__gitcomp_builtin show-branch "--no-color"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#118 lore raw

PATCH v3 39/42 completion: use __gitcomp_builtin in _git_status

In reply to Nguyễn Thái Ngọc Duy

The new completable options are --null and --show-stash.

---
 contrib/completion/git-completion.bash | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
contrib/completion/git-completion.bash +1 -5
index 7d58969efb..7724ce7808 100644
@@ -2066,11 +2066,7 @@ _git_status ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--short --branch --porcelain --long --verbose
-			--untracked-files= --ignore-submodules= --ignored
-			--column= --no-column
-			"
+		__gitcomp_builtin status "--no-column"
 		return
 		;;
 	esac
Signature · 1 line
2.16.1.207.gedba492059
#119 lore raw

PATCH v3 40/42 completion: use __gitcomp_builtin in _git_tag

In reply to Nguyễn Thái Ngọc Duy

The new completable options are:

--color
--format=
--ignore-case

---
 contrib/completion/git-completion.bash | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
contrib/completion/git-completion.bash +1 -5
index 7724ce7808..e76b2f0356 100644
@@ -3002,11 +3002,7 @@ _git_tag ()
 
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--list --delete --verify --annotate --message --file
-			--sign --cleanup --local-user --force --column --sort=
-			--contains --no-contains --points-at --merged --no-merged --create-reflog
-			"
+		__gitcomp_builtin tag
 		;;
 	esac
 }
Signature · 1 line
2.16.1.207.gedba492059
#120 lore raw

PATCH v3 41/42 completion: use __gitcomp_builtin in _git_worktree

In reply to Nguyễn Thái Ngọc Duy

The new completable options for "worktree add" are:

--checkout
--guess-remote
--lock
--track

---
 builtin/worktree.c                     | 2 +-
 contrib/completion/git-completion.bash | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)
builtin/worktree.c +1 -1
index 4d3422f62e..76dc6b8cb5 100644
@@ -367,7 +367,7 @@ static int add(int ac, const char **av, const char *prefix)
 	struct option options[] = {
 		OPT__FORCE(&opts.force,
 			   N_("checkout <branch> even if already checked out in other worktree"),
-			   0),
+			   PARSE_OPT_NOCOMPLETE),
 		OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
 			   N_("create a new branch")),
 		OPT_STRING('B', NULL, &new_branch_force, N_("branch"),
contrib/completion/git-completion.bash +4 -4
index e76b2f0356..0ddf40063b 100644
@@ -3021,16 +3021,16 @@ _git_worktree ()
 	else
 		case "$subcommand,$cur" in
 		add,--*)
-			__gitcomp "--detach"
+			__gitcomp_builtin worktree_add
 			;;
 		list,--*)
-			__gitcomp "--porcelain"
+			__gitcomp_builtin worktree_list
 			;;
 		lock,--*)
-			__gitcomp "--reason"
+			__gitcomp_builtin worktree_lock
 			;;
 		prune,--*)
-			__gitcomp "--dry-run --expire --verbose"
+			__gitcomp_builtin worktree_prune
 			;;
 		*)
 			;;
Signature · 1 line
2.16.1.207.gedba492059
#121 lore raw

PATCH v3 42/42 git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

In reply to Nguyễn Thái Ngọc Duy

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.

---
 contrib/completion/git-completion.bash |  6 +++++-
 parse-options.c                        | 11 +++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)
contrib/completion/git-completion.bash +5 -1
index 0ddf40063b..0cfa489a8e 100644
@@ -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
 
 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
parse-options.c +7 -4
index 979577ba2c..5b8b2b376e 100644
@@ -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;
Signature · 1 line
2.16.1.207.gedba492059
#122 lore raw

Re: [PATCH v3 42/42] git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

On Fri, Feb 09 2018, Nguyễn Thái Ngọc Duy jotted:

Quoted 16 lines

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.

---
 contrib/completion/git-completion.bash |  6 +++++-
 parse-options.c                        | 11 +++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)
contrib/completion/git-completion.bash +0 -0
index 0ddf40063b..0cfa489a8e 100644

contrib/completion/git-completion.bash line 42

Quoted 7 lines
contrib/completion/git-completion.bash +4 -0
@@ -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.

Quoted 46 lines
contrib/completion/git-completion.bash +1 -1
 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
parse-options.c +7 -4
index 979577ba2c..5b8b2b376e 100644
@@ -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;
author
#123 lore raw

Re: [PATCH v3 42/42] git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

Quoted 50 lines · Ævar Arnfjörð Bjarmason

On Fri, Feb 09 2018, Nguyễn Thái Ngọc Duy jotted:

Quoted 16 lines

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.

---
 contrib/completion/git-completion.bash |  6 +++++-
 parse-options.c                        | 11 +++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)
contrib/completion/git-completion.bash +0 -0
index 0ddf40063b..0cfa489a8e 100644

contrib/completion/git-completion.bash line 42

Quoted 7 lines
contrib/completion/git-completion.bash +4 -0
@@ -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.

Quoted 6 lines

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.

No. You're asking for a second default. I'm not adding plenty of GIT_COMPLETION_* variables for that. You either have all options, or you convince people that --force should be part of the current default.

Or you could push for a generic mechanism that allows you to customize your own default. Something like the below patch could give you what you want with:

GIT_COMPLETION_OPTIONS=all GIT_COMPLETION_EXCLUDES=--open-files-in-pager # and some more . /path/to/git-completion.bash

I'm not going to make a real patch for this since people may want to ignore --foo in one command and complete --foo in others... I'm just not interested in trying to cover all cases.

-- 8< --

contrib/completion/git-completion.bash +5 -1
index 0cfa489a8e..9ca0d80cd7 100644
@@ -40,6 +40,10 @@
 #   GIT_COMPLETION_OPTIONS
 #
 #     When set to "all", complete all possible options
+#
+#   GIT_COMPLETION_EXCLUDES
+#
+#     Exclude some options from the complete list
 
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
@@ -298,7 +302,7 @@ __gitcomp_builtin ()
 	# commands, e.g. "git remote add" becomes remote_add.
 	local cmd="$1"
 	local incl="$2"
-	local excl="$3"
+	local excl="$3 $GIT_COMPLETION_EXCLUDES"
 
 	local var=__gitcomp_builtin_"${cmd/-/_}"
 	local options

-- 8< --

#124 lore raw

Re: [PATCH v3 42/42] git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

On Sat, Feb 10 2018, Duy Nguyen jotted:

Quoted 55 lines · Ævar Arnfjörð Bjarmason
Quoted 54 lines

On Fri, Feb 09 2018, Nguyễn Thái Ngọc Duy jotted:

Quoted 16 lines

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.

---
 contrib/completion/git-completion.bash |  6 +++++-
 parse-options.c                        | 11 +++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)
contrib/completion/git-completion.bash +0 -0
index 0ddf40063b..0cfa489a8e 100644

contrib/completion/git-completion.bash line 42

Quoted 7 lines
contrib/completion/git-completion.bash +4 -0
@@ -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

Quoted 7 lines
Quoted 2 lines

Or other similar boolean variable, for consistency with all the "*SHOW* variables already in git-completion.bash.

No. You're asking for a second default. I'm not adding plenty of GIT_COMPLETION_* variables for that. You either have all options, or you convince people that --force should be part of the current default.

No sorry, I mean that IMO the current patch you have could be simplified where instead of saying "=all" there's just another variable that only hides "dangerous" options, i.e. only "--force" (unless I've missed another supposedly dangerous one).

But as previously discussed I think it just makes sense to stop doing this conditionally and include --force too, the only stuff we should hide is stuff like rebase --continue when not in an interactive rebase.

Quoted 38 lines

Or you could push for a generic mechanism that allows you to customize your own default. Something like the below patch could give you what you want with:

GIT_COMPLETION_OPTIONS=all GIT_COMPLETION_EXCLUDES=--open-files-in-pager # and some more . /path/to/git-completion.bash

I'm not going to make a real patch for this since people may want to ignore --foo in one command and complete --foo in others... I'm just not interested in trying to cover all cases.

-- 8< --

contrib/completion/git-completion.bash +5 -2
index 0cfa489a8e..9ca0d80cd7 100644
@@ -40,6 +40,10 @@
 #   GIT_COMPLETION_OPTIONS
 #
 #     When set to "all", complete all possible options
+#
+#   GIT_COMPLETION_EXCLUDES
+#
+#     Exclude some options from the complete list
 
 case "$COMP_WORDBREAKS" in
 *:*) : great ;;
@@ -298,7 +302,7 @@ __gitcomp_builtin ()
 	# commands, e.g. "git remote add" becomes remote_add.
 	local cmd="$1"
 	local incl="$2"
-	local excl="$3"
+	local excl="$3 $GIT_COMPLETION_EXCLUDES"
 
 	local var=__gitcomp_builtin_"${cmd/-/_}"
 	local options
-- 8< --
#125 lore raw

Re: [PATCH v3 42/42] git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

In reply to Nguyễn Thái Ngọc Duy
Quoted 14 lines · Nguyễn Thái Ngọc Duy

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.

---

contrib/completion/git-completion.bash +4 -0
@@ -36,6 +36,10 @@
+#
+#   GIT_COMPLETION_OPTIONS
+#
+#     When set to "all", complete all possible options

contrib/completion/git-completion.bash __gitcomp_builtin () · line 310

Quoted 5 lines
contrib/completion/git-completion.bash +1 -1
@@ -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 "

This approach is rather different from what I had envisioned. Rather than asking --git-completion-helper to do the filtering, my thought was that it should unconditionally dump _all_ options but annotate them, and then git-completion.bash can filter however it sees fit. For instance, --git-completion-helper might annotate "dangerous" options with a "!" ("!--force" or "--force!" or "--force:!" or whatever).

The benefit of this approach is that it more easily supports future enhancements. For instance, options which only make sense in certain contexts could be annotated to indicate such. An example are the --continue, --abort, --skip options for git-rebase which only make sense when a rebase session is active. One could imagine these options being annotated something like this:

--abort:rebasing
--continue:rebasing
--skip:rebasing

where git-completion.bash understands the "rebasing" annotation as meaning that these options only make sense when "rebase-apply" is present. (In fact, the annotation could be more expressive, such as "--abort:exists(rebase-apply)", but that might be overkill.)

author
#126 lore raw

Re: [PATCH v3 42/42] git-completion.bash: add GIT_COMPLETION_OPTIONS=all config

Quoted 35 lines · Eric Sunshine
Quoted 14 lines · Nguyễn Thái Ngọc Duy

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.

---

contrib/completion/git-completion.bash +4 -0
@@ -36,6 +36,10 @@
+#
+#   GIT_COMPLETION_OPTIONS
+#
+#     When set to "all", complete all possible options

contrib/completion/git-completion.bash __gitcomp_builtin () · line 310

Quoted 5 lines
contrib/completion/git-completion.bash +1 -1
@@ -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 "

This approach is rather different from what I had envisioned. Rather than asking --git-completion-helper to do the filtering, my thought was that it should unconditionally dump _all_ options but annotate them, and then git-completion.bash can filter however it sees fit. For instance, --git-completion-helper might annotate "dangerous" options with a "!" ("!--force" or "--force!" or "--force:!" or whatever).

The benefit of this approach is that it more easily supports future enhancements. For instance, options which only make sense in certain contexts could be annotated to indicate such. An example are the --continue, --abort, --skip options for git-rebase which only make sense when a rebase session is active. One could imagine these options being annotated something like this:

Quoted 8 lines

--abort:rebasing
--continue:rebasing
--skip:rebasing

where git-completion.bash understands the "rebasing" annotation as meaning that these options only make sense when "rebase-apply" is present. (In fact, the annotation could be more expressive, such as "--abort:exists(rebase-apply)", but that might be overkill.)

I agree. I went a bit off track with this ...=all. But yes some form of annotation will be needed long term to describe these options in details. We haven't gotten the annotation in struct option[] to this level yet, it's a bit hard to see what will be needed here. Let's drop 42/42 for now. I will study git-completion.bash more to see what it needs and revisit this at some point in future.

Signature · 1 line
Duy