{"thread":{"id":"47619","subject":"[PATCH/RFC 0/2] Automate updating git-completion.bash a bit","startedAt":"2018-01-16T10:37:19Z","lastAt":"2019-04-11T11:11:33Z","messageCount":14,"participants":["Nguyễn Thái Ngọc Duy","Jacob Keller","Junio C Hamano","Duy Nguyen","SZEDER Gábor"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"336652","messageId":"20180116103700.4505-1-pclouds@gmail.com","threadId":"47619","inReplyTo":null,"subject":"[PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-16T10:36:58Z","receivedAt":"2018-01-16T10:37:19Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"I noticed --recurse-submodules was missing from git-grep complete\nlist. Then I found a couple more should be on the list as well and\nmany more in future may face the same faith. Perhaps this helps remedy\nthis situation?\n\nThis lets us extract certain information from git commands and feed it\ndirectly to git-completion.bash. Now long options by default will\nbe complete-able (which also means it's the reviewer's and coder's\nresponsibility to add \"no complete\" flag appropriately) but I think\nthe number of new dangerous options will be much fewer than\ncompleteable ones.\n\nThis is not really a new idea. Python has argcomplete that does more\nor less the same thing.\n\nThis is just a proof of concept. More commands should be converted of\ncourse if it's a good thing to do.\n\nNguyễn Thái Ngọc Duy (2):\n  parse-options: support --git-completion-helper\n  git-completion: use --git-completion-helper\n\n builtin/grep.c                         | 13 +++++++-----\n contrib/completion/git-completion.bash | 16 +--------------\n parse-options.c                        | 37 ++++++++++++++++++++++++++++++++++\n parse-options.h                        | 14 ++++++++-----\n 4 files changed, 55 insertions(+), 25 deletions(-)\n\n-- \n2.15.1.600.g899a5f85c6\n\n"},{"id":"336653","messageId":"20180116103700.4505-2-pclouds@gmail.com","threadId":"47619","inReplyTo":"20180116103700.4505-1-pclouds@gmail.com","subject":"[PATCH 1/2] parse-options: support --git-completion-helper","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-16T10:36:59Z","receivedAt":"2018-01-16T10:37:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This option is designed to be used by git-completion.bash. For many\nsimple cases, what we do in there is usually\n\n    __gitcomp \"lots of completion options\"\n\nwhich has to be manually updated when a new user-visible option is\nadded. With support from parse-options, we can write\n\n    __gitcomp \"$(git command --git-completion-helper)\"\n\nand get that list directly from the parser for free. Dangerous/Unpopular\noptions could be hidden with the new \"NO_GITCOMP\" flag.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n parse-options.c | 37 +++++++++++++++++++++++++++++++++++++\n parse-options.h |  6 ++++--\n 2 files changed, 41 insertions(+), 2 deletions(-)\n\ndiff --git a/parse-options.c b/parse-options.c\nindex fca7159646..6c542f44cf 100644\n--- a/parse-options.c\n+++ b/parse-options.c\n@@ -425,6 +425,35 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,\n \tparse_options_check(options);\n }\n \n+static int show_gitcomp(struct parse_opt_ctx_t *ctx, const struct option *opts)\n+{\n+\tfor (; opts->type != OPTION_END; opts++) {\n+\t\tconst char *suffix;\n+\n+\t\tif (!opts->long_name)\n+\t\t\tcontinue;\n+\t\tif (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NO_GITCOMP))\n+\t\t\tcontinue;\n+\n+\t\tswitch (opts->type) {\n+\t\tcase OPTION_GROUP:\n+\t\t\tcontinue;\n+\t\tcase OPTION_STRING:\n+\t\tcase OPTION_FILENAME:\n+\t\tcase OPTION_INTEGER:\n+\t\tcase OPTION_MAGNITUDE:\n+\t\t\tif (!(opts->flags & PARSE_OPT_OPTARG))\n+\t\t\t\tsuffix = \"=\";\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tsuffix = \"\";\n+\t\t}\n+\t\tprintf(\" --%s%s\", opts->long_name, suffix);\n+\t}\n+\tfputc('\\n', stdout);\n+\texit(0);\n+}\n+\n static int usage_with_options_internal(struct parse_opt_ctx_t *,\n \t\t\t\t       const char * const *,\n \t\t\t\t       const struct option *, int, int);\n@@ -434,6 +463,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,\n \t\t       const char * const usagestr[])\n {\n \tint internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);\n+\tint internal_gitcomp = !(ctx->flags & PARSE_OPT_NO_INTERNAL_GITCOMP);\n \tint err = 0;\n \n \t/* we must reset ->opt, unknown short option leave it dangling */\n@@ -455,6 +485,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,\n \t\tif (internal_help && ctx->total == 1 && !strcmp(arg + 1, \"h\"))\n \t\t\tgoto show_usage;\n \n+\t\t/* lone --git-completion-helper is asked by git-completion.bash */\n+\t\tif (internal_gitcomp && ctx->total == 1 &&\n+\t\t    !strcmp(arg + 1, \"-git-completion-helper\"))\n+\t\t\tgoto show_git_comp;\n+\n \t\tif (arg[1] != '-') {\n \t\t\tctx->opt = arg + 1;\n \t\t\tswitch (parse_short_opt(ctx, options)) {\n@@ -521,6 +556,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,\n \terr = 1;\n  show_usage:\n \treturn usage_with_options_internal(ctx, usagestr, options, 0, err);\n+ show_git_comp:\n+\treturn show_gitcomp(ctx, options);\n }\n \n int parse_options_end(struct parse_opt_ctx_t *ctx)\ndiff --git a/parse-options.h b/parse-options.h\nindex af711227ae..8a3389b05b 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -27,7 +27,8 @@ enum parse_opt_flags {\n \tPARSE_OPT_STOP_AT_NON_OPTION = 2,\n \tPARSE_OPT_KEEP_ARGV0 = 4,\n \tPARSE_OPT_KEEP_UNKNOWN = 8,\n-\tPARSE_OPT_NO_INTERNAL_HELP = 16\n+\tPARSE_OPT_NO_INTERNAL_HELP = 16,\n+\tPARSE_OPT_NO_INTERNAL_GITCOMP = 32\n };\n \n enum parse_opt_option_flags {\n@@ -38,7 +39,8 @@ enum parse_opt_option_flags {\n \tPARSE_OPT_LASTARG_DEFAULT = 16,\n \tPARSE_OPT_NODASH = 32,\n \tPARSE_OPT_LITERAL_ARGHELP = 64,\n-\tPARSE_OPT_SHELL_EVAL = 256\n+\tPARSE_OPT_SHELL_EVAL = 256,\n+\tPARSE_OPT_NO_GITCOMP = 512\n };\n \n struct option;\n-- \n2.15.1.600.g899a5f85c6\n\n"},{"id":"336654","messageId":"20180116103700.4505-3-pclouds@gmail.com","threadId":"47619","inReplyTo":"20180116103700.4505-1-pclouds@gmail.com","subject":"[PATCH 2/2] git-completion: use --git-completion-helper","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-16T10:37:00Z","receivedAt":"2018-01-16T10:37:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The builtin command is updated to hide some options. The new options\nthat are complete-able are:\n\n--after-context=\n--all-match\n--before-context=\n--color\n--context\n--exclude-standard\n--recurse-submodules\n--textconv\n\n--max-depth and --threads are already completable, but now it will\ncomplete with the \"=\" suffix because these always take an argument.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/grep.c                         | 13 ++++++++-----\n contrib/completion/git-completion.bash | 16 +---------------\n parse-options.h                        |  8 +++++---\n 3 files changed, 14 insertions(+), 23 deletions(-)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 3ca4ac80d8..8fe5560ee8 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -832,8 +832,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL('L', \"files-without-match\",\n \t\t\t&opt.unmatch_name_only,\n \t\t\tN_(\"show only the names of files without match\")),\n-\t\tOPT_BOOL('z', \"null\", &opt.null_following_name,\n-\t\t\tN_(\"print NUL after filenames\")),\n+\t\tOPT_BOOL_F('z', \"null\", &opt.null_following_name,\n+\t\t\t   N_(\"print NUL after filenames\"),\n+\t\t\t   PARSE_OPT_NO_GITCOMP),\n \t\tOPT_BOOL('c', \"count\", &opt.count,\n \t\t\tN_(\"show the number of matches instead of matching lines\")),\n \t\tOPT__COLOR(&opt.color, N_(\"highlight matches\")),\n@@ -884,9 +885,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\tOPT_GROUP(\"\"),\n \t\t{ OPTION_STRING, 'O', \"open-files-in-pager\", &show_in_pager,\n \t\t\tN_(\"pager\"), N_(\"show matching files in the pager\"),\n-\t\t\tPARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },\n-\t\tOPT_BOOL(0, \"ext-grep\", &external_grep_allowed__ignored,\n-\t\t\t N_(\"allow calling of grep(1) (ignored by this build)\")),\n+\t\t\tPARSE_OPT_OPTARG | PARSE_OPT_NO_GITCOMP,\n+\t\t\tNULL, (intptr_t)default_pager },\n+\t\tOPT_BOOL_F(0, \"ext-grep\", &external_grep_allowed__ignored,\n+\t\t\t   N_(\"allow calling of grep(1) (ignored by this build)\"),\n+\t\t\t   PARSE_OPT_NO_GITCOMP),\n \t\tOPT_END()\n \t};\n \ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 3683c772c5..f0d9126fd6 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1585,21 +1585,7 @@ _git_grep ()\n \n \tcase \"$cur\" in\n \t--*)\n-\t\t__gitcomp \"\n-\t\t\t--cached\n-\t\t\t--text --ignore-case --word-regexp --invert-match\n-\t\t\t--full-name --line-number\n-\t\t\t--extended-regexp --basic-regexp --fixed-strings\n-\t\t\t--perl-regexp\n-\t\t\t--threads\n-\t\t\t--files-with-matches --name-only\n-\t\t\t--files-without-match\n-\t\t\t--max-depth\n-\t\t\t--count\n-\t\t\t--and --or --not --all-match\n-\t\t\t--break --heading --show-function --function-context\n-\t\t\t--untracked --no-index\n-\t\t\t\"\n+\t\t__gitcomp \"$(git grep --git-completion-helper)\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/parse-options.h b/parse-options.h\nindex 8a3389b05b..2bd833a4c5 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -124,9 +124,11 @@ struct option {\n \t\t\t\t      (h), PARSE_OPT_NOARG, NULL, (b) }\n #define OPT_COUNTUP(s, l, v, h)     { OPTION_COUNTUP, (s), (l), (v), NULL, \\\n \t\t\t\t      (h), PARSE_OPT_NOARG }\n-#define OPT_SET_INT(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \\\n-\t\t\t\t      (h), PARSE_OPT_NOARG, NULL, (i) }\n-#define OPT_BOOL(s, l, v, h)        OPT_SET_INT(s, l, v, h, 1)\n+#define OPT_SET_INT_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \\\n+\t\t\t\t\t  (h), PARSE_OPT_NOARG | (f), NULL, (i) }\n+#define OPT_SET_INT(s, l, v, h, i)  OPT_SET_INT_F(s, l, v, h, i, 0)\n+#define OPT_BOOL_F(s, l, v, h, f)   OPT_SET_INT_F(s, l, v, h, 1, f)\n+#define OPT_BOOL(s, l, v, h)        OPT_BOOL_F(s, l, v, h, 0)\n #define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \\\n \t\t\t\t      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}\n #define OPT_CMDMODE(s, l, v, h, i)  { OPTION_CMDMODE, (s), (l), (v), NULL, \\\n-- \n2.15.1.600.g899a5f85c6\n\n"},{"id":"336665","messageId":"CA+P7+xohkxpoBHTVcD5i-=gT_evL5HKhCGLyV0LYyj8YdyLmqg@mail.gmail.com","threadId":"47619","inReplyTo":"20180116103700.4505-2-pclouds@gmail.com","subject":"Re: [PATCH 1/2] parse-options: support --git-completion-helper","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2018-01-16T18:25:42Z","receivedAt":"2018-01-16T18:26:09Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Tue, Jan 16, 2018 at 2:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> This option is designed to be used by git-completion.bash. For many\n> simple cases, what we do in there is usually\n>\n>     __gitcomp \"lots of completion options\"\n>\n> which has to be manually updated when a new user-visible option is\n> added. With support from parse-options, we can write\n>\n>     __gitcomp \"$(git command --git-completion-helper)\"\n>\n> and get that list directly from the parser for free. Dangerous/Unpopular\n> options could be hidden with the new \"NO_GITCOMP\" flag.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nWas this possibly avoided in the past due to being slower than simply\nstoring the list in the completion code itself?\n\nI think this is a good idea myself.\n\nThanks,\nJake\n\n> ---\n>  parse-options.c | 37 +++++++++++++++++++++++++++++++++++++\n>  parse-options.h |  6 ++++--\n>  2 files changed, 41 insertions(+), 2 deletions(-)\n>\n> diff --git a/parse-options.c b/parse-options.c\n> index fca7159646..6c542f44cf 100644\n> --- a/parse-options.c\n> +++ b/parse-options.c\n> @@ -425,6 +425,35 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,\n>         parse_options_check(options);\n>  }\n>\n> +static int show_gitcomp(struct parse_opt_ctx_t *ctx, const struct option *opts)\n> +{\n> +       for (; opts->type != OPTION_END; opts++) {\n> +               const char *suffix;\n> +\n> +               if (!opts->long_name)\n> +                       continue;\n> +               if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NO_GITCOMP))\n> +                       continue;\n> +\n> +               switch (opts->type) {\n> +               case OPTION_GROUP:\n> +                       continue;\n> +               case OPTION_STRING:\n> +               case OPTION_FILENAME:\n> +               case OPTION_INTEGER:\n> +               case OPTION_MAGNITUDE:\n> +                       if (!(opts->flags & PARSE_OPT_OPTARG))\n> +                               suffix = \"=\";\n> +                       break;\n> +               default:\n> +                       suffix = \"\";\n> +               }\n> +               printf(\" --%s%s\", opts->long_name, suffix);\n> +       }\n> +       fputc('\\n', stdout);\n> +       exit(0);\n> +}\n> +\n>  static int usage_with_options_internal(struct parse_opt_ctx_t *,\n>                                        const char * const *,\n>                                        const struct option *, int, int);\n> @@ -434,6 +463,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,\n>                        const char * const usagestr[])\n>  {\n>         int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);\n> +       int internal_gitcomp = !(ctx->flags & PARSE_OPT_NO_INTERNAL_GITCOMP);\n>         int err = 0;\n>\n>         /* we must reset ->opt, unknown short option leave it dangling */\n> @@ -455,6 +485,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,\n>                 if (internal_help && ctx->total == 1 && !strcmp(arg + 1, \"h\"))\n>                         goto show_usage;\n>\n> +               /* lone --git-completion-helper is asked by git-completion.bash */\n> +               if (internal_gitcomp && ctx->total == 1 &&\n> +                   !strcmp(arg + 1, \"-git-completion-helper\"))\n> +                       goto show_git_comp;\n> +\n>                 if (arg[1] != '-') {\n>                         ctx->opt = arg + 1;\n>                         switch (parse_short_opt(ctx, options)) {\n> @@ -521,6 +556,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,\n>         err = 1;\n>   show_usage:\n>         return usage_with_options_internal(ctx, usagestr, options, 0, err);\n> + show_git_comp:\n> +       return show_gitcomp(ctx, options);\n>  }\n>\n>  int parse_options_end(struct parse_opt_ctx_t *ctx)\n> diff --git a/parse-options.h b/parse-options.h\n> index af711227ae..8a3389b05b 100644\n> --- a/parse-options.h\n> +++ b/parse-options.h\n> @@ -27,7 +27,8 @@ enum parse_opt_flags {\n>         PARSE_OPT_STOP_AT_NON_OPTION = 2,\n>         PARSE_OPT_KEEP_ARGV0 = 4,\n>         PARSE_OPT_KEEP_UNKNOWN = 8,\n> -       PARSE_OPT_NO_INTERNAL_HELP = 16\n> +       PARSE_OPT_NO_INTERNAL_HELP = 16,\n> +       PARSE_OPT_NO_INTERNAL_GITCOMP = 32\n>  };\n>\n>  enum parse_opt_option_flags {\n> @@ -38,7 +39,8 @@ enum parse_opt_option_flags {\n>         PARSE_OPT_LASTARG_DEFAULT = 16,\n>         PARSE_OPT_NODASH = 32,\n>         PARSE_OPT_LITERAL_ARGHELP = 64,\n> -       PARSE_OPT_SHELL_EVAL = 256\n> +       PARSE_OPT_SHELL_EVAL = 256,\n> +       PARSE_OPT_NO_GITCOMP = 512\n>  };\n>\n>  struct option;\n> --\n> 2.15.1.600.g899a5f85c6\n>\n"},{"id":"336680","messageId":"xmqq4lnltlia.fsf@gitster.mtv.corp.google.com","threadId":"47619","inReplyTo":"20180116103700.4505-2-pclouds@gmail.com","subject":"Re: [PATCH 1/2] parse-options: support --git-completion-helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-01-16T23:46:37Z","receivedAt":"2018-01-16T23:46:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> This option is designed to be used by git-completion.bash. For many\n> simple cases, what we do in there is usually\n>\n>     __gitcomp \"lots of completion options\"\n>\n> which has to be manually updated when a new user-visible option is\n> added. With support from parse-options, we can write\n>\n>     __gitcomp \"$(git command --git-completion-helper)\"\n>\n> and get that list directly from the parser for free. Dangerous/Unpopular\n> options could be hidden with the new \"NO_GITCOMP\" flag.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  parse-options.c | 37 +++++++++++++++++++++++++++++++++++++\n>  parse-options.h |  6 ++++--\n>  2 files changed, 41 insertions(+), 2 deletions(-)\n\nI do not know if you need PARSE_OPT_NO_INTERNAL_GITCOMP.  The only\nway to trigger this is by passing a rather long option (intended to\nbe used only by scripts), so unlike PARSE_OPT_NO_INTERNAL_HELP which\nwas an escape hatch to free a short-and-sweet \"-h\" to be retargetted\nby a selected few commands, there may not be need for it.\n\nSome day when everybody uses parse-options, it would be trivially\ncorrect to declare that this is the right approach ;-) I am not sure\nhow much of the current completion script's hardcoded option list\ncan be reduced with this approach with today's code, given that the\nbigger ones (diff and log family) are not using parse-options API at\nall, but for the ones that already do use parse-options, I think\nthis makes sense.\n\nThanks for a fun read ;-)\n\n"},{"id":"336682","messageId":"CACsJy8BeODhidfBthT2oDWOzBv8jakpg8=O3yz+wMLhu-tAWzQ@mail.gmail.com","threadId":"47619","inReplyTo":"CA+P7+xohkxpoBHTVcD5i-=gT_evL5HKhCGLyV0LYyj8YdyLmqg@mail.gmail.com","subject":"Re: [PATCH 1/2] parse-options: support --git-completion-helper","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-17T00:21:21Z","receivedAt":"2018-01-17T00:21:56Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jan 17, 2018 at 1:25 AM, Jacob Keller <jacob.keller@gmail.com> wrote:\n> On Tue, Jan 16, 2018 at 2:36 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>> This option is designed to be used by git-completion.bash. For many\n>> simple cases, what we do in there is usually\n>>\n>>     __gitcomp \"lots of completion options\"\n>>\n>> which has to be manually updated when a new user-visible option is\n>> added. With support from parse-options, we can write\n>>\n>>     __gitcomp \"$(git command --git-completion-helper)\"\n>>\n>> and get that list directly from the parser for free. Dangerous/Unpopular\n>> options could be hidden with the new \"NO_GITCOMP\" flag.\n>>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>\n> Was this possibly avoided in the past due to being slower than simply\n> storing the list in the completion code itself?\n\nAt least on linux I would not worry too much about performance (but\nthen I don't know what platforms this git-completion supports and\nwhether this may become real performance problems for them).\ngit-completion.bash already executes some heavy commands (getting refs\nfor completion for example), though this makes the script call git\nmuch earlier.\n\nThere's one thing I will have to be careful about though, that to make\nsure that --git-completion-helper runs even if the command itself is\nnot supposed to run, e.g. calling git-status without a worktree will\nfail, but calling 'git status --git-completion-helper' should still\nwork in that condition.\n\n-- \nDuy\n"},{"id":"336683","messageId":"CACsJy8C1-sjeEgFBRx45zHeqNo2ZcgDvoRMs0mKtJLUqmtQsAg@mail.gmail.com","threadId":"47619","inReplyTo":"xmqq4lnltlia.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 1/2] parse-options: support --git-completion-helper","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-17T00:27:13Z","receivedAt":"2018-01-17T00:27:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jan 17, 2018 at 6:46 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>\n>> This option is designed to be used by git-completion.bash. For many\n>> simple cases, what we do in there is usually\n>>\n>>     __gitcomp \"lots of completion options\"\n>>\n>> which has to be manually updated when a new user-visible option is\n>> added. With support from parse-options, we can write\n>>\n>>     __gitcomp \"$(git command --git-completion-helper)\"\n>>\n>> and get that list directly from the parser for free. Dangerous/Unpopular\n>> options could be hidden with the new \"NO_GITCOMP\" flag.\n>>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>>  parse-options.c | 37 +++++++++++++++++++++++++++++++++++++\n>>  parse-options.h |  6 ++++--\n>>  2 files changed, 41 insertions(+), 2 deletions(-)\n>\n> I do not know if you need PARSE_OPT_NO_INTERNAL_GITCOMP.  The only\n> way to trigger this is by passing a rather long option (intended to\n> be used only by scripts), so unlike PARSE_OPT_NO_INTERNAL_HELP which\n> was an escape hatch to free a short-and-sweet \"-h\" to be retargetted\n> by a selected few commands, there may not be need for it.\n\nIt's a copy/paste from internal_help. Because I was asking for\ncomments, not really aiming to submit these changes to git.git (yet),\nI didn't bother to check further.\n\n> Some day when everybody uses parse-options, it would be trivially\n> correct to declare that this is the right approach ;-) I am not sure\n> how much of the current completion script's hardcoded option list\n> can be reduced with this approach with today's code, given that the\n> bigger ones (diff and log family) are not using parse-options API at\n> all, but for the ones that already do use parse-options, I think\n> this makes sense.\n\nYeah yeah the horrible handle_revision_opt() and diff_opt_parse(). I\nthink I attempted to convert them two parse-options at some point, not\nsure why I dropped it, maybe because target variables are in\ndynamically allocated memory ('struct diff_options *' and 'struct\nrev_info *') which does not fit well to how we usually initialize\n'struct options[]'.\n-- \nDuy\n"},{"id":"336686","messageId":"CAM0VKjkz8-VsLJ8i64OHHUH4R4WY5fT6x3X+s=FKuZyfM9txkA@mail.gmail.com","threadId":"47619","inReplyTo":"20180116103700.4505-1-pclouds@gmail.com","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2018-01-17T00:51:56Z","receivedAt":"2018-01-17T00:52:03Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Tue, Jan 16, 2018 at 11:36 AM, Nguyễn Thái Ngọc Duy\n<pclouds@gmail.com> wrote:\n> I noticed --recurse-submodules was missing from git-grep complete\n> list. Then I found a couple more should be on the list as well and\n> many more in future may face the same faith. Perhaps this helps remedy\n> this situation?\n>\n> This lets us extract certain information from git commands and feed it\n> directly to git-completion.bash. Now long options by default will\n> be complete-able (which also means it's the reviewer's and coder's\n> responsibility to add \"no complete\" flag appropriately) but I think\n> the number of new dangerous options will be much fewer than\n> completeable ones.\n>\n> This is not really a new idea. Python has argcomplete that does more\n> or less the same thing.\n\nThis has come up before for Git as well, see:\n\n  https://public-inbox.org/git/1334140165-24958-1-git-send-email-bebarino@gmail.com/T/#u\n\nI see that your approach solves one of the shortcomings of those older\npatches, namely it makes possible to omit dangerous options from\ncompletion.  Great.\n\nI also see that you want to invoke git in a subshell every time the user\nattempts to complete an --option.  Not so great, at least for Windows\nusers.  That older thread contains a few ideas about how to do it only\nonce by lazy-initializing a variable for each command to hold its\noptions.\n\n\n> This is just a proof of concept. More commands should be converted of\n> course if it's a good thing to do.\n>\n> Nguyễn Thái Ngọc Duy (2):\n>   parse-options: support --git-completion-helper\n>   git-completion: use --git-completion-helper\n>\n>  builtin/grep.c                         | 13 +++++++-----\n>  contrib/completion/git-completion.bash | 16 +--------------\n>  parse-options.c                        | 37 ++++++++++++++++++++++++++++++++++\n>  parse-options.h                        | 14 ++++++++-----\n>  4 files changed, 55 insertions(+), 25 deletions(-)\n>\n> --\n> 2.15.1.600.g899a5f85c6\n>\n"},{"id":"336692","messageId":"CACsJy8D3wRmP_o5iFJwWtODOJpj-r=JZsJ3P8XxWOCD8rJJrHA@mail.gmail.com","threadId":"47619","inReplyTo":"CAM0VKjkz8-VsLJ8i64OHHUH4R4WY5fT6x3X+s=FKuZyfM9txkA@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-17T09:16:22Z","receivedAt":"2018-01-17T09:17:03Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jan 17, 2018 at 7:51 AM, SZEDER Gábor <szeder.dev@gmail.com> wrote:\n> On Tue, Jan 16, 2018 at 11:36 AM, Nguyễn Thái Ngọc Duy\n> <pclouds@gmail.com> wrote:\n>> I noticed --recurse-submodules was missing from git-grep complete\n>> list. Then I found a couple more should be on the list as well and\n>> many more in future may face the same faith. Perhaps this helps remedy\n>> this situation?\n>>\n>> This lets us extract certain information from git commands and feed it\n>> directly to git-completion.bash. Now long options by default will\n>> be complete-able (which also means it's the reviewer's and coder's\n>> responsibility to add \"no complete\" flag appropriately) but I think\n>> the number of new dangerous options will be much fewer than\n>> completeable ones.\n>>\n>> This is not really a new idea. Python has argcomplete that does more\n>> or less the same thing.\n>\n> This has come up before for Git as well, see:\n>\n>   https://public-inbox.org/git/1334140165-24958-1-git-send-email-bebarino@gmail.com/T/#u\n\nThanks! I did search the archive but couldn't find this one.\n\n>\n> I see that your approach solves one of the shortcomings of those older\n> patches, namely it makes possible to omit dangerous options from\n> completion.  Great.\n>\n> I also see that you want to invoke git in a subshell every time the user\n> attempts to complete an --option.  Not so great, at least for Windows\n> users.  That older thread contains a few ideas about how to do it only\n> once by lazy-initializing a variable for each command to hold its\n> options.\n\nNoted.\n\nI see you also pointed out the problem with running commands like\n\"git-status\" without a repository. I'll try to address this too if\npossible (I'm thinking about making struct options[] available outside\ncmd_*(); then we could handle it more like \"git --version\" which\nalways works)\n-- \nDuy\n"},{"id":"336693","messageId":"20180117093432.GA19189@ash","threadId":"47619","inReplyTo":"CACsJy8D3wRmP_o5iFJwWtODOJpj-r=JZsJ3P8XxWOCD8rJJrHA@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-17T09:34:32Z","receivedAt":"2018-01-17T09:34:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Actually I forgot another option. What if we automate updating the\nscript at \"compile\" time instead of calling git at run time? E.g. with\nsomething like below, a contributor could just run\n\n    make update-completion\n\nthen add git-completion.bash changes to the same patch that introduces\nnew options. If they forget, Junio could always run this near -rc0.\n\nI know this output is a bit ugly. I probably could try to make the\nupdate work with wrapped __gitcomp lines to be friendlier to human\neyes.\n\n-- 8< --\ndiff --git a/Makefile b/Makefile\nindex 1a9b23b679..05eb7c8742 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2834,3 +2834,5 @@ cover_db: coverage-report\n cover_db_html: cover_db\n \tcover -report html -outputdir cover_db_html cover_db\n \n+update-completion:\n+\tcontrib/completion/update.sh contrib/completion/git-completion.bash ./git\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 3683c772c5..e8c224f486 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1585,21 +1585,7 @@ _git_grep ()\n \n \tcase \"$cur\" in\n \t--*)\n-\t\t__gitcomp \"\n-\t\t\t--cached\n-\t\t\t--text --ignore-case --word-regexp --invert-match\n-\t\t\t--full-name --line-number\n-\t\t\t--extended-regexp --basic-regexp --fixed-strings\n-\t\t\t--perl-regexp\n-\t\t\t--threads\n-\t\t\t--files-with-matches --name-only\n-\t\t\t--files-without-match\n-\t\t\t--max-depth\n-\t\t\t--count\n-\t\t\t--and --or --not --all-match\n-\t\t\t--break --heading --show-function --function-context\n-\t\t\t--untracked --no-index\n-\t\t\t\"\n+\t\t__gitcomp_auto grep \"--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\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/contrib/completion/update.sh b/contrib/completion/update.sh\nnew file mode 100755\nindex 0000000000..99c4841152\n--- /dev/null\n+++ b/contrib/completion/update.sh\n@@ -0,0 +1,8 @@\n+#!/bin/sh\n+\n+file=\"$1\"\n+git=\"$2\"\n+\n+grep __gitcomp_auto \"$file\" | while read a cmd b; do\n+    sed -i \"s/\\\\(.*$a $cmd \\).*/\\\\1$(\"$git\" $cmd --git-completion-helper)/\" \"$file\"\n+done\n-- 8< --\n\n\n\n\nOn Wed, Jan 17, 2018 at 04:16:22PM +0700, Duy Nguyen wrote:\n> On Wed, Jan 17, 2018 at 7:51 AM, SZEDER Gábor <szeder.dev@gmail.com> wrote:\n> > On Tue, Jan 16, 2018 at 11:36 AM, Nguyễn Thái Ngọc Duy\n> > <pclouds@gmail.com> wrote:\n> >> I noticed --recurse-submodules was missing from git-grep complete\n> >> list. Then I found a couple more should be on the list as well and\n> >> many more in future may face the same faith. Perhaps this helps remedy\n> >> this situation?\n> >>\n> >> This lets us extract certain information from git commands and feed it\n> >> directly to git-completion.bash. Now long options by default will\n> >> be complete-able (which also means it's the reviewer's and coder's\n> >> responsibility to add \"no complete\" flag appropriately) but I think\n> >> the number of new dangerous options will be much fewer than\n> >> completeable ones.\n> >>\n> >> This is not really a new idea. Python has argcomplete that does more\n> >> or less the same thing.\n> >\n> > This has come up before for Git as well, see:\n> >\n> >   https://public-inbox.org/git/1334140165-24958-1-git-send-email-bebarino@gmail.com/T/#u\n> \n> Thanks! I did search the archive but couldn't find this one.\n> \n> >\n> > I see that your approach solves one of the shortcomings of those older\n> > patches, namely it makes possible to omit dangerous options from\n> > completion.  Great.\n> >\n> > I also see that you want to invoke git in a subshell every time the user\n> > attempts to complete an --option.  Not so great, at least for Windows\n> > users.  That older thread contains a few ideas about how to do it only\n> > once by lazy-initializing a variable for each command to hold its\n> > options.\n> \n> Noted.\n> \n> I see you also pointed out the problem with running commands like\n> \"git-status\" without a repository. I'll try to address this too if\n> possible (I'm thinking about making struct options[] available outside\n> cmd_*(); then we could handle it more like \"git --version\" which\n> always works)\n> -- \n> Duy\n"},{"id":"337096","messageId":"CAM0VKj=NeQ_BthG087vswP=mCizXPBcfmCAa9haH4N5MRCNRWQ@mail.gmail.com","threadId":"47619","inReplyTo":"20180117093432.GA19189@ash","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2018-01-22T18:03:24Z","receivedAt":"2018-01-22T18:03:30Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Wed, Jan 17, 2018 at 10:34 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> Actually I forgot another option. What if we automate updating the\n> script at \"compile\" time instead of calling git at run time? E.g. with\n> something like below, a contributor could just run\n>\n>     make update-completion\n>\n> then add git-completion.bash changes to the same patch that introduces\n> new options. If they forget\n\nThey inevitably will :)\nIf contributors have to remember something anyway, then they might\nas well remember to update the completion script in the first place.\n\nAnother alternative would be to extend t9902 with (preferably\nauto-generated) tests to compare the output of 'git $cmd\n--git-completion-helper' with 'run_completion \"git $cmd --\"'.  Then\ncontributors wouldn't have to remember anything, because everyone runs\nthe full test suite every time anyway, right?\n\nHowever, that would result in some code churn initially, because I\nsuspect the options are listed in different order in the command and\nin the completion script.\n\nAll in all I don't think it would trump getting all --options straight\nfrom the commands themselves.\n"},{"id":"337149","messageId":"20180123095927.GA26613@ash","threadId":"47619","inReplyTo":"CAM0VKj=NeQ_BthG087vswP=mCizXPBcfmCAa9haH4N5MRCNRWQ@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-01-23T09:59:27Z","receivedAt":"2018-01-23T09:59:39Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Jan 22, 2018 at 07:03:24PM +0100, SZEDER Gábor wrote:\n> On Wed, Jan 17, 2018 at 10:34 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> > Actually I forgot another option. What if we automate updating the\n> > script at \"compile\" time instead of calling git at run time? E.g. with\n> > something like below, a contributor could just run\n> >\n> >     make update-completion\n> >\n> > then add git-completion.bash changes to the same patch that introduces\n> > new options. If they forget\n> \n> They inevitably will :)\n\nOK. We go with the first option then (with caching to reduce overhead\non Windows). I'm not going to bother you with actual code changes. The\ndiff of completable options looks like below. It would be great if\npeople could check if some options should NOT be completable for some\nreason.\n\nA couple points\n\n- Ignore options that are removed in the diff. They are removed for a\n  reason which I will explain when real patches come.\n\n- There are regressions where --foo= becomes --foo, I hope this is ok\n  for now. We can tweak this later.\n\n- In some commands you can complete both --foo and --foo= (now it's\n  just one form, --foo). I would argue that it's pointless. It's no\n  big deal to type '=' (or a space) after we have completed --foo.\n\n- I feel --force is not treated the same way everywhere. But I guess\n  that's ok since \"forcing\" in some command context may be less severe\n  than others.\n\n-- 8< --\ndiff --git a/git-add.txt b/git-add.txt\nindex 1c249a3..2693cc1 100644\n--- a/git-add.txt\n+++ b/git-add.txt\n@@ -1,10 +1,15 @@\n+--all\n --chmod=\n --dry-run\n --edit\n --force\n --ignore-errors\n+--ignore-missing\n+--ignore-removal\n --intent-to-add\n --interactive\n --patch\n --refresh\n+--renormalize\n --update\n+--verbose\ndiff --git a/git-am.txt b/git-am.txt\nindex b0082bf..552dc96 100644\n--- a/git-am.txt\n+++ b/git-am.txt\n@@ -1,12 +1,24 @@\n --3way\n --committer-date-is-author-date\n+--directory\n+--exclude\n+--gpg-sign\n --ignore-date\n --ignore-space-change\n --ignore-whitespace\n+--include\n --interactive\n --keep\n+--keep-cr\n+--keep-non-patch\n+--message-id\n+--no-keep-cr\n --no-utf8\n+--patch-format\n+--quiet\n+--reject\n+--resolvemsg=\n --scissors\n --signoff\n --utf8\n---whitespace=\n+--whitespace\ndiff --git a/git-apply.txt b/git-apply.txt\nindex 6bf4c2f..71d53d2 100644\n--- a/git-apply.txt\n+++ b/git-apply.txt\n@@ -1,13 +1,17 @@\n+--3way\n+--allow-overlap\n --apply\n+--build-fake-ancestor=\n --cached\n --check\n---directory=\n---exclude=\n+--directory\n+--exclude\n --ignore-space-change\n --ignore-whitespace\n --inaccurate-eof\n+--include\n --index\n---index-info\n+--no-add\n --no-add\n --numstat\n --recount\n@@ -17,4 +21,4 @@\n --summary\n --unidiff-zero\n --verbose\n---whitespace=\n+--whitespace\ndiff --git a/git-branch.txt b/git-branch.txt\nindex 69594e3..9d308aa 100644\n--- a/git-branch.txt\n+++ b/git-branch.txt\n@@ -1,10 +1,14 @@\n---abbrev=\n+--abbrev\n+--all\n --color\n --column\n --contains\n --copy\n+--create-reflog\n --delete\n --edit-description\n+--format=\n+--ignore-case\n --list\n --merged\n --move\n@@ -15,9 +19,10 @@\n --no-merged\n --no-track\n --points-at\n+--quiet\n --remotes\n --set-upstream-to=\n---sort=\n+--sort\n --track\n --unset-upstream\n --verbose\ndiff --git a/git-checkout.txt b/git-checkout.txt\nindex 493a1fe..75f19d2 100644\n--- a/git-checkout.txt\n+++ b/git-checkout.txt\n@@ -1,12 +1,14 @@\n --conflict=\n --detach\n+--ignore-other-worktrees\n --ignore-skip-worktree-bits\n --merge\n --no-recurse-submodules\n --no-track\n---orphan\n+--orphan=\n --ours\n --patch\n+--progress\n --quiet\n --recurse-submodules\n --theirs\ndiff --git a/git-cherry-pick.txt b/git-cherry-pick.txt\nindex 39ba895..f8cdbce 100644\n--- a/git-cherry-pick.txt\n+++ b/git-cherry-pick.txt\n@@ -1,5 +1,14 @@\n+--abort\n+--allow-empty\n+--allow-empty-message\n+--continue\n --edit\n+--ff\n+--gpg-sign\n+--keep-redundant-commits\n --mainline\n --no-commit\n+--quit\n --signoff\n --strategy=\n+--strategy-option\ndiff --git a/git-clean.txt b/git-clean.txt\nindex 40407f7..10c6155 100644\n--- a/git-clean.txt\n+++ b/git-clean.txt\n@@ -1,2 +1,4 @@\n --dry-run\n+--exclude\n+--interactive\n --quiet\ndiff --git a/git-clone.txt b/git-clone.txt\nindex f6e892b..1b6a4da 100644\n--- a/git-clone.txt\n+++ b/git-clone.txt\n@@ -1,18 +1,29 @@\n --bare\n---branch\n---depth\n+--branch=\n+--config\n+--depth=\n+--dissociate\n+--ipv4\n+--ipv6\n+--jobs=\n --local\n --mirror\n --no-checkout\n --no-hardlinks\n --no-single-branch\n --no-tags\n---origin\n+--origin=\n+--progress\n --quiet\n --recurse-submodules\n --reference\n+--reference-if-able\n+--separate-git-dir=\n+--shallow-exclude\n+--shallow-since=\n --shallow-submodules\n --shared\n --single-branch\n --template=\n---upload-pack\n+--upload-pack=\n+--verbose\ndiff --git a/git-commit.txt b/git-commit.txt\nindex 2f98a59..337a57e 100644\n--- a/git-commit.txt\n+++ b/git-commit.txt\n@@ -1,20 +1,26 @@\n --all\n---allow-empty\n --amend\n --author=\n+--branch\n --cleanup=\n---date\n+--date=\n --dry-run\n --edit\n --file=\n --fixup=\n+--gpg-sign\n --include\n --interactive\n---message=\n+--long\n+--message\n --no-edit\n+--no-post-rewrite\n --no-verify\n+--no-verify\n+--null\n --only\n --patch\n+--porcelain\n --quiet\n --reedit-message=\n --reset-author\n@@ -22,8 +28,7 @@\n --short\n --signoff\n --squash=\n+--status\n --template=\n --untracked-files\n---untracked-files=\n --verbose\n---verify\ndiff --git a/git-config.txt b/git-config.txt\nindex c4bcd1e..651fc27 100644\n--- a/git-config.txt\n+++ b/git-config.txt\n@@ -1,15 +1,28 @@\n --add\n+--blob=\n+--bool\n+--bool-or-int\n+--edit\n+--expiry-date\n --file=\n --get\n --get-all\n+--get-color\n+--get-colorbool\n --get-regexp\n+--get-urlmatch\n --global\n+--includes\n+--int\n --list\n --local\n --name-only\n+--null\n+--path\n --remove-section\n --rename-section\n --replace-all\n+--show-origin\n --system\n --unset\n --unset-all\ndiff --git a/git-describe.txt b/git-describe.txt\nindex 05eeb7a..275debb 100644\n--- a/git-describe.txt\n+++ b/git-describe.txt\n@@ -1,4 +1,4 @@\n---abbrev=\n+--abbrev\n --all\n --always\n --broken\ndiff --git a/git-fsck.txt b/git-fsck.txt\nindex 9732ebf..3af9964 100644\n--- a/git-fsck.txt\n+++ b/git-fsck.txt\n@@ -1,8 +1,12 @@\n --cache\n+--connectivity-only\n+--dangling\n --full\n --lost-found\n --name-objects\n --no-reflogs\n+--progress\n+--reflogs\n --root\n --strict\n --tags\ndiff --git a/git-gc.txt b/git-gc.txt\nindex 3b7ca6f..c08e60a 100644\n--- a/git-gc.txt\n+++ b/git-gc.txt\n@@ -1,2 +1,3 @@\n --aggressive\n --prune\n+--quiet\ndiff --git a/git-grep.txt b/git-grep.txt\nindex 6bec8f7..f7770be 100644\n--- a/git-grep.txt\n+++ b/git-grep.txt\n@@ -1,9 +1,14 @@\n+--after-context=\n --all-match\n --and\n --basic-regexp\n+--before-context=\n --break\n --cached\n+--color\n+--context\n --count\n+--exclude-standard\n --extended-regexp\n --files-with-matches\n --files-without-match\n@@ -14,14 +19,17 @@\n --ignore-case\n --invert-match\n --line-number\n---max-depth\n+--max-depth=\n --name-only\n --no-index\n --not\n --or\n --perl-regexp\n+--quiet\n+--recurse-submodules\n --show-function\n --text\n---threads\n+--textconv\n+--threads=\n --untracked\n --word-regexp\ndiff --git a/git-init.txt b/git-init.txt\nindex a7d3da6..aec6a35 100644\n--- a/git-init.txt\n+++ b/git-init.txt\n@@ -1,5 +1,5 @@\n --bare\n --quiet\n+--separate-git-dir=\n --shared\n---shared=\n --template=\ndiff --git a/git-ls-files.txt b/git-ls-files.txt\nindex 04d6f08..6810eb0 100644\n--- a/git-ls-files.txt\n+++ b/git-ls-files.txt\n@@ -1,20 +1,23 @@\n --abbrev\n --cached\n+--debug\n --deleted\n --directory\n+--empty-directory\n+--eol\n --error-unmatch\n---exclude=\n---exclude-from=\n---exclude-per-directory\n+--exclude\n+--exclude-from\n --exclude-per-directory=\n --exclude-standard\n --full-name\n --ignored\n---ignored\n --killed\n --modified\n --no-empty-directory\n --others\n+--recurse-submodules\n+--resolve-undo\n --stage\n --unmerged\n --with-tree=\ndiff --git a/git-ls-remote.txt b/git-ls-remote.txt\nindex c58c80e..381384b 100644\n--- a/git-ls-remote.txt\n+++ b/git-ls-remote.txt\n@@ -1,5 +1,7 @@\n --get-url\n --heads\n+--quiet\n --refs\n --symref\n --tags\n+--upload-pack=\ndiff --git a/git-mv.txt b/git-mv.txt\nindex c26c9e6..28ae674 100644\n--- a/git-mv.txt\n+++ b/git-mv.txt\n@@ -1 +1,2 @@\n --dry-run\n+--verbose\ndiff --git a/git-name-rev.txt b/git-name-rev.txt\nindex 7b1acde..1e5044a 100644\n--- a/git-name-rev.txt\n+++ b/git-name-rev.txt\n@@ -1,3 +1,8 @@\n --all\n+--always\n+--exclude\n+--name-only\n+--refs\n --stdin\n --tags\n+--undefined\ndiff --git a/git-notes_add.txt b/git-notes_add.txt\nindex 87cb06b..4c2dfc1 100644\n--- a/git-notes_add.txt\n+++ b/git-notes_add.txt\n@@ -1,4 +1,5 @@\n---file=\n---message=\n---reedit-message=\n---reuse-message=\n+--allow-empty\n+--file\n+--message\n+--reedit-message\n+--reuse-message\ndiff --git a/git-notes_append.txt b/git-notes_append.txt\nindex 87cb06b..4c2dfc1 100644\n--- a/git-notes_append.txt\n+++ b/git-notes_append.txt\n@@ -1,4 +1,5 @@\n---file=\n---message=\n---reedit-message=\n---reuse-message=\n+--allow-empty\n+--file\n+--message\n+--reedit-message\n+--reuse-message\ndiff --git a/git-notes_copy.txt b/git-notes_copy.txt\nindex 93aa025..d088b96 100644\n--- a/git-notes_copy.txt\n+++ b/git-notes_copy.txt\n@@ -1 +1,2 @@\n+--for-rewrite=\n --stdin\ndiff --git a/git-push.txt b/git-push.txt\nindex 1f4182f..5ea1e39 100644\n--- a/git-push.txt\n+++ b/git-push.txt\n@@ -1,16 +1,24 @@\n --all\n+--atomic\n --delete\n --dry-run\n+--exec=\n --follow-tags\n --force\n --force-with-lease\n---force-with-lease=\n+--ipv4\n+--ipv6\n --mirror\n+--no-verify\n+--porcelain\n+--progress\n --prune\n+--push-option\n --quiet\n --receive-pack=\n---recurse-submodules=\n+--recurse-submodules\n --repo=\n --set-upstream\n+--signed\n --tags\n --verbose\ndiff --git a/git-remote_add.txt b/git-remote_add.txt\nindex aed6530..4889f31 100644\n--- a/git-remote_add.txt\n+++ b/git-remote_add.txt\n@@ -1,6 +1,6 @@\n --fetch\n---master\n---mirror=\n+--master=\n+--mirror\n --no-tags\n --tags\n --track\ndiff --git a/git-replace.txt b/git-replace.txt\nindex 53cd1aa..d494653 100644\n--- a/git-replace.txt\n+++ b/git-replace.txt\n@@ -3,3 +3,4 @@\n --format=\n --graft\n --list\n+--raw\ndiff --git a/git-reset.txt b/git-reset.txt\nindex eafefbc..840cbae 100644\n--- a/git-reset.txt\n+++ b/git-reset.txt\n@@ -1,6 +1,9 @@\n --hard\n+--intent-to-add\n --keep\n --merge\n --mixed\n --patch\n+--quiet\n+--recurse-submodules\n --soft\ndiff --git a/git-revert.txt b/git-revert.txt\nindex abd5c1e..ffa0d80 100644\n--- a/git-revert.txt\n+++ b/git-revert.txt\n@@ -1,7 +1,11 @@\n+--abort\n+--continue\n --edit\n+--gpg-sign\n --mainline\n --no-commit\n --no-edit\n+--quit\n --signoff\n --strategy=\n---strategy-option=\n+--strategy-option\ndiff --git a/git-show-branch.txt b/git-show-branch.txt\nindex e3c3096..37c9594 100644\n--- a/git-show-branch.txt\n+++ b/git-show-branch.txt\n@@ -5,7 +5,7 @@\n --independent\n --list\n --merge-base\n---more=\n+--more\n --no-color\n --no-name\n --reflog\ndiff --git a/git-status.txt b/git-status.txt\nindex 2dce372..ed86ad5 100644\n--- a/git-status.txt\n+++ b/git-status.txt\n@@ -1,10 +1,12 @@\n --branch\n---column=\n+--column\n --ignored\n---ignore-submodules=\n+--ignore-submodules\n --long\n --no-column\n+--null\n --porcelain\n --short\n---untracked-files=\n+--show-stash\n+--untracked-files\n --verbose\ndiff --git a/git-tag.txt b/git-tag.txt\nindex b983562..a5419db 100644\n--- a/git-tag.txt\n+++ b/git-tag.txt\n@@ -1,18 +1,21 @@\n --annotate\n---cleanup\n+--cleanup=\n+--color\n --column\n --contains\n --create-reflog\n --delete\n---file\n+--file=\n --force\n+--format=\n+--ignore-case\n --list\n---local-user\n+--local-user=\n --merged\n --message\n --no-contains\n --no-merged\n --points-at\n --sign\n---sort=\n+--sort\n --verify\ndiff --git a/git-worktree_add.txt b/git-worktree_add.txt\nindex 9dd7f92..3cb6a7e 100644\n--- a/git-worktree_add.txt\n+++ b/git-worktree_add.txt\n@@ -1 +1,5 @@\n+--checkout\n --detach\n+--guess-remote\n+--lock\n+--track\ndiff --git a/git-worktree_lock.txt b/git-worktree_lock.txt\nindex a0bc06b..6ad59bb 100644\n--- a/git-worktree_lock.txt\n+++ b/git-worktree_lock.txt\n@@ -1 +1 @@\n---reason\n+--reason=\n-- 8< --\n--\nDuy\n"},{"id":"373629","messageId":"20190411111038.GA5620@ash","threadId":"47619","inReplyTo":"CAM0VKjkz8-VsLJ8i64OHHUH4R4WY5fT6x3X+s=FKuZyfM9txkA@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2019-04-11T11:10:38Z","receivedAt":"2019-04-11T11:10:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"\n"},{"id":"373630","messageId":"CACsJy8Ays5vUs9aREmornQGhT7dMEkd8uzA90A2=Ghf1BfN_8w@mail.gmail.com","threadId":"47619","inReplyTo":"20190411111038.GA5620@ash","subject":"Re: [PATCH/RFC 0/2] Automate updating git-completion.bash a bit","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2019-04-11T11:11:05Z","receivedAt":"2019-04-11T11:11:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Sorry mistyped 'y', please ignore.\n\nOn Thu, Apr 11, 2019 at 6:10 PM Duy Nguyen <pclouds@gmail.com> wrote:\n>\n>\n\n\n-- \nDuy\n"}]}