{"thread":{"id":"56329","subject":"[PATCH v2 0/3] send-email: shell completion improvements","startedAt":"2021-08-20T00:47:09Z","lastAt":"2021-10-28T16:31:37Z","messageCount":58,"participants":["Thiago Perrotta","Junio C Hamano","Bagas Sanjaya","Carlo Arenas","Ævar Arnfjörð Bjarmason","Carlo Marcelo Arenas Belón"],"isPatch":true,"patchVersion":2,"patchTotal":3},"messages":[{"id":"433190","messageId":"20210820004604.9948-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":null,"subject":"[PATCH v2 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-20T00:46:01Z","receivedAt":"2021-08-20T00:47:09Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"This patch makes git-send-email(1) shell completion (bash, zsh) uniform,\ncentralizing the completion options on git-send-email.perl instead of\ngit-completion.bash\n\nThe overall result is that git send-email --git-completion-helper now\nproperly emits send-email specific options. Previously, it was only\nemitting format-patch flags.\n\nAdditionally there's a sentence in git-send-email(1) to explicitly\nmention that format-patch options can also be passed to it. Currently\nit's not obvious this is the case from the man page alone.\n\nDifference from V1: Improved commit messages.\n\nThiago Perrotta (3):\n  send-email: print newline for --git-completion-helper\n  send-email: move bash completions to the perl script\n  send-email docs: mention format-patch options\n\n Documentation/git-send-email.txt       |  2 ++\n contrib/completion/git-completion.bash | 11 +-------\n git-send-email.perl                    | 35 ++++++++++++++++++++++++++\n t/t9902-completion.sh                  |  3 +++\n 4 files changed, 41 insertions(+), 10 deletions(-)\n\n-- \n2.33.0\n\n"},{"id":"433191","messageId":"20210820004604.9948-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"20210820004604.9948-1-tbperrotta@gmail.com","subject":"[PATCH v2 1/3] send-email: print newline for --git-completion-helper","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-20T00:46:02Z","receivedAt":"2021-08-20T00:47:10Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Rationale: Currently all git built-in commands print a newline upon upon git\n<cmd> --git-completion-helper. Therefore git-send-email should follow suit for\nconsistency.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n git-send-email.perl | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..e991bf333d 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -115,6 +115,7 @@ sub usage {\n \n sub completion_helper {\n     print Git::command('format-patch', '--git-completion-helper');\n+    print \"\\n\";\n     exit(0);\n }\n \n-- \n2.33.0\n\n"},{"id":"433192","messageId":"20210820004604.9948-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"20210820004604.9948-1-tbperrotta@gmail.com","subject":"[PATCH v2 2/3] send-email: move bash completions to the perl script","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-20T00:46:03Z","receivedAt":"2021-08-20T00:47:12Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"As far as bash-completion is concerned, this refactoring is a no-op.\n\nHowever, this improves `git send-email --git-completion-helper`, which\nwas previously printing only `git format-patch` flags, to print\n`send-email` specific flags as well.\n\nAdd a completion test for `--validate` which is a send-email specific\noption.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +--------\n git-send-email.perl                    | 34 ++++++++++++++++++++++++++\n t/t9902-completion.sh                  |  3 +++\n 3 files changed, 38 insertions(+), 10 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e991bf333d..eec78d76c7 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,6 +114,40 @@ sub usage {\n }\n \n sub completion_helper {\n+    my @send_email_flags = qw/\n+    --annotate\n+    --bcc\n+    --cc\n+    --cc-cmd\n+    --chain-reply-to\n+    --compose\n+    --confirm=\n+    --dry-run\n+    --envelope-sender\n+    --from\n+    --identity\n+    --in-reply-to\n+    --no-chain-reply-to\n+    --no-signed-off-by-cc\n+    --no-suppress-from\n+    --no-thread\n+    --quiet\n+    --reply-to\n+    --signed-off-by-cc\n+    --smtp-pass\n+    --smtp-server\n+    --smtp-server-port\n+    --smtp-encryption=\n+    --smtp-user\n+    --subject\n+    --suppress-cc=\n+    --suppress-from\n+    --thread\n+    --to\n+    --validate\n+    --no-validate\n+    /;\n+    print \"@send_email_flags\";\n     print Git::command('format-patch', '--git-completion-helper');\n     print \"\\n\";\n     exit(0);\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"433193","messageId":"20210820004604.9948-4-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"20210820004604.9948-1-tbperrotta@gmail.com","subject":"[PATCH v2 3/3] send-email docs: mention format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-20T00:46:04Z","receivedAt":"2021-08-20T00:47:14Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Currently git-send-email(1) does not make it explicit that format-patch\noptions are accepted.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..05dd8ded44 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -42,6 +42,8 @@ and the \"Subject:\" of the message as the second line.\n OPTIONS\n -------\n \n+Options from linkgit:git-format-patch[1] are also accepted.\n+\n Composing\n ~~~~~~~~~\n \n-- \n2.33.0\n\n"},{"id":"433276","messageId":"xmqqmtpbub07.fsf@gitster.g","threadId":"56329","inReplyTo":"20210820004604.9948-2-tbperrotta@gmail.com","subject":"Re: [PATCH v2 1/3] send-email: print newline for --git-completion-helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-08-20T20:17:12Z","receivedAt":"2021-08-20T20:17:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thiago Perrotta <tbperrotta@gmail.com> writes:\n\n> Rationale: Currently all git built-in commands print a newline upon upon git\n> <cmd> --git-completion-helper. Therefore git-send-email should follow suit for\n> consistency.\n\n\"upon upon\".\n\nYou do not need to start with \"Rationale\", because one of the things\nyou need to have in any proposed log message is a justification for\nthe change.  You also do not need \"Currently\" in our log message, as\nthe convention here is to state the status quo in the present tense,\npoint out what's wrong there (or leave it unsaid and implied by the\ndescription of the current state, if it is obvious), state the\napproach to correct what's wrong, and finally give an order to the\ncodebase to \"become like so\".\n\n\tUnlike other Git subcommands, \"git send-email\" leaves its\n\toutput an incomplete line when \"--git-completion-helper\" is\n\tasked.  Be consistent by terminating the message with LF\n\there.\n\nor something like that.\n\nI do not know which style is preferred among\n\n (1)\tprint something;\n\tprint \"\\n\";\n\n (2)\tprint something, \"\\n\";\n\n (3)\tprint something . \"\\n\";\n\nbut other than that, the goal and the implementation both sound\nsensible (the second one is what I'd be writing if I were doing this\nchange myself, FWIW).\n\nThanks.\n\n> Signed-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n> ---\n>  git-send-email.perl | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/git-send-email.perl b/git-send-email.perl\n> index e65d969d0b..e991bf333d 100755\n> --- a/git-send-email.perl\n> +++ b/git-send-email.perl\n> @@ -115,6 +115,7 @@ sub usage {\n>  \n>  sub completion_helper {\n>      print Git::command('format-patch', '--git-completion-helper');\n> +    print \"\\n\";\n>      exit(0);\n>  }\n"},{"id":"433278","messageId":"xmqqh7fjuaar.fsf@gitster.g","threadId":"56329","inReplyTo":"20210820004604.9948-4-tbperrotta@gmail.com","subject":"Re: [PATCH v2 3/3] send-email docs: mention format-patch options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-08-20T20:32:28Z","receivedAt":"2021-08-20T20:32:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thiago Perrotta <tbperrotta@gmail.com> writes:\n\n> Currently git-send-email(1) does not make it explicit that format-patch\n> options are accepted.\n\nIt may be a feature ;-), as running format-patch while send-email is\nrunning encourages a wrong workflow.\n\nBut as long as we allow users to do so, we'd need to desribe it.\n\n\n> Signed-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n> ---\n>  Documentation/git-send-email.txt | 2 ++\n>  1 file changed, 2 insertions(+)\n>\n> diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\n> index 3db4eab4ba..05dd8ded44 100644\n> --- a/Documentation/git-send-email.txt\n> +++ b/Documentation/git-send-email.txt\n> @@ -42,6 +42,8 @@ and the \"Subject:\" of the message as the second line.\n>  OPTIONS\n>  -------\n>  \n> +Options from linkgit:git-format-patch[1] are also accepted.\n> +\n\nThe program works in two majorly different modes.  It either takes\n\n * message files that are already proof-read and copy-edited from\n   the filesystem and sends them out, or \n\n * format-patch options to generate message files out of the commits\n   and send them out without any proofreading.\n\nThe documentation for OPTIONS has various sections, starting from\nComposing, then Sending, Automating, Administering, and Information.\n\nBy having this new sentence before all the sections gives a wrong\nimpression that format-patch options are accepted in both modes.\nBut the format-patch options are relevant only when we are using the\nlatter operation mode.  Unlike that, all the options documented\nunder these sections starting from Composing are applicable to both\nmodes.\n\nWe may want to clarify that we have two modes near the top of the\ndocument, perhaps like the attached, and extend the description a\nbit there.\n\n Documentation/git-send-email.txt | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git c/Documentation/git-send-email.txt w/Documentation/git-send-email.txt\nindex 3db4eab4ba..8adc8ace79 100644\n--- c/Documentation/git-send-email.txt\n+++ w/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, and options understood by\n+linkgit:git-format-patch[1] can be passed.\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\n\n\n"},{"id":"434000","messageId":"20210828030839.2989-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"xmqqmtpbub07.fsf@gitster.g","subject":"[PATCH v3 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-28T03:08:36Z","receivedAt":"2021-08-28T03:09:25Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email\" completion (bash, zsh) is inconsistent, its flags are\nsplit into both git-completion.bash and git-send-email.perl, and it only\nemits format-patch flags.\n\nMake shell completion uniform, centralizing completion\noptions on git-send-email.perl.\n\nMake \"git send-email --git-completion-helper\" properly emit send-email\nspecific options.\n\nAdditionally, update git-send-email(1) man page to explicitly\nmention format-patch options.\n\nDifferences from V2:\n\n- Incorporate Junio's code suggestions.\n- Follow proper conventions for git commit messages.\n\nThiago Perrotta (3):\n  send-email: terminate --git-completion-helper with LF\n  send-email: move bash completions to core script\n  send-email docs: add format-patch options\n\n Documentation/git-send-email.txt       |  6 +++--\n contrib/completion/git-completion.bash | 11 +-------\n git-send-email.perl                    | 36 +++++++++++++++++++++++++-\n t/t9902-completion.sh                  |  3 +++\n 4 files changed, 43 insertions(+), 13 deletions(-)\n\n-- \n2.33.0\n\n"},{"id":"434001","messageId":"20210828030839.2989-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"xmqqmtpbub07.fsf@gitster.g","subject":"[PATCH v3 1/3] send-email: terminate --git-completion-helper with LF","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-28T03:08:37Z","receivedAt":"2021-08-28T03:09:25Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Unlike other Git subcommands, \"git send-email\" leaves its output an\nincomplete line when \"--git-completion-helper\" is asked.  Be consistent\nby terminating the message with LF here.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n git-send-email.perl | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..d1731c1755 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,7 +114,7 @@ sub usage {\n }\n \n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n+    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\n \n-- \n2.33.0\n\n"},{"id":"434002","messageId":"20210828030839.2989-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"xmqqmtpbub07.fsf@gitster.g","subject":"[PATCH v3 2/3] send-email: move bash completions to core script","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-28T03:08:38Z","receivedAt":"2021-08-28T03:09:29Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well.\n\nAdd a completion test for \"send-email --validate\", a send-email option.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +--------\n git-send-email.perl                    | 34 ++++++++++++++++++++++++++\n t/t9902-completion.sh                  |  3 +++\n 3 files changed, 38 insertions(+), 10 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex d1731c1755..cbaefcd943 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,6 +114,40 @@ sub usage {\n }\n \n sub completion_helper {\n+    my @send_email_flags = qw/\n+    --annotate\n+    --bcc\n+    --cc\n+    --cc-cmd\n+    --chain-reply-to\n+    --compose\n+    --confirm=\n+    --dry-run\n+    --envelope-sender\n+    --from\n+    --identity\n+    --in-reply-to\n+    --no-chain-reply-to\n+    --no-signed-off-by-cc\n+    --no-suppress-from\n+    --no-thread\n+    --quiet\n+    --reply-to\n+    --signed-off-by-cc\n+    --smtp-pass\n+    --smtp-server\n+    --smtp-server-port\n+    --smtp-encryption=\n+    --smtp-user\n+    --subject\n+    --suppress-cc=\n+    --suppress-from\n+    --thread\n+    --to\n+    --validate\n+    --no-validate\n+    /;\n+    print \"@send_email_flags\";\n     print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"434003","messageId":"20210828030839.2989-4-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"xmqqmtpbub07.fsf@gitster.g","subject":"[PATCH v3 3/3] send-email docs: add format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-08-28T03:08:39Z","receivedAt":"2021-08-28T03:09:29Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"git-send-email(1) does not mention that \"git format-patch\" options are\naccepted. Augment SYNOPSIS and DESCRIPTION to mention it.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..8adc8ace79 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, and options understood by\n+linkgit:git-format-patch[1] can be passed.\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\n-- \n2.33.0\n\n"},{"id":"434007","messageId":"f54fdc77-e87a-75cd-dffa-719e30067495@gmail.com","threadId":"56329","inReplyTo":"20210828030839.2989-4-tbperrotta@gmail.com","subject":"Re: [PATCH v3 3/3] send-email docs: add format-patch options","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-08-28T05:22:52Z","receivedAt":"2021-08-28T05:23:00Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 28/08/21 10.08, Thiago Perrotta wrote:\n> @@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n>   Patches can be specified as files, directories (which will send all\n>   files in the directory), or directly as a revision list.  In the\n>   last case, any format accepted by linkgit:git-format-patch[1] can\n> -be passed to git send-email.\n> +be passed to git send-email, and options understood by\n> +linkgit:git-format-patch[1] can be passed.\n\nBetter say \"..., as well as options understood by \nlinkgit:git-format-patch[1].\".\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"434008","messageId":"CAPUEsphYPqaZueCcZ-SJx9HabuesSyx8MJOhkEjAJjWGGrzxEw@mail.gmail.com","threadId":"56329","inReplyTo":"20210828030839.2989-3-tbperrotta@gmail.com","subject":"Re: [PATCH v3 2/3] send-email: move bash completions to core script","fromName":"Carlo Arenas","fromEmail":"carenas@gmail.com","sentAt":"2021-08-28T05:25:47Z","receivedAt":"2021-08-28T05:26:01Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Fri, Aug 27, 2021 at 8:10 PM Thiago Perrotta <tbperrotta@gmail.com> wrote:\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 4bdd27ddc8..1b73a4dcc0 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2359,16 +2359,7 @@ _git_send_email ()\n>                 return\n>                 ;;\n>         --*)\n> -               __gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n> -                       --compose --confirm= --dry-run --envelope-sender\n> -                       --from --identity\n> -                       --in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n> -                       --no-suppress-from --no-thread --quiet --reply-to\n> -                       --signed-off-by-cc --smtp-pass --smtp-server\n> -                       --smtp-server-port --smtp-encryption= --smtp-user\n> -                       --subject --suppress-cc= --suppress-from --thread --to\n> -                       --validate --no-validate\n> -                       $__git_format_patch_extra_options\"\n> +               __gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n\n13374987dd (completion: use __gitcomp_builtin for format-patch,\n2018-11-03) mentions\nthat keeping these in the shell script help with caching and that\nmoving them to perl would\nbe better done so that the list can be maintained programmatically\ninstead of manually.\n\nFWIW it is missing several options (ex: batch-size, {cc,to}-cover,\n{8bit,compose}-encoding)\n\nCarlo\n"},{"id":"434811","messageId":"20210907001609.156105-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"CAPUEsphYPqaZueCcZ-SJx9HabuesSyx8MJOhkEjAJjWGGrzxEw@mail.gmail.com","subject":"[PATCH] send-email: move bash completions to core script","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-07T00:16:09Z","receivedAt":"2021-09-07T00:16:53Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well.\n\nAdd a completion test for \"send-email --validate\", a send-email option.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\nHi Carlos,\n\nGood catch. Initially I had only moved the options from the script.\n\nI am working on another patch (attached) that exhaustively adds all\noptions. At this time, it's still manual, I agree that generating the\nflags programatically would be even better, but I didn't want to\ncomplicate this series too much.\n\nLet me know how you would like me to proceed here, I see 3 options:\n\n1. drop the second part of the patch (v3 2/3) completely, only keep the\n  other ones (1/3 and 3/3), which just adds the newline and touches the\n  man page - leave automated flags for another series\n2. send v4 with the attached - which exhaustively adds all send-email\noptions to the perl script, while removing the completions from the bash\ncompletion script\n3. send v4 with the attached and do not touch the current bash\ncompletion script (keeping caching as is)\n\n contrib/completion/git-completion.bash | 11 +----\n git-send-email.perl                    | 62 ++++++++++++++++++++++++++\n t/t9902-completion.sh                  |  3 ++\n 3 files changed, 66 insertions(+), 10 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex d1731c1755..7139384f7a 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,6 +114,68 @@ sub usage {\n }\n \n sub completion_helper {\n+    my @send_email_flags = qw/\n+    --8bit-encoding\n+    --annotate\n+    --batch-size\n+    --bcc\n+    --cc\n+    --cc-cmd\n+    --cc-cover\n+    --chain-reply-to\n+    --compose\n+    --compose-encoding\n+    --confirm\n+    --dry-run\n+    --dump-aliases\n+    --envelope-sender\n+    --force\n+    --format-patch\n+    --from\n+    --identity\n+    --in-reply-to\n+    --no-annotate\n+    --no-bcc\n+    --no-cc\n+    --no-cc-cover\n+    --no-chain-reply-to\n+    --no-format-patch\n+    --no-signed-off-by-cc\n+    --no-smtp-auth\n+    --no-suppress-from\n+    --no-thread\n+    --no-to\n+    --no-to-cover\n+    --no-validate\n+    --no-xmailer\n+    --quiet\n+    --relogin-delay\n+    --reply-to\n+    --sendmail-cmd\n+    --signed-off-by-cc\n+    --smtp-auth\n+    --smtp-debug\n+    --smtp-domain\n+    --smtp-encryption\n+    --smtp-pass\n+    --smtp-server\n+    --smtp-server-option\n+    --smtp-server-port\n+    --smtp-ssl\n+    --smtp-ssl-cert-path\n+    --smtp-user\n+    --subject\n+    --suppress-cc\n+    --suppress-from\n+    --thread\n+    --to\n+    --to-cmd\n+    --to-cover\n+    --transfer-encoding\n+    --validate\n+    --xmailer\n+    /;\n+    print \"@send_email_flags\";\n     print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"434813","messageId":"CAPUEsphn15H9HbHKHRk+GFMvjq5O=8NL0Vo4L8NoUwiRrQUJJA@mail.gmail.com","threadId":"56329","inReplyTo":"20210907001609.156105-1-tbperrotta@gmail.com","subject":"Re: [PATCH] send-email: move bash completions to core script","fromName":"Carlo Arenas","fromEmail":"carenas@gmail.com","sentAt":"2021-09-07T01:28:21Z","receivedAt":"2021-09-07T01:28:35Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Mon, Sep 6, 2021 at 5:16 PM Thiago Perrotta <tbperrotta@gmail.com> wrote:\n>\n> Let me know how you would like me to proceed here, I see 3 options:\n>\n> 1. drop the second part of the patch (v3 2/3) completely, only keep the\n>   other ones (1/3 and 3/3), which just adds the newline and touches the\n>   man page - leave automated flags for another series\n\nThis seems like the most straightforward and quick way out, but I was\nreally hoping you could take the time to instead do the move to perl\nwith the programmatic option, which is long overdue anyway.\n\nIf you go with 1, then 2 and an improved 4 could be done as a follow up\n\nCarlo\n"},{"id":"436625","messageId":"20210921155152.4215-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"CAPUEsphn15H9HbHKHRk+GFMvjq5O=8NL0Vo4L8NoUwiRrQUJJA@mail.gmail.com","subject":"[PATCH v4 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-21T15:51:49Z","receivedAt":"2021-09-21T15:52:28Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email\" completion (bash, zsh) is inconsistent, its flags are\nsplit into both git-completion.bash and git-send-email.perl, and it only\nemits format-patch flags.\n\nMake shell completion uniform, centralizing completion\noptions on git-send-email.perl.\n\nMake \"git send-email --git-completion-helper\" properly emit send-email\nspecific options.\n\nAdditionally, update git-send-email(1) man page to explicitly\nmention format-patch options.\n\nDifferences from V3:\n\n- Incorporate Carlo Arenas' code suggestions, adding all flags\n  exhaustively.\n- Incorporate Bagas Sanjaya's suggestion.\n\nDifferences from V2:\n\n- Incorporate Junio's code suggestions.\n- Follow proper conventions for git commit messages.\n\nCarlo suggests to generate the flags programatically from the perl\nscript. I am looking into this and already have a proof-of-concept\nworking and plan to submit it as a separate patch series. I would like\nto get this series checked in first though.\n\nThiago Perrotta (3):\n  send-email: terminate --git-completion-helper with LF\n  send-email: move bash completions to core script\n  send-email docs: add format-patch options\n\n Documentation/git-send-email.txt       |  6 ++-\n contrib/completion/git-completion.bash | 11 +----\n git-send-email.perl                    | 64 +++++++++++++++++++++++++-\n t/t9902-completion.sh                  |  3 ++\n 4 files changed, 71 insertions(+), 13 deletions(-)\n\n-- \n2.33.0\n\n"},{"id":"436626","messageId":"20210921155152.4215-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"20210921155152.4215-1-tbperrotta@gmail.com","subject":"[PATCH v4 1/3] send-email: terminate --git-completion-helper with LF","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-21T15:51:50Z","receivedAt":"2021-09-21T15:52:40Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Unlike other Git subcommands, \"git send-email\" leaves its output an\nincomplete line when \"--git-completion-helper\" is asked.  Be consistent\nby terminating the message with LF here.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n git-send-email.perl | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..d1731c1755 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,7 +114,7 @@ sub usage {\n }\n \n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n+    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\n \n-- \n2.33.0\n\n"},{"id":"436627","messageId":"20210921155152.4215-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"20210921155152.4215-1-tbperrotta@gmail.com","subject":"[PATCH v4 2/3] send-email: move bash completions to core script","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-21T15:51:51Z","receivedAt":"2021-09-21T15:52:43Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well.\n\nAdd a completion test for \"send-email --validate\", a send-email option.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +----\n git-send-email.perl                    | 62 ++++++++++++++++++++++++++\n t/t9902-completion.sh                  |  3 ++\n 3 files changed, 66 insertions(+), 10 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex d1731c1755..7139384f7a 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,6 +114,68 @@ sub usage {\n }\n \n sub completion_helper {\n+    my @send_email_flags = qw/\n+    --8bit-encoding\n+    --annotate\n+    --batch-size\n+    --bcc\n+    --cc\n+    --cc-cmd\n+    --cc-cover\n+    --chain-reply-to\n+    --compose\n+    --compose-encoding\n+    --confirm\n+    --dry-run\n+    --dump-aliases\n+    --envelope-sender\n+    --force\n+    --format-patch\n+    --from\n+    --identity\n+    --in-reply-to\n+    --no-annotate\n+    --no-bcc\n+    --no-cc\n+    --no-cc-cover\n+    --no-chain-reply-to\n+    --no-format-patch\n+    --no-signed-off-by-cc\n+    --no-smtp-auth\n+    --no-suppress-from\n+    --no-thread\n+    --no-to\n+    --no-to-cover\n+    --no-validate\n+    --no-xmailer\n+    --quiet\n+    --relogin-delay\n+    --reply-to\n+    --sendmail-cmd\n+    --signed-off-by-cc\n+    --smtp-auth\n+    --smtp-debug\n+    --smtp-domain\n+    --smtp-encryption\n+    --smtp-pass\n+    --smtp-server\n+    --smtp-server-option\n+    --smtp-server-port\n+    --smtp-ssl\n+    --smtp-ssl-cert-path\n+    --smtp-user\n+    --subject\n+    --suppress-cc\n+    --suppress-from\n+    --thread\n+    --to\n+    --to-cmd\n+    --to-cover\n+    --transfer-encoding\n+    --validate\n+    --xmailer\n+    /;\n+    print \"@send_email_flags\";\n     print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"436628","messageId":"20210921155152.4215-4-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"20210921155152.4215-1-tbperrotta@gmail.com","subject":"[PATCH v4 3/3] send-email docs: add format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-21T15:51:52Z","receivedAt":"2021-09-21T15:52:57Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"git-send-email(1) does not mention that \"git format-patch\" options are\naccepted. Augment SYNOPSIS and DESCRIPTION to mention it.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..41cd8cb424 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, as well as options understood by\n+linkgit:git-format-patch[1].\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\n-- \n2.33.0\n\n"},{"id":"436856","messageId":"87zgs34ccx.fsf@evledraar.gmail.com","threadId":"56329","inReplyTo":"20210921155152.4215-1-tbperrotta@gmail.com","subject":"Re: [PATCH v4 0/3] send-email: shell completion improvements","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-23T14:02:50Z","receivedAt":"2021-09-23T14:04:34Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Sep 21 2021, Thiago Perrotta wrote:\n\nNote: using --in-reply-to to the previous version in \"git format-patch\"\nhelps keep track of the context.\n\n> Carlo suggests to generate the flags programatically from the perl\n> script. I am looking into this and already have a proof-of-concept\n> working and plan to submit it as a separate patch series. I would like\n> to get this series checked in first though.\n\nIsn't this just:\n\nmy @params = <getopts list>;\nGetOptions(@params);\n\nAnd then doing some light parsing/slicinng of the @params list to get\nthe keys you've duplicated here?\n\nI for one would much prefer to see that go in right away than the churn\nof first hardcoding these, then removing the hardcoding etc.\n"},{"id":"436916","messageId":"20210924024606.20542-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87zgs34ccx.fsf@evledraar.gmail.com","subject":"[PATCH v5 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-24T02:46:03Z","receivedAt":"2021-09-24T02:47:05Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email\" completion (bash, zsh) is inconsistent, its flags are\nsplit into both git-completion.bash and git-send-email.perl, and it only\nemits format-patch flags.\n\nMake shell completion uniform, centralizing completion\noptions on git-send-email.perl.\n\nMake \"git send-email --git-completion-helper\" properly emit send-email\nspecific options, generating them programmatically.\n\nAdditionally, update git-send-email(1) man page to explicitly\nmention format-patch options.\n\n\nDifferences from V4:\n\nIncorporate Carlo Arenas' and Ævar Arnfjörð Bjarmason's suggestion to\nprogramatically generate the flags.\n\nI tried to be concise whilst preserving readability, hopefully it's\nstraightforward to parse the current implementation.\n\n\nReviewers of previous versions:\n\n- Bagas Sanjaya\n- Carlo Arenas\n- Junio Hamano\n- Ævar Arnfjörð Bjarmason\n\n\nÆvar wrote earlier:\n\n> Note: using --in-reply-to to the previous version in \"git format-patch\"\n> helps keep track of the context.\n\nThanks for the heads up, I am slowly getting used to this email\nworkflow, this is my first contribution. Hopefully I got it right this\ntime.\n\n> Isn't this just:\n\n> my @params = <getopts list>;\n> GetOptions(@params);\n\nLet me know if the regex approach I went with is OK. You seem to have\nsuggested me to do something with the `GetOptions` module, but I'm\nafraid I only know the basics of Perl.\n\nI tried to do something like `GetOptions($USAGE)` but it didn't quite\nwork (clearly I have no idea how to do that :P). If you have something\nspecific in mind, I'd appreciate if you could send a small patch back\nthat I can incorporate. Otherwise, either way, the current regex\napproach isn't too horrible and seems to be reasonably reliable.\n\nThiago Perrotta (3):\n  send-email: terminate --git-completion-helper with LF\n  send-email: programmatically generate bash completions\n  send-email docs: add format-patch options\n\n Documentation/git-send-email.txt       |  6 ++++--\n contrib/completion/git-completion.bash | 11 +----------\n git-send-email.perl                    | 21 +++++++++++++++++----\n t/t9902-completion.sh                  |  3 +++\n 4 files changed, 25 insertions(+), 16 deletions(-)\n\n-- \n2.33.0\n\n"},{"id":"436917","messageId":"20210924024606.20542-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87zgs34ccx.fsf@evledraar.gmail.com","subject":"[PATCH v5 1/3] send-email: terminate --git-completion-helper with LF","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-24T02:46:04Z","receivedAt":"2021-09-24T02:47:07Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Unlike other Git subcommands, \"git send-email\" leaves its output an\nincomplete line when \"--git-completion-helper\" is asked.  Be consistent\nby terminating the message with LF here.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n git-send-email.perl | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..d1731c1755 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,7 +114,7 @@ sub usage {\n }\n \n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n+    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\n \n-- \n2.33.0\n\n"},{"id":"436918","messageId":"20210924024606.20542-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87zgs34ccx.fsf@evledraar.gmail.com","subject":"[PATCH v5 2/3] send-email: programmatically generate bash completions","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-24T02:46:05Z","receivedAt":"2021-09-24T02:47:10Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well, generating them\nprogrammatically from the usage.\n\nIntroduce a uniq subroutine, otherwise --dump-aliases would show\nup twice in the flags.\n\nAdd a completion test for \"send-email --validate\", a send-email option.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +----------\n git-send-email.perl                    | 21 +++++++++++++++++----\n t/t9902-completion.sh                  |  3 +++\n 3 files changed, 21 insertions(+), 14 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex d1731c1755..3d4836aa48 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -38,9 +38,8 @@ sub readline {\n package main;\n \n \n-sub usage {\n-\tprint <<EOT;\n-git send-email [options] <file | directory | rev-list options >\n+my $USAGE = <<EOT\n+git send-email [options] <file | directory | rev-list options>\n git send-email --dump-aliases\n \n   Composing:\n@@ -110,11 +109,25 @@ sub usage {\n     --dump-aliases                 * Dump configured aliases and exit.\n \n EOT\n+;\n+\n+sub usage {\n+\tprint $USAGE;\n \texit(1);\n }\n \n+sub uniq {\n+    my %seen;\n+    grep !$seen{$_}++, @_;\n+}\n+\n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n+    my @no_only_flags;\n+    push @no_only_flags, \"--$1\", \"--no-$1\" while ($USAGE =~ /--\\[no-](\\w+(?:-\\w+)*)/g);\n+\n+    my @all_flags = uniq($USAGE =~ /--\\w+(?:-\\w+)*/g, @no_only_flags);\n+\n+    print \"@all_flags\", Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"436919","messageId":"20210924024606.20542-4-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87zgs34ccx.fsf@evledraar.gmail.com","subject":"[PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-24T02:46:06Z","receivedAt":"2021-09-24T02:47:11Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"git-send-email(1) does not mention that \"git format-patch\" options are\naccepted. Augment SYNOPSIS and DESCRIPTION to mention it.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..41cd8cb424 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, as well as options understood by\n+linkgit:git-format-patch[1].\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\n-- \n2.33.0\n\n"},{"id":"436921","messageId":"9a60226c-7a35-0486-a687-31f7691e7551@gmail.com","threadId":"56329","inReplyTo":"20210924024606.20542-4-tbperrotta@gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-09-24T04:36:32Z","receivedAt":"2021-09-24T04:36:38Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 24/09/21 09.46, Thiago Perrotta wrote:\n>   SYNOPSIS\n>   --------\n>   [verse]\n> -'git send-email' [<options>] <file|directory|rev-list options>...\n> +'git send-email' [<options>] <file|directory>...\n> +'git send-email' [<options>] <format-patch options>\n>   'git send-email' --dump-aliases\n\nIs <format-patch options> optional? If so, we can say [<format-patch \noptions>].\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"436922","messageId":"CAPUEspjxYy4GOABXkzRza-wmKnZAdq-v=OP-9+-wfV2PCnDGwQ@mail.gmail.com","threadId":"56329","inReplyTo":"9a60226c-7a35-0486-a687-31f7691e7551@gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Carlo Arenas","fromEmail":"carenas@gmail.com","sentAt":"2021-09-24T04:53:54Z","receivedAt":"2021-09-24T04:54:09Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Thu, Sep 23, 2021 at 9:36 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n>\n> On 24/09/21 09.46, Thiago Perrotta wrote:\n> >   SYNOPSIS\n> >   --------\n> >   [verse]\n> > -'git send-email' [<options>] <file|directory|rev-list options>...\n> > +'git send-email' [<options>] <file|directory>...\n> > +'git send-email' [<options>] <format-patch options>\n> >   'git send-email' --dump-aliases\n>\n> Is <format-patch options> optional? If so, we can say [<format-patch\n> options>].\n\nno; as Junio explained [1] this omission is intentional while the\nrev-list options that\ngot cut to make space are not and are more relevant.\n\nIMHO leaving [<options>] to imply ALL options (that also include diff\noptions, for example) is better\n\nCarlo\n\n[1] https://lore.kernel.org/git/xmqqh7fjuaar.fsf@gitster.g/\n"},{"id":"436925","messageId":"4c415fd4-a74e-5eb0-061e-39185be623ca@gmail.com","threadId":"56329","inReplyTo":"CAPUEspjxYy4GOABXkzRza-wmKnZAdq-v=OP-9+-wfV2PCnDGwQ@mail.gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-09-24T06:19:03Z","receivedAt":"2021-09-24T06:21:30Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 24/09/21 11.53, Carlo Arenas wrote:\n> no; as Junio explained [1] this omission is intentional while the\n> rev-list options that\n> got cut to make space are not and are more relevant.\n> \n> IMHO leaving [<options>] to imply ALL options (that also include diff\n> options, for example) is better\n\nQuoting what you linked:\n\n> The program works in two majorly different modes.  It either takes\n> \n>  * message files that are already proof-read and copy-edited from\n>    the filesystem and sends them out, or \n> \n>  * format-patch options to generate message files out of the commits\n>    and send them out without any proofreading.\n\nI think we need to again modify SYNOPSIS and DESCRIPTIONS to highlight \nabove fact:\n\n---- 8> ----\ndiff --git a/Documentation/git-send-email.txt \nb/Documentation/git-send-email.txt\nindex 3db4eab4ba..6002ca1a02 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,17 +9,19 @@ git-send-email - Send a collection of patches as emails\n  SYNOPSIS\n  --------\n  [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <revision list>...\n  'git send-email' --dump-aliases\n\n\n  DESCRIPTION\n  -----------\n-Takes the patches given on the command line and emails them out.\n-Patches can be specified as files, directories (which will send all\n-files in the directory), or directly as a revision list.  In the\n-last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+In the first form, take the patches in <file> or <directory> and\n+emails them out. In the second form, generate patches from specified\n+<revision list> (it can be revision range or explicit list of\n+revisions from linkgit:git-rev-list[1]), then emails them out.\n+<options> can also include options understood by\n+linkgit:git-format-patch[1] if the second form is specified.\n\n  The header of the email is configurable via command-line options.  If not\n  specified on the command line, the user will be prompted with a ReadLine\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"436933","messageId":"CAPUEspg23UqzrVSFb9KYY9k0bcp2wo4kfNbjE_ma6j4fM1=gNA@mail.gmail.com","threadId":"56329","inReplyTo":"4c415fd4-a74e-5eb0-061e-39185be623ca@gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Carlo Arenas","fromEmail":"carenas@gmail.com","sentAt":"2021-09-24T06:56:42Z","receivedAt":"2021-09-24T06:56:57Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Thu, Sep 23, 2021 at 11:19 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n>\n> On 24/09/21 11.53, Carlo Arenas wrote:\n> > no; as Junio explained [1] this omission is intentional while the\n> > rev-list options that\n> > got cut to make space are not and are more relevant.\n> >\n> > IMHO leaving [<options>] to imply ALL options (that also include diff\n> > options, for example) is better\n>\n> Quoting what you linked:\n>\n> > The program works in two majorly different modes.  It either takes\n> >\n> >  * message files that are already proof-read and copy-edited from\n> >    the filesystem and sends them out, or\n> >\n> >  * format-patch options to generate message files out of the commits\n> >    and send them out without any proofreading.\n>\n> I think we need to again modify SYNOPSIS and DESCRIPTIONS to highlight\n> above fact:\n\nBagas,\n\nThis is much better; can you SOB and help Thiago import it into his\ntree so it can be included in the next reroll?\n\nThiago,\n\nLet's wait a little while to collect more feedback on patch2 before\nsending it, though\n\nCarlo\n"},{"id":"436951","messageId":"xmqqzgs2vvim.fsf@gitster.g","threadId":"56329","inReplyTo":"CAPUEspjxYy4GOABXkzRza-wmKnZAdq-v=OP-9+-wfV2PCnDGwQ@mail.gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-24T15:33:05Z","receivedAt":"2021-09-24T15:33:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carlo Arenas <carenas@gmail.com> writes:\n\n> On Thu, Sep 23, 2021 at 9:36 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n>>\n>> On 24/09/21 09.46, Thiago Perrotta wrote:\n>> >   SYNOPSIS\n>> >   --------\n>> >   [verse]\n>> > -'git send-email' [<options>] <file|directory|rev-list options>...\n>> > +'git send-email' [<options>] <file|directory>...\n>> > +'git send-email' [<options>] <format-patch options>\n>> >   'git send-email' --dump-aliases\n>>\n>> Is <format-patch options> optional? If so, we can say [<format-patch\n>> options>].\n>\n> no; as Junio explained [1] this omission is intentional while the\n> rev-list options that\n> got cut to make space are not and are more relevant.\n>\n> IMHO leaving [<options>] to imply ALL options (that also include diff\n> options, for example) is better\n\nCould you claify this idea a bit more?  Do you mean that the second form\ncan just be:\n\n\tgit send-email <format-patch options>\n\nThat will exclude the send-email specific ones (like\n\"--in-reply-to=<msg>\"), so it may not be a great idea.\n\nOr do you mean\n\n\tgit send-email <options>\n\nand have the <options> placeholder to stand for both send-email\noptions and options meant for format-patch?\n\nThanks.\n"},{"id":"436983","messageId":"CAPUEspiSh91a8MvhqhKm=DAn5_u-HoRBuL6-gBRMUtSshqpf=g@mail.gmail.com","threadId":"56329","inReplyTo":"xmqqzgs2vvim.fsf@gitster.g","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Carlo Arenas","fromEmail":"carenas@gmail.com","sentAt":"2021-09-24T17:34:19Z","receivedAt":"2021-09-24T17:34:53Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Fri, Sep 24, 2021 at 8:33 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Carlo Arenas <carenas@gmail.com> writes:\n>\n> > On Thu, Sep 23, 2021 at 9:36 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n> >>\n> >> On 24/09/21 09.46, Thiago Perrotta wrote:\n> >> >   SYNOPSIS\n> >> >   --------\n> >> >   [verse]\n> >> > -'git send-email' [<options>] <file|directory|rev-list options>...\n> >> > +'git send-email' [<options>] <file|directory>...\n> >> > +'git send-email' [<options>] <format-patch options>\n> >> >   'git send-email' --dump-aliases\n> >>\n> >> Is <format-patch options> optional? If so, we can say [<format-patch\n> >> options>].\n> >\n> > no; as Junio explained [1] this omission is intentional while the\n> > rev-list options that\n> > got cut to make space are not and are more relevant.\n> >\n> > IMHO leaving [<options>] to imply ALL options (that also include diff\n> > options, for example) is better\n>\n> Could you claify this idea a bit more?  Do you mean that the second form\n> can just be:\n>\n>         git send-email <format-patch options>\n>\n> That will exclude the send-email specific ones (like\n> \"--in-reply-to=<msg>\"), so it may not be a great idea.\n>\n> Or do you mean\n>\n>         git send-email <options>\n>\n> and have the <options> placeholder to stand for both send-email\n> options and options meant for format-patch?\n\nthe later AND including a non optional part that explains that you\nneed to indicate some sort of revision (which hopefully will also\nimply to users that all the related options are also expected),\nbut also won't be specific, not to promote the use of this type of\nmode or the need to update it further to include the whole universe of\noptions through format-patch (ex: log and diff)\n\nGranted, I could have worded it better, but Bagas' proposal[1] (based\non this discussion) does and clarifies both; why this is not optional\nin a way that is less confusing than what Thiago posted and is IMHO[2]\na good candidate for replacing this patch in the series\n\nCarlo\n\n[1] https://lore.kernel.org/git/20210924121352.42138-1-bagasdotme@gmail.com\n[2] https://lore.kernel.org/git/CAPUEsphn15H9HbHKHRk+GFMvjq5O=8NL0Vo4L8NoUwiRrQUJJA@mail.gmail.com/T/#m6f0600b597fbe0b59aa767603a7f1d24d60e8fe9\n"},{"id":"437027","messageId":"xmqqo88hspvv.fsf@gitster.g","threadId":"56329","inReplyTo":"CAPUEspiSh91a8MvhqhKm=DAn5_u-HoRBuL6-gBRMUtSshqpf=g@mail.gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-24T20:03:00Z","receivedAt":"2021-09-24T20:03:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carlo Arenas <carenas@gmail.com> writes:\n\n>> Or do you mean\n>>\n>>         git send-email <options>\n>>\n>> and have the <options> placeholder to stand for both send-email\n>> options and options meant for format-patch?\n>\n> the later AND including a non optional part that explains that you\n> need to indicate some sort of revision ...\n\nAh, thanks for explanation.\n\n    git format-patch -2\n\nwould be options-only way to \"indicate some sort of revision\", so\nperhaps \n\n    . git send-email <send-email options> files|directory\n    . git send-email <send-email options> <format-patch options>\n\n(where \"options\" is used to refer to both --options and arguments)\nwould illustrate the differences better?\n"},{"id":"437029","messageId":"87bl4h3fgv.fsf@evledraar.gmail.com","threadId":"56329","inReplyTo":"20210924024606.20542-1-tbperrotta@gmail.com","subject":"Re: [PATCH v5 0/3] send-email: shell completion improvements","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-24T20:02:25Z","receivedAt":"2021-09-24T20:07:18Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Thu, Sep 23 2021, Thiago Perrotta wrote:\n\n> Thanks for the heads up, I am slowly getting used to this email\n> workflow, this is my first contribution. Hopefully I got it right this\n> time.\n>\n>> Isn't this just:\n>\n>> my @params = <getopts list>;\n>> GetOptions(@params);\n>\n> Let me know if the regex approach I went with is OK. You seem to have\n> suggested me to do something with the `GetOptions` module, but I'm\n> afraid I only know the basics of Perl.\n>\n> I tried to do something like `GetOptions($USAGE)` but it didn't quite\n> work (clearly I have no idea how to do that :P). If you have something\n> specific in mind, I'd appreciate if you could send a small patch back\n> that I can incorporate. Otherwise, either way, the current regex\n> approach isn't too horrible and seems to be reasonably reliable.\n\nI meant something like the below patch, feel free to incorporate it if\nyou'd like with my signed-off-by, i.e. there's no reason to parse the\nusage message, or hardcode another set of options, we've got it right\nthere as structured program data being fed to the GetOptions() function.\n\nAll we need to do is to assign that to a hash, and use it both for\nemitting the help and to call GetOptions().\n\nWhat I have doesn't *quite* work, i.e. the --git-completion-helper\nexpects \"--foo=\" I think for things that are \"foo=s\" in perl, so the\nregex needs adjusting, but that should be an easy addition on top.\n\n-- >8 --\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 5262d88ee32..221115fbbdd 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,8 +114,18 @@ sub usage {\n }\n \n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n-    exit(0);\n+\tmy ($options) = @_;\n+\n+\tmy @gse_options = sort map {\n+\t\t\"--$_\"\n+\t} map {\n+\t\ts/(?:[:=][si]|!)$//;\n+\t\tsplit /\\|/, $_;\n+\t} keys %$options;\n+\tmy @fpa_options = Git::command('format-patch', '--git-completion-helper');\n+\tmy @options = sort @gse_options, @fpa_options;\n+\tprint \"@options\\n\";\n+\texit(0);\n }\n \n # most mail servers generate the Date: header, but not all...\n@@ -449,7 +459,7 @@ sub config_regexp {\n usage() unless $rc;\n die __(\"--dump-aliases incompatible with other options\\n\")\n     if !$help and $dump_aliases and @ARGV;\n-$rc = GetOptions(\n+my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n                     \"in-reply-to=s\" => \\$initial_in_reply_to,\n \t\t    \"reply-to=s\" => \\$reply_to,\n@@ -508,7 +518,8 @@ sub config_regexp {\n \t\t    \"batch-size=i\" => \\$batch_size,\n \t\t    \"relogin-delay=i\" => \\$relogin_delay,\n \t\t    \"git-completion-helper\" => \\$git_completion_helper,\n-\t );\n+);\n+$rc = GetOptions(%options);\n \n # Munge any \"either config or getopt, not both\" variables\n my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);\n@@ -516,7 +527,7 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-completion_helper() if $git_completion_helper;\n+completion_helper(\\%options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n }\n"},{"id":"437064","messageId":"d9114e0a-cb6e-1791-51f8-6e57f313e8d5@gmail.com","threadId":"56329","inReplyTo":"xmqqo88hspvv.fsf@gitster.g","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-09-25T03:03:01Z","receivedAt":"2021-09-25T03:03:08Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 25/09/21 03.03, Junio C Hamano wrote:\n> Ah, thanks for explanation.\n> \n>      git format-patch -2\n> \n> would be options-only way to \"indicate some sort of revision\", so\n> perhaps\n> \n>      . git send-email <send-email options> files|directory\n>      . git send-email <send-email options> <format-patch options>\n> \n> (where \"options\" is used to refer to both --options and arguments)\n> would illustrate the differences better?\n> \n\nBut we can also directly specify revision range (commonly <common \nancestor>..HEAD or HEAD ^<common ancestor>).\n\nSo for the second form, the syntax will be:\n\n   git send-email <send-email options> <format-patch options> <revision \nrange>\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"437066","messageId":"xmqq5yups3g8.fsf@gitster.g","threadId":"56329","inReplyTo":"d9114e0a-cb6e-1791-51f8-6e57f313e8d5@gmail.com","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-25T04:07:35Z","receivedAt":"2021-09-25T04:07:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bagas Sanjaya <bagasdotme@gmail.com> writes:\n\n> On 25/09/21 03.03, Junio C Hamano wrote:\n>> Ah, thanks for explanation.\n>>      git format-patch -2\n>> would be options-only way to \"indicate some sort of revision\", so\n>> perhaps\n>>      . git send-email <send-email options> files|directory\n>>      . git send-email <send-email options> <format-patch options>\n>> (where \"options\" is used to refer to both --options and arguments)\n>> would illustrate the differences better?\n>> \n>\n> But we can also directly specify revision range (commonly <common\n> ancestor>..HEAD or HEAD ^<common ancestor>).\n\nThat is exactly why I have the parenthetical definition of what\n\"options\" mean in my explanation.  \n\n\tgit format-patch -2\n\tgit format-patch master\n\tgit format-patch master..HEAD\n\nEverything after \"git format-patch\", i.e. -2, master, master..HEAD,\nare usable, and there isn't much point in singling out revision\nranges.  FWIW, I think you can even give \"-- <pathspec>\" at the end,\nwhich are not options or revision ranges.\n"},{"id":"437068","messageId":"YU6+BWC+xvGJP3b0@carlos-mbp.lan","threadId":"56329","inReplyTo":"xmqq5yups3g8.fsf@gitster.g","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Carlo Marcelo Arenas Belón","fromEmail":"carenas@gmail.com","sentAt":"2021-09-25T06:13:25Z","receivedAt":"2021-09-25T06:13:32Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Fri, Sep 24, 2021 at 09:07:35PM -0700, Junio C Hamano wrote:\n> Bagas Sanjaya <bagasdotme@gmail.com> writes:\n> > On 25/09/21 03.03, Junio C Hamano wrote:\n> >> Ah, thanks for explanation.\n> >>      git format-patch -2\n> >> would be options-only way to \"indicate some sort of revision\", so\n> >> perhaps\n> >>      . git send-email <send-email options> files|directory\n> >>      . git send-email <send-email options> <format-patch options>\n> >> (where \"options\" is used to refer to both --options and arguments)\n> >> would illustrate the differences better?\n> >> \n> > But we can also directly specify revision range (commonly <common\n> > ancestor>..HEAD or HEAD ^<common ancestor>).\n> \n> That is exactly why I have the parenthetical definition of what\n> \"options\" mean in my explanation.  \n> \n> \tgit format-patch -2\n> \tgit format-patch master\n> \tgit format-patch master..HEAD\n> \n> Everything after \"git format-patch\", i.e. -2, master, master..HEAD,\n> are usable, and there isn't much point in singling out revision\n> ranges.  FWIW, I think you can even give \"-- <pathspec>\" at the end,\n> which are not options or revision ranges.\n\n<format-patch options> then it is; would the following be worth adding\nin top so the recursive reference can be followed?\n\nCarlo\n------ >8 ------\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex fe2f69d36e..806ff93259 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -30,7 +30,7 @@ SYNOPSIS\n \t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n \t\t   [--filename-max-length=<n>]\n \t\t   [--progress]\n-\t\t   [<common diff options>]\n+\t\t   [<common diff options>] [<rev-list options>]\n \t\t   [ <since> | <revision range> ]\n \n DESCRIPTION\n"},{"id":"437480","messageId":"xmqqpmsrcc4g.fsf@gitster.g","threadId":"56329","inReplyTo":"YU6+BWC+xvGJP3b0@carlos-mbp.lan","subject":"Re: [PATCH v5 3/3] send-email docs: add format-patch options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-29T21:20:31Z","receivedAt":"2021-09-29T21:20:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carlo Marcelo Arenas Belón <carenas@gmail.com> writes:\n\n>> Everything after \"git format-patch\", i.e. -2, master, master..HEAD,\n>> are usable, and there isn't much point in singling out revision\n>> ranges.  FWIW, I think you can even give \"-- <pathspec>\" at the end,\n>> which are not options or revision ranges.\n>\n> <format-patch options> then it is; would the following be worth adding\n> in top so the recursive reference can be followed?\n\nI am not sure what \"the recursive reference\" is an issue here, but\nI agree that we may want to improve upon <revision range> in the\npart you are touching, which currently we say:\n\n    There are two ways to specify which commits to operate on.\n\n    1. A single commit, <since>, specifies that the commits leading\n       to the tip of the current branch that are not in the history\n       that leads to the <since> to be output.\n\n    2. Generic <revision range> expression (see \"SPECIFYING\n       REVISIONS\" section in linkgit:gitrevisions[7]) means the\n       commits in the specified range.\n\n    The first rule takes precedence in the case of a single <commit>.  To\n    apply the second rule, i.e., format everything since the beginning of\n    history up until <commit>, use the `--root` option: `git format-patch\n    --root <commit>`.  If you want to format only <commit> itself, you\n    can do this with `git format-patch -1 <commit>`.\n\nWhat we refer to in the prose, e.g. \"--root\" and \" -1\", do not\nappear in the SYNOPSIS section.\n\n> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n> index fe2f69d36e..806ff93259 100644\n> --- a/Documentation/git-format-patch.txt\n> +++ b/Documentation/git-format-patch.txt\n> @@ -30,7 +30,7 @@ SYNOPSIS\n>  \t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n>  \t\t   [--filename-max-length=<n>]\n>  \t\t   [--progress]\n> -\t\t   [<common diff options>]\n> +\t\t   [<common diff options>] [<rev-list options>]\n>  \t\t   [ <since> | <revision range> ]\n\nI think the \"<rev-list options>\" you are adding here is to enhance\nwhat <revision range> in the original wants to convey.  In addition\nto things like @{u}..HEAD~2 (i.e. \"the branch is mostly good, but\nthe tip 2 commits are not yet ready so do not send them out\"), you\ncan do \"-2\" (i.e. \"the topmost 2 commits\"), which is not exactly\nwhat \"SPECIFYING REVISIONS\" part of gitrevisions(7) describes.\n\nSo, yes, I like the spirit of the change, but no, I do not think it\ngoes there; rather, it would replace or extend <revision range>, I\nwould think.\n\nIn addition, \"Generic <revision range> expression (see \"SPECIFYING\nREVISIONS\" section...) may need to be updated.  First, what we'd\nwant to refer to is not ways to specify revisions, but ways to\nspecify a range.  IOW, it should be referring to \"SPECIFYING RANGES\"\nsection instead.\n\nIf we replace <revision range> with your <rev-list options> in the\nSYNOPSIS, that will fall out as a natural consequence.  Perhaps, the\nsecond description and an earlier part of the explanation can be\nrewritten like so:\n\n    2. <rev-list options> that specifies a range of commits (see\n       linkgit:git-rev-list[1]) to be shown.\n\n    If you give a single <commit> and nothing else, it is taken as\n    the <since> of the first form.  If you want to format everything \n    since the beginning of history up until <commit>, use ...\n\nThanks.\n"},{"id":"437493","messageId":"CABOtWuqXS_kJk2md=kgg-ReaWtKermpUW_Dk_bc0pMXQL+xMeA@mail.gmail.com","threadId":"56329","inReplyTo":"87bl4h3fgv.fsf@evledraar.gmail.com","subject":"Re: [PATCH v5 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-09-30T03:10:23Z","receivedAt":"2021-09-30T03:10:41Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"On Fri, 24 Sept 2021 at 16:07, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:\n\n> I meant something like the below patch, feel free to incorporate it if\n> you'd like with my signed-off-by, i.e. there's no reason to parse the\n> usage message, or hardcode another set of options, we've got it right\n> there as structured program data being fed to the GetOptions() function.\n>\n> All we need to do is to assign that to a hash, and use it both for\n> emitting the help and to call GetOptions().\n>\n> What I have doesn't *quite* work, i.e. the --git-completion-helper\n> expects \"--foo=\" I think for things that are \"foo=s\" in perl, so the\n> regex needs adjusting, but that should be an easy addition on top.\n\n1)\nThanks Ævar, I get the gist of it. Your approach revealed a few issues\nwith the current usage string:\n\nThe following options exist in GetOptions but not in the usage string:\n\n--git-completion-helper\n--no-signed-off-cc\n--sender\n--signed-off-cc\n\nOut of these, I'd argue --git-completion-helper is intentionally omitted,\nhowever --sender and --signed-off-cc were overlooked.\n\n2)\nAlso, your patch misses --dump-aliases and --identity; that's because\nthey are in other GetOptions functions in the file.\n\nThe two obvious possibilities here are either (i) hard-code them directly, i.e.:\n\n-my @options = sort @gse_options, @fpa_options;\n+my @options = sort @gse_options, @fpa_options, \"--dump-aliases\", \"--sender\";\n\nor (ii) refactor the other two GetOptions like you did in your patch,\nso that `sub completion_helper` ends up receiving all three hashes\n(or maybe a single hash as a result of all three merged).\n\nAny preference between (i) or (ii)? I am leaning towards (i).\n\n3)\nFinally, I noticed that \"sort @gse_options, @fpa_options\" doesn't\nreally sort fpa_options.\n\nIf sorting is really intended, it would be better to modify the source\nof format-patch to\nemit sorted output.\n\nOtherwise, we may as well leave it untouched. AFAIK from a completion\nperspective it\nseems that it doesn't matter: both bash and zsh emit `git format-patch\n--<TAB>` sorted\ntoday, even though the output of `git format-patch\n--git-completion-helper` isn't sorted.\nThe only benefit of sorting I see would be to deduplicate ('uniq') flags.\n\nDo you agree with this rationale?\nEither way, let me know whether or not it's preferable to sort.\nI'll probably sort `send-email` options anyway just to deduplicate a\nfew flags such as --to-cover,\nbut `format-patch` could remain as is.\n\n\nI'll wait for replies before sending another patch (on top of your\noriginal one).\n"},{"id":"438114","messageId":"20211007033652.80793-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"CABOtWuqXS_kJk2md=kgg-ReaWtKermpUW_Dk_bc0pMXQL+xMeA@mail.gmail.com","subject":"[PATCH v6 1/3] send-email: terminate --git-completion-helper with LF","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-07T03:36:50Z","receivedAt":"2021-10-07T03:43:03Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Unlike other Git subcommands, \"git send-email\" leaves its output an\nincomplete line when \"--git-completion-helper\" is asked.  Be consistent\nby terminating the message with LF here.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n git-send-email.perl | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..d1731c1755 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,7 +114,7 @@ sub usage {\n }\n \n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n+    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\n \n-- \n2.33.0\n\n"},{"id":"438115","messageId":"20211007033652.80793-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"CABOtWuqXS_kJk2md=kgg-ReaWtKermpUW_Dk_bc0pMXQL+xMeA@mail.gmail.com","subject":"[PATCH v6 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-07T03:36:49Z","receivedAt":"2021-10-07T03:43:03Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Differences from V5:\n\nAddresses original Ævar's patch:\n\n- Effectively including all combined options, which ends up adding\n  --dump-aliases and --identity.\n\n- Manually excluded --h and --git-completion-helper. This is consistent\n  with \"git format-patch --git-completion-helper\".\n\n- Completely dropped sorting, because it seems the current git\n  subcommands don't really care about it (I verified \"git format-patch\"\n  and \"git apply\" only).\n\nAs mentioned earlier, the following issue remains open:\n\n> \"The following options exist in GetOptions but not in the current\n> usage string:\n>\n> --no-signed-off-cc --sender --signed-off-cc\"\n\nI wouldn't mind adding a fourth patch to this series that fixes the\ncurrent usage, just let me know which wording you'd like me to add.\n\nFinally, I will note that I haven't touched the third patch of this\nseries (git-send-email.txt) because it is not obvious to me which\ndirection we're taking. My understanding is that Junio prefers to leave\nthings as is, but let me know if I should change it to e.g. Carlos' or\nBagas' version.\n\nThiago Perrotta (3):\n  send-email: terminate --git-completion-helper with LF\n  send-email: programmatically generate bash completions\n  send-email docs: add format-patch options\n\n Documentation/git-send-email.txt       |  6 ++--\n contrib/completion/git-completion.bash | 11 +------\n git-send-email.perl                    | 43 +++++++++++++++++++-------\n t/t9902-completion.sh                  |  3 ++\n 4 files changed, 40 insertions(+), 23 deletions(-)\n\n-- \n2.33.0\n\n"},{"id":"438116","messageId":"20211007033652.80793-4-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"CABOtWuqXS_kJk2md=kgg-ReaWtKermpUW_Dk_bc0pMXQL+xMeA@mail.gmail.com","subject":"[PATCH v6 3/3] send-email docs: add format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-07T03:36:52Z","receivedAt":"2021-10-07T03:43:03Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"git-send-email(1) does not mention that \"git format-patch\" options are\naccepted. Augment SYNOPSIS and DESCRIPTION to mention it.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..41cd8cb424 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, as well as options understood by\n+linkgit:git-format-patch[1].\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\n-- \n2.33.0\n\n"},{"id":"438117","messageId":"20211007033652.80793-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"CABOtWuqXS_kJk2md=kgg-ReaWtKermpUW_Dk_bc0pMXQL+xMeA@mail.gmail.com","subject":"[PATCH v6 2/3] send-email: programmatically generate bash completions","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-07T03:36:51Z","receivedAt":"2021-10-07T03:43:03Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well, generating them\nprogrammatically from the usage.\n\nExtract flags from the three existing `GetOptions`.\n\nIntroduce a uniq subroutine, otherwise --cc-cover, --to-cover and other\nflags would show up twice.\n\nRemove two extraneous flags: --h and --git-completion-helper.\n\nAdd a completion test for \"send-email --validate\", a send-email flag.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\nBased-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +------\n git-send-email.perl                    | 43 +++++++++++++++++++-------\n t/t9902-completion.sh                  |  3 ++\n 3 files changed, 36 insertions(+), 21 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex d1731c1755..465e9867b9 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -40,7 +40,7 @@ package main;\n \n sub usage {\n \tprint <<EOT;\n-git send-email [options] <file | directory | rev-list options >\n+git send-email [options] <file | directory | rev-list options>\n git send-email --dump-aliases\n \n   Composing:\n@@ -113,8 +113,23 @@ sub usage {\n \texit(1);\n }\n \n+sub uniq {\n+    my %seen;\n+    grep !$seen{$_}++, @_;\n+}\n+\n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n+    my ($options) = @_;\n+    my @send_email_opts = map {\n+      \"--$_\"\n+    } map {\n+      s/(?:[:=][si]|!)$//;\n+      split /\\|/, $_;\n+    } keys %$options;\n+    my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');\n+    my @options = uniq @send_email_opts, @format_patch_opts;\n+    @options = grep !/--git-completion-helper|--h/, @options;\n+    print \"@options\\n\";\n     exit(0);\n }\n \n@@ -425,10 +440,11 @@ sub config_regexp {\n \tmy $key = \"sendemail.identity\";\n \t$identity = Git::config(@repo, $key) if exists $known_config_keys{$key};\n }\n-my $rc = GetOptions(\n-\t\"identity=s\" => \\$identity,\n-\t\"no-identity\" => \\$no_identity,\n+my %identity_options = (\n+  \"identity=s\" => \\$identity,\n+  \"no-identity\" => \\$no_identity,\n );\n+my $rc = GetOptions(%identity_options);\n usage() unless $rc;\n undef $identity if $no_identity;\n \n@@ -444,14 +460,17 @@ sub config_regexp {\n \n my $help;\n my $git_completion_helper;\n-$rc = GetOptions(\"h\" => \\$help,\n-                 \"dump-aliases\" => \\$dump_aliases);\n+my %dump_aliases_options = (\n+  \"h\" => \\$help,\n+  \"dump-aliases\" => \\$dump_aliases,\n+);\n+$rc = GetOptions(%dump_aliases_options);\n usage() unless $rc;\n die __(\"--dump-aliases incompatible with other options\\n\")\n     if !$help and $dump_aliases and @ARGV;\n-$rc = GetOptions(\n+my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n-                    \"in-reply-to=s\" => \\$initial_in_reply_to,\n+\t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n \t\t    \"reply-to=s\" => \\$reply_to,\n \t\t    \"subject=s\" => \\$initial_subject,\n \t\t    \"to=s\" => \\@getopt_to,\n@@ -508,7 +527,8 @@ sub config_regexp {\n \t\t    \"batch-size=i\" => \\$batch_size,\n \t\t    \"relogin-delay=i\" => \\$relogin_delay,\n \t\t    \"git-completion-helper\" => \\$git_completion_helper,\n-\t );\n+);\n+$rc = GetOptions(%options);\n \n # Munge any \"either config or getopt, not both\" variables\n my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);\n@@ -516,7 +536,8 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-completion_helper() if $git_completion_helper;\n+my %all_options = (%options, %dump_aliases_options, %identity_options);\n+completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"438392","messageId":"YWE41xTLhBFWqUFl@carlos-mbp.lan","threadId":"56329","inReplyTo":"20211007033652.80793-3-tbperrotta@gmail.com","subject":"Re: [PATCH v6 2/3] send-email: programmatically generate bash completions","fromName":"Carlo Marcelo Arenas Belón","fromEmail":"carenas@gmail.com","sentAt":"2021-10-09T06:38:15Z","receivedAt":"2021-10-09T06:38:24Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Wed, Oct 06, 2021 at 11:36:51PM -0400, Thiago Perrotta wrote:\n> diff --git a/git-send-email.perl b/git-send-email.perl\n> index d1731c1755..465e9867b9 100755\n> --- a/git-send-email.perl\n> +++ b/git-send-email.perl\n> @@ -40,7 +40,7 @@ package main;\n>  \n>  sub usage {\n>  \tprint <<EOT;\n> -git send-email [options] <file | directory | rev-list options >\n> +git send-email [options] <file | directory | rev-list options>\n\nthis change isn't really needed now that you are not using the usage()\nto get the options, and should probably go into an independent patch,\nor even better, as part of patch 3 so it is consistent.\n\n> @@ -113,8 +113,23 @@ sub usage {\n>  \texit(1);\n>  }\n>  \n> +sub uniq {\n> +    my %seen;\n> +    grep !$seen{$_}++, @_;\n> +}\n\nindentation in this file is a little odd, but will be better if you use the\nmost common one (tab), instead of your own version here (4 or 2 spaces) and\nin the rest of the code.\n\n>  sub completion_helper {\n> -    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n> +    my ($options) = @_;\n> +    my @send_email_opts = map {\n> +      \"--$_\"\n> +    } map {\n> +      s/(?:[:=][si]|!)$//;\n> +      split /\\|/, $_;\n> +    } keys %$options;\n> +    my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');\n> +    my @options = uniq @send_email_opts, @format_patch_opts;\n\nreusing \"options\" here makes this code more confusing than it needs to be\nmaybe something like :\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex a1338dd774..d47543bc0d 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -119,13 +119,13 @@ sub uniq {\n }\n\n sub completion_helper {\n-    my ($options) = @_;\n+    my ($original_opts) = @_;\n     my @send_email_opts = map {\n       \"--$_\"\n     } map {\n       s/(?:[:=][si]|!)$//;\n-      split /\\|/, $_;\n-    } keys %$options;\n+      split /\\|/;\n+    } keys %$original_opts;\n     my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');\n     my @options = uniq @send_email_opts, @format_patch_opts;\n     @options = grep !/--git-completion-helper|--h/, @options;\n\nmight help on top\n\nCarlo\n"},{"id":"438397","messageId":"20211009083133.4446-1-carenas@gmail.com","threadId":"56329","inReplyTo":"20211007033652.80793-4-tbperrotta@gmail.com","subject":"[RFC PATCH] Documentation: better document format-patch options in send-email","fromName":"Carlo Marcelo Arenas Belón","fromEmail":"carenas@gmail.com","sentAt":"2021-10-09T08:31:33Z","receivedAt":"2021-10-09T08:31:47Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"From: Thiago Perrotta <tbperrotta@gmail.com>\n\nThe use of <rev-list options> in format-patch is confusing because\nit is meant to represent instead a subset of options from format-patch\nand a revision range.\n\nChange the documentation from both git send-email and format-patch to\nbetter describe the list of options that are expected.\n\nSigned-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>\n---\nThis is an alternative to patch 3 which include most of the suggestions\nby Junio and Bagas, while also trying to minimize the change or the need\nto link to even more pages (which is why the suggestion[1] to link/use\nrev-list options was avoided).\n\nI expect it to be consistent and clear, but might had gotten some of the\nterminology wrong, and probably could have better grammar, so hoping for\nsome feedback to improve on that.\n\n[1] https://lore.kernel.org/git/CABOtWuqXS_kJk2md=kgg-ReaWtKermpUW_Dk_bc0pMXQL+xMeA@mail.gmail.com/T/#m396f2a42936ec9a3191658d4b40d9043dfbc59e2\n\n Documentation/git-format-patch.txt | 20 +++++++++++---------\n Documentation/git-send-email.txt   |  7 ++++---\n 2 files changed, 15 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex fe2f69d36e..fa2377d5e9 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -64,15 +64,17 @@ There are two ways to specify which commits to operate on.\n    to the tip of the current branch that are not in the history\n    that leads to the <since> to be output.\n \n-2. Generic <revision range> expression (see \"SPECIFYING\n-   REVISIONS\" section in linkgit:gitrevisions[7]) means the\n-   commits in the specified range.\n-\n-The first rule takes precedence in the case of a single <commit>.  To\n-apply the second rule, i.e., format everything since the beginning of\n-history up until <commit>, use the `--root` option: `git format-patch\n---root <commit>`.  If you want to format only <commit> itself, you\n-can do this with `git format-patch -1 <commit>`.\n+2. A Generic <revision range> expression that describes with\n+   options and revisions a range of commits.\n+\n+If you give a single <commit> and nothing else, it is taken as the\n+<since> of the first form.  If you want to format everything since the\n+beginning of history up until <commit>, use the `--root` option:\n+`git format-patch --root <commit>`.  If you want to format only the\n+<commit> itself, use instead `git format-patch -1 <commit>`.\n+\n+If you want to affect a set of commits, provide a range (see\n+\"SPECIFYING RANGES\" section in linkgit:gitrevisions[7]).\n \n By default, each output file is numbered sequentially from 1, and uses the\n first line of the commit message (massaged for pathname safety) as\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..16d8d19cf5 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<send-email options>] <file|directory>...\n+'git send-email' [<send-email options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -18,8 +19,8 @@ DESCRIPTION\n Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n-last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+last case, a revision in a format accepted by linkgit:git-format-patch[1]\n+as well as relevant options must be provided to git send-email.\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\n-- \n2.33.0.1081.g099423f5b7\n\n"},{"id":"438398","messageId":"1d6ec04f-6f89-5da6-75a9-3099e2437df5@gmail.com","threadId":"56329","inReplyTo":"20211009083133.4446-1-carenas@gmail.com","subject":"Re: [RFC PATCH] Documentation: better document format-patch options in send-email","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-10-09T08:57:32Z","receivedAt":"2021-10-09T08:57:47Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 09/10/21 15.31, Carlo Marcelo Arenas Belón wrote:\n> -2. Generic <revision range> expression (see \"SPECIFYING\n> -   REVISIONS\" section in linkgit:gitrevisions[7]) means the\n> -   commits in the specified range.\n> -\n> -The first rule takes precedence in the case of a single <commit>.  To\n> -apply the second rule, i.e., format everything since the beginning of\n> -history up until <commit>, use the `--root` option: `git format-patch\n> ---root <commit>`.  If you want to format only <commit> itself, you\n> -can do this with `git format-patch -1 <commit>`.\n> +2. A Generic <revision range> expression that describes with\n> +   options and revisions a range of commits.\n> +\n> +If you give a single <commit> and nothing else, it is taken as the\n> +<since> of the first form.  If you want to format everything since the\n> +beginning of history up until <commit>, use the `--root` option:\n> +`git format-patch --root <commit>`.  If you want to format only the\n> +<commit> itself, use instead `git format-patch -1 <commit>`.\n> +\n> +If you want to affect a set of commits, provide a range (see\n> +\"SPECIFYING RANGES\" section in linkgit:gitrevisions[7]).\n>   \n\nSupposed that we have following commit graph:\n\na --- b --- c --- d --- e --- f (main)\n             \\\n              --- g --- h --- i (mywork, HEAD)\n\nAccording to your edit, `git format-patch <c>` and `git format-patch \n--root <i>` are equivalent, right?\n\nI think for the third case, s/affect/format/.\n\n> @@ -18,8 +19,8 @@ DESCRIPTION\n>   Takes the patches given on the command line and emails them out.\n>   Patches can be specified as files, directories (which will send all\n>   files in the directory), or directly as a revision list.  In the\n> -last case, any format accepted by linkgit:git-format-patch[1] can\n> -be passed to git send-email.\n> +last case, a revision in a format accepted by linkgit:git-format-patch[1]\n> +as well as relevant options must be provided to git send-email.\n>   \n>   The header of the email is configurable via command-line options.  If not\n>   specified on the command line, the user will be prompted with a ReadLine\n> \n\nDid you mean that in the second form of git send-email, only \nformat-patch options are accepted?\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"438400","messageId":"CAPUEsphrNMPO_KaAmae02-DsxB9m1tBEK_Gnv29_mLQn0j2MkA@mail.gmail.com","threadId":"56329","inReplyTo":"1d6ec04f-6f89-5da6-75a9-3099e2437df5@gmail.com","subject":"Re: [RFC PATCH] Documentation: better document format-patch options in send-email","fromName":"Carlo Arenas","fromEmail":"carenas@gmail.com","sentAt":"2021-10-09T09:32:42Z","receivedAt":"2021-10-09T09:33:07Z","isPatch":true,"sender":{"key":"carenas@gmail.com","avatar":"https://avatars.githubusercontent.com/u/76036?v=4"},"body":"On Sat, Oct 9, 2021 at 1:57 AM Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n>\n> On 09/10/21 15.31, Carlo Marcelo Arenas Belón wrote:\n> > -2. Generic <revision range> expression (see \"SPECIFYING\n> > -   REVISIONS\" section in linkgit:gitrevisions[7]) means the\n> > -   commits in the specified range.\n> > -\n> > -The first rule takes precedence in the case of a single <commit>.  To\n> > -apply the second rule, i.e., format everything since the beginning of\n> > -history up until <commit>, use the `--root` option: `git format-patch\n> > ---root <commit>`.  If you want to format only <commit> itself, you\n> > -can do this with `git format-patch -1 <commit>`.\n> > +2. A Generic <revision range> expression that describes with\n> > +   options and revisions a range of commits.\n> > +\n> > +If you give a single <commit> and nothing else, it is taken as the\n> > +<since> of the first form.  If you want to format everything from the\n> > +beginning of history up until <commit>, use the `--root` option:\n> > +`git format-patch --root <commit>`.  If you want to format only the\n> > +<commit> itself, use instead `git format-patch -1 <commit>`.\n> > +\n> > +If you want to affect a set of commits, provide a range (see\n> > +\"SPECIFYING RANGES\" section in linkgit:gitrevisions[7]).\n>\n> Supposed that we have following commit graph:\n>\n> a --- b --- c --- d --- e --- f (main)\n>              \\\n>               --- g --- h --- i (mywork, HEAD)\n>\n> According to your edit, `git format-patch <c>` and `git format-patch\n> --root <i>` are equivalent, right?\n\nI didn't change the definition of --root with my edit, but I guess it\nis still confusing.\n\nthe beginning of history from your tree is a, c would be a \"fork\npoint\" AFAIK, but if you use --root will get 6 patches (a, b, c, g, h,\ni)\n\n> > @@ -18,8 +19,8 @@ DESCRIPTION\n> >   Takes the patches given on the command line and emails them out.\n> >   Patches can be specified as files, directories (which will send all\n> >   files in the directory), or directly as a revision list.  In the\n> > -last case, any format accepted by linkgit:git-format-patch[1] can\n> > -be passed to git send-email.\n> > +last case, a revision in a format accepted by linkgit:git-format-patch[1]\n> > +as well as relevant options must be provided to git send-email.\n> >\n> >   The header of the email is configurable via command-line options.  If not\n> >   specified on the command line, the user will be prompted with a ReadLine\n>\n> Did you mean that in the second form of git send-email, only\n> format-patch options are accepted?\n\nThe synopsis shows \"send-email options\" are also allowed (as\noptional), the mention of \"relevant options\" here was to indicate\nadditional options from git-format-patch which make sense (ex: common\ndiff options, --root, or the options from the range section of\nreferences).\n\nThe truth is that you can actually do files, directories and revisions\nnow, but that is a bug.\n\nCarlo\n"},{"id":"438402","messageId":"189cd45c-c550-8021-a1d1-b271bd4ecf57@gmail.com","threadId":"56329","inReplyTo":"CAPUEsphrNMPO_KaAmae02-DsxB9m1tBEK_Gnv29_mLQn0j2MkA@mail.gmail.com","subject":"Re: [RFC PATCH] Documentation: better document format-patch options in send-email","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-10-09T11:04:22Z","receivedAt":"2021-10-09T11:04:30Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 09/10/21 16.32, Carlo Arenas wrote:\n> The synopsis shows \"send-email options\" are also allowed (as\n> optional), the mention of \"relevant options\" here was to indicate\n> additional options from git-format-patch which make sense (ex: common\n> diff options, --root, or the options from the range section of\n> references).\n> \n> The truth is that you can actually do files, directories and revisions\n> now, but that is a bug.\n> \n> Carlo\n> \n\ngit send-email behaves similar to ln(1), depending on what options and \narguments that are passed. See my attempted patch [1] for the wording.\n\n[1]: \nhttps://lore.kernel.org/git/20210924121352.42138-1-bagasdotme@gmail.com/\n\nFor SYNOPSIS for file/directory and revision range, I suggest:\n\n'git send-email' [<options>] <file|directory>...\n'git send-email' [<send-email options>] [<format-patch options>] \n<revision range>\n\nwhere <revision range> must be any forms that are accepted by \ngit-format-patch(1).\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"438430","messageId":"xmqq1r4sftuf.fsf@gitster.g","threadId":"56329","inReplyTo":"CAPUEsphrNMPO_KaAmae02-DsxB9m1tBEK_Gnv29_mLQn0j2MkA@mail.gmail.com","subject":"Re: [RFC PATCH] Documentation: better document format-patch options in send-email","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-10-10T21:33:28Z","receivedAt":"2021-10-10T21:33:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carlo Arenas <carenas@gmail.com> writes:\n\n>> > +If you give a single <commit> and nothing else, it is taken as the\n>> > +<since> of the first form.  If you want to format everything from the\n>> > +beginning of history up until <commit>, use the `--root` option:\n>> > +`git format-patch --root <commit>`.\n>>\n>> Supposed that we have following commit graph:\n>>\n>> a --- b --- c --- d --- e --- f (main)\n>>              \\\n>>               --- g --- h --- i (mywork, HEAD)\n>>\n>> According to your edit, `git format-patch <c>` and `git format-patch\n>> --root <i>` are equivalent, right?\n>\n> I didn't change the definition of --root with my edit, but I guess it\n> is still confusing.\n\nThe explanation you gave Bagas describes what these two variants,\ni.e. \"<c> alone\" and \"--root <c>\", mean and how they behave very\nclearly.  In fact, the 4-line description is designed to encourage\nreaders to compare a pair of cases like these, using the same commit\nin the middle of the history you get two quite different set of\ncommits with and without \"--root\".\n\nYou can ask for \"--root <i>\" to get a-b-c-g-h-i but it is not\na good example as there is no useful contrasting example that does\nnot use \"--root\", as \"git format-patch i\" would be showing an empty\nset.\n\nThe fact that somebody wanted to compare between \"<c>\" and \"--root\n<i>\" might be a sign that the 4-line description is still somehow\nconfusing, but I cannot quite figure out what needs to be improved\nin the description to avoid such a confusion (IOW, I fail to see how\nthe description can lead to such a confusion).\n\nThanks.\n\n\n"},{"id":"438438","messageId":"20211011041033.20004-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"YWE41xTLhBFWqUFl@carlos-mbp.lan","subject":"[PATCH v7 0/3] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-11T04:10:30Z","receivedAt":"2021-10-11T04:10:56Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Differences from V6:\n\n2/3: Addresses all of Carlos's comments:\n  - make indentation consistent (tabs): note that there's a giant diff\n    for the largest GetOptions now, it adds a bit of noise to the patch\n  - do not reuse the options variable, for improved readability.\n\n2/3: One extra improvement:\n  - deduplicate send-email and format-patch common options (for example,\n    now --from appears only once)\n\n3/3:\n  - updated git-send-email.perl USAGE to be consistent with\n    git-send-email(1)\n  - still haven't touched anything else, waiting on Carlos's RFC patch\n    ongoing discussion to settle.\n\nThiago Perrotta (3):\n  send-email: terminate --git-completion-helper with LF\n  send-email: programmatically generate bash completions\n  send-email docs: add format-patch options\n\n Documentation/git-send-email.txt       |   6 +-\n contrib/completion/git-completion.bash |  11 +-\n git-send-email.perl                    | 156 ++++++++++++++-----------\n t/t9902-completion.sh                  |   3 +\n 4 files changed, 97 insertions(+), 79 deletions(-)\n\n-- \n2.33.0\n\n"},{"id":"438439","messageId":"20211011041033.20004-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"YWE41xTLhBFWqUFl@carlos-mbp.lan","subject":"[PATCH v7 1/3] send-email: terminate --git-completion-helper with LF","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-11T04:10:31Z","receivedAt":"2021-10-11T04:10:57Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"Unlike other Git subcommands, \"git send-email\" leaves its output an\nincomplete line when \"--git-completion-helper\" is asked.  Be consistent\nby terminating the message with LF here.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n git-send-email.perl | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..d1731c1755 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -114,7 +114,7 @@ sub usage {\n }\n \n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n+    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n     exit(0);\n }\n \n-- \n2.33.0\n\n"},{"id":"438440","messageId":"20211011041033.20004-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"YWE41xTLhBFWqUFl@carlos-mbp.lan","subject":"[PATCH v7 2/3] send-email: programmatically generate bash completions","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-11T04:10:32Z","receivedAt":"2021-10-11T04:11:00Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well, generating them\nprogrammatically from the usage.\n\nExtract flags from the three existing `GetOptions`.\n\nIntroduce a uniq subroutine, otherwise --cc-cover, --to-cover and other\nflags would show up twice. In addition, deduplicate options common to\nboth send-email and format-patch, like --from.\n\nRemove extraneous flags: --, --h and --git-completion-helper.\n\nAdd a completion test for \"send-email --validate\", a send-email flag.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\nBased-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n contrib/completion/git-completion.bash |  11 +-\n git-send-email.perl                    | 153 ++++++++++++++-----------\n t/t9902-completion.sh                  |   3 +\n 3 files changed, 91 insertions(+), 76 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex d1731c1755..587e52d1d8 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -113,9 +113,24 @@ sub usage {\n \texit(1);\n }\n \n+sub uniq {\n+\tmy %seen;\n+\tgrep !$seen{$_}++, @_;\n+}\n+\n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper'), \"\\n\";\n-    exit(0);\n+\tmy ($original_opts) = @_;\n+\tmy @send_email_opts = map {\n+\t\t\"--$_\"\n+\t} map {\n+\t\ts/(?:[:=][si]|!)$//;\n+\t\tsplit /\\|/;\n+\t} keys %$original_opts;\n+\tmy @format_patch_opts = split(/ /, Git::command('format-patch', '--git-completion-helper'));\n+\tmy @options = (@send_email_opts, @format_patch_opts);\n+\t@options = uniq (grep !/^$|^--$|--git-completion-helper|--h/, @options);\n+\tprint \"@options\\n\";\n+\texit(0);\n }\n \n # most mail servers generate the Date: header, but not all...\n@@ -425,10 +440,11 @@ sub config_regexp {\n \tmy $key = \"sendemail.identity\";\n \t$identity = Git::config(@repo, $key) if exists $known_config_keys{$key};\n }\n-my $rc = GetOptions(\n+my %identity_options = (\n \t\"identity=s\" => \\$identity,\n \t\"no-identity\" => \\$no_identity,\n );\n+my $rc = GetOptions(%identity_options);\n usage() unless $rc;\n undef $identity if $no_identity;\n \n@@ -444,71 +460,75 @@ sub config_regexp {\n \n my $help;\n my $git_completion_helper;\n-$rc = GetOptions(\"h\" => \\$help,\n-                 \"dump-aliases\" => \\$dump_aliases);\n+my %dump_aliases_options = (\n+\t\"h\" => \\$help,\n+\t\"dump-aliases\" => \\$dump_aliases,\n+);\n+$rc = GetOptions(%dump_aliases_options);\n usage() unless $rc;\n die __(\"--dump-aliases incompatible with other options\\n\")\n     if !$help and $dump_aliases and @ARGV;\n-$rc = GetOptions(\n-\t\t    \"sender|from=s\" => \\$sender,\n-                    \"in-reply-to=s\" => \\$initial_in_reply_to,\n-\t\t    \"reply-to=s\" => \\$reply_to,\n-\t\t    \"subject=s\" => \\$initial_subject,\n-\t\t    \"to=s\" => \\@getopt_to,\n-\t\t    \"to-cmd=s\" => \\$to_cmd,\n-\t\t    \"no-to\" => \\$no_to,\n-\t\t    \"cc=s\" => \\@getopt_cc,\n-\t\t    \"no-cc\" => \\$no_cc,\n-\t\t    \"bcc=s\" => \\@getopt_bcc,\n-\t\t    \"no-bcc\" => \\$no_bcc,\n-\t\t    \"chain-reply-to!\" => \\$chain_reply_to,\n-\t\t    \"no-chain-reply-to\" => sub {$chain_reply_to = 0},\n-\t\t    \"sendmail-cmd=s\" => \\$sendmail_cmd,\n-\t\t    \"smtp-server=s\" => \\$smtp_server,\n-\t\t    \"smtp-server-option=s\" => \\@smtp_server_options,\n-\t\t    \"smtp-server-port=s\" => \\$smtp_server_port,\n-\t\t    \"smtp-user=s\" => \\$smtp_authuser,\n-\t\t    \"smtp-pass:s\" => \\$smtp_authpass,\n-\t\t    \"smtp-ssl\" => sub { $smtp_encryption = 'ssl' },\n-\t\t    \"smtp-encryption=s\" => \\$smtp_encryption,\n-\t\t    \"smtp-ssl-cert-path=s\" => \\$smtp_ssl_cert_path,\n-\t\t    \"smtp-debug:i\" => \\$debug_net_smtp,\n-\t\t    \"smtp-domain:s\" => \\$smtp_domain,\n-\t\t    \"smtp-auth=s\" => \\$smtp_auth,\n-\t\t    \"no-smtp-auth\" => sub {$smtp_auth = 'none'},\n-\t\t    \"annotate!\" => \\$annotate,\n-\t\t    \"no-annotate\" => sub {$annotate = 0},\n-\t\t    \"compose\" => \\$compose,\n-\t\t    \"quiet\" => \\$quiet,\n-\t\t    \"cc-cmd=s\" => \\$cc_cmd,\n-\t\t    \"suppress-from!\" => \\$suppress_from,\n-\t\t    \"no-suppress-from\" => sub {$suppress_from = 0},\n-\t\t    \"suppress-cc=s\" => \\@suppress_cc,\n-\t\t    \"signed-off-cc|signed-off-by-cc!\" => \\$signed_off_by_cc,\n-\t\t    \"no-signed-off-cc|no-signed-off-by-cc\" => sub {$signed_off_by_cc = 0},\n-\t\t    \"cc-cover|cc-cover!\" => \\$cover_cc,\n-\t\t    \"no-cc-cover\" => sub {$cover_cc = 0},\n-\t\t    \"to-cover|to-cover!\" => \\$cover_to,\n-\t\t    \"no-to-cover\" => sub {$cover_to = 0},\n-\t\t    \"confirm=s\" => \\$confirm,\n-\t\t    \"dry-run\" => \\$dry_run,\n-\t\t    \"envelope-sender=s\" => \\$envelope_sender,\n-\t\t    \"thread!\" => \\$thread,\n-\t\t    \"no-thread\" => sub {$thread = 0},\n-\t\t    \"validate!\" => \\$validate,\n-\t\t    \"no-validate\" => sub {$validate = 0},\n-\t\t    \"transfer-encoding=s\" => \\$target_xfer_encoding,\n-\t\t    \"format-patch!\" => \\$format_patch,\n-\t\t    \"no-format-patch\" => sub {$format_patch = 0},\n-\t\t    \"8bit-encoding=s\" => \\$auto_8bit_encoding,\n-\t\t    \"compose-encoding=s\" => \\$compose_encoding,\n-\t\t    \"force\" => \\$force,\n-\t\t    \"xmailer!\" => \\$use_xmailer,\n-\t\t    \"no-xmailer\" => sub {$use_xmailer = 0},\n-\t\t    \"batch-size=i\" => \\$batch_size,\n-\t\t    \"relogin-delay=i\" => \\$relogin_delay,\n-\t\t    \"git-completion-helper\" => \\$git_completion_helper,\n-\t );\n+my %options = (\n+\t\"sender|from=s\" => \\$sender,\n+\t\"in-reply-to=s\" => \\$initial_in_reply_to,\n+\t\"reply-to=s\" => \\$reply_to,\n+\t\"subject=s\" => \\$initial_subject,\n+\t\"to=s\" => \\@getopt_to,\n+\t\"to-cmd=s\" => \\$to_cmd,\n+\t\"no-to\" => \\$no_to,\n+\t\"cc=s\" => \\@getopt_cc,\n+\t\"no-cc\" => \\$no_cc,\n+\t\"bcc=s\" => \\@getopt_bcc,\n+\t\"no-bcc\" => \\$no_bcc,\n+\t\"chain-reply-to!\" => \\$chain_reply_to,\n+\t\"no-chain-reply-to\" => sub {$chain_reply_to = 0},\n+\t\"sendmail-cmd=s\" => \\$sendmail_cmd,\n+\t\"smtp-server=s\" => \\$smtp_server,\n+\t\"smtp-server-option=s\" => \\@smtp_server_options,\n+\t\"smtp-server-port=s\" => \\$smtp_server_port,\n+\t\"smtp-user=s\" => \\$smtp_authuser,\n+\t\"smtp-pass:s\" => \\$smtp_authpass,\n+\t\"smtp-ssl\" => sub { $smtp_encryption = 'ssl' },\n+\t\"smtp-encryption=s\" => \\$smtp_encryption,\n+\t\"smtp-ssl-cert-path=s\" => \\$smtp_ssl_cert_path,\n+\t\"smtp-debug:i\" => \\$debug_net_smtp,\n+\t\"smtp-domain:s\" => \\$smtp_domain,\n+\t\"smtp-auth=s\" => \\$smtp_auth,\n+\t\"no-smtp-auth\" => sub {$smtp_auth = 'none'},\n+\t\"annotate!\" => \\$annotate,\n+\t\"no-annotate\" => sub {$annotate = 0},\n+\t\"compose\" => \\$compose,\n+\t\"quiet\" => \\$quiet,\n+\t\"cc-cmd=s\" => \\$cc_cmd,\n+\t\"suppress-from!\" => \\$suppress_from,\n+\t\"no-suppress-from\" => sub {$suppress_from = 0},\n+\t\"suppress-cc=s\" => \\@suppress_cc,\n+\t\"signed-off-cc|signed-off-by-cc!\" => \\$signed_off_by_cc,\n+\t\"no-signed-off-cc|no-signed-off-by-cc\" => sub {$signed_off_by_cc = 0},\n+\t\"cc-cover|cc-cover!\" => \\$cover_cc,\n+\t\"no-cc-cover\" => sub {$cover_cc = 0},\n+\t\"to-cover|to-cover!\" => \\$cover_to,\n+\t\"no-to-cover\" => sub {$cover_to = 0},\n+\t\"confirm=s\" => \\$confirm,\n+\t\"dry-run\" => \\$dry_run,\n+\t\"envelope-sender=s\" => \\$envelope_sender,\n+\t\"thread!\" => \\$thread,\n+\t\"no-thread\" => sub {$thread = 0},\n+\t\"validate!\" => \\$validate,\n+\t\"no-validate\" => sub {$validate = 0},\n+\t\"transfer-encoding=s\" => \\$target_xfer_encoding,\n+\t\"format-patch!\" => \\$format_patch,\n+\t\"no-format-patch\" => sub {$format_patch = 0},\n+\t\"8bit-encoding=s\" => \\$auto_8bit_encoding,\n+\t\"compose-encoding=s\" => \\$compose_encoding,\n+\t\"force\" => \\$force,\n+\t\"xmailer!\" => \\$use_xmailer,\n+\t\"no-xmailer\" => sub {$use_xmailer = 0},\n+\t\"batch-size=i\" => \\$batch_size,\n+\t\"relogin-delay=i\" => \\$relogin_delay,\n+\t\"git-completion-helper\" => \\$git_completion_helper,\n+);\n+$rc = GetOptions(%options);\n \n # Munge any \"either config or getopt, not both\" variables\n my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);\n@@ -516,7 +536,8 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-completion_helper() if $git_completion_helper;\n+my %all_options = (%options, %dump_aliases_options, %identity_options);\n+completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"438441","messageId":"20211011041033.20004-4-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"YWE41xTLhBFWqUFl@carlos-mbp.lan","subject":"[PATCH v7 3/3] send-email docs: add format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-11T04:10:33Z","receivedAt":"2021-10-11T04:11:03Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"git-send-email(1) does not mention that \"git format-patch\" options are\naccepted. Augment SYNOPSIS and DESCRIPTION to mention it.\n\nUpdate git-send-email.perl USAGE to be consistent with\ngit-send-email(1).\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 6 ++++--\n git-send-email.perl              | 3 ++-\n 2 files changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..41cd8cb424 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, as well as options understood by\n+linkgit:git-format-patch[1].\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 587e52d1d8..850c572dec 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -40,7 +40,8 @@ package main;\n \n sub usage {\n \tprint <<EOT;\n-git send-email [options] <file | directory | rev-list options >\n+git send-email' [<options>] <file|directory>\n+git send-email' [<options>] <format-patch options>\n git send-email --dump-aliases\n \n   Composing:\n-- \n2.33.0\n\n"},{"id":"438463","messageId":"87fst7lkjx.fsf@evledraar.gmail.com","threadId":"56329","inReplyTo":"20211011041033.20004-1-tbperrotta@gmail.com","subject":"Re: [PATCH v7 0/3] send-email: shell completion improvements","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-11T13:46:20Z","receivedAt":"2021-10-11T14:29:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Oct 11 2021, Thiago Perrotta wrote:\n\n> Differences from V6:\n>\n> 2/3: Addresses all of Carlos's comments:\n>   - make indentation consistent (tabs): note that there's a giant diff\n>     for the largest GetOptions now, it adds a bit of noise to the patch\n\nI took Carlo's suggestion to mean to indent your uniq function, not to\nre-indent a bunch of existing code while at it...\n\n>   - do not reuse the options variable, for improved readability.\n\n...I think that re-indentation is better left alone for the patch\nreadability.\n\nAnyway, sorry about not looking at this sooner after my off-the-cuff\n[1]; I think this looks mostly good-ish, but there's a few broken things\nhere:\n\nFirst, in your 1/3 you're adding a \\n, but in 2/3 we end up with \\n\\n. I\nthink you can just skip 1/3, maybe mention \"how it also has a \"\\n\" in\nthe commit message.\n\nI.e. you start implicitly picking up the newline because you changed\nfrom a \"print\" to a \"split\", and latter imposes Perl's scalar context on\nits argument, but the former doesn't. That's a combination of some Perl\ntrivia and our own Git.pm being overly clever about wantarray(), but\nthere you go.\n\nMore importantly in [1] I meant that last paragraph as a \"and as an\nexcercise for the reader..\".\n\nI.e. we should not simply strip the trailing \"=\" etc., we need to parse\nthose out of the Perl GetOptions arguments, and come up with mapping to\nwhat we do in parse-options.c. I think that's basically adding a \"=\" at\nthe end of all options that end with \"=s\", \":i\", \"=d\", \":s\" etc.\n\nYou then strip out \"--\" arguments from the combined list, but isn't this\nsomething we do need to emit? I.e. it's used as syntax by the bash\ncompletion isn't it? (I just skimmed the relevant C code in\nparse-options.c).\n    \n    $ git clone --git-completion-helper | tr ' ' '\\n' | grep -C2 -- ^--$\n    --hardlinks\n    --tags\n    --\n    --no-verbose\n    --no-quiet\n\nFor --no-foo arguments we emit both a --foo and --no-foo in it, that\nsort of (maybe entirely) works in your version because some/all (I\nhaven't checked all) options have corresponding \"foo\" arguments for\n\"no-foo\", so maybe it sort of works out, but does the ordering\nbefore/after the \"--\", and that we strip out the \"--\" but e.g. \"git\nclone\" will emit it?\n\nWe then don't want to emit \"-h\", but you strip out \"--h\", first we\nmapped \"h\" to \"--h\" in the loop above, so we should do that there. But\nbetter yet we have a \"%dump_aliases_options\" already, maybe it +\n\"git-completion-helper\" can be moved to another \"%not_for_completion\"\nhash or something.\n\nThe map/map/keys loop also will silently do something odd if it starts\ngetting input data it didn't expect, i.e. it would be more reliable as a\nregex check, and then die() if we start getting somethnig we don't\nexpect, i.e. if someone adds an option not covered by our regex.\n\nThat it's a map/map/keys is just some off-the-cuff Perl hacking on my\npart, I think for validation etc. it's usually better to just turn it\ninto a plain old boring for-loop.\n\n1. https://lore.kernel.org/git/87bl4h3fgv.fsf@evledraar.gmail.com/\n"},{"id":"438481","messageId":"20211011171221.70231-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87fst7lkjx.fsf@evledraar.gmail.com","subject":"[DRAFT/WIP PATCH] send-email: programmatically generate bash completions","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-11T17:12:22Z","receivedAt":"2021-10-11T17:13:45Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well, extracting them\nprogrammatically from its three existing \"GetOptions\".\n\nIntroduce a \"uniq\" subroutine, otherwise --cc-cover, --to-cover and\nother flags would show up twice. In addition, deduplicate flags common\nto both \"send-email\" and \"format-patch\", like --from.\n\nRemove extraneous flags: --, --h and --git-completion-helper.\n\nAdd a completion test for \"send-email --validate\", a send-email flag.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\nBased-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n\n> ...I think that re-indentation is better left alone for the patch\n> readability.\n\nReverted the `GetOptions` indentation. Noise is now gone :-)\n\n> First, in your 1/3 you're adding a \\n, but in 2/3 we end up with \\n\\n. I\n> think you can just skip 1/3, maybe mention \"how it also has a \"\\n\" in\n> the commit message.\n\nI don't quite see how this would fit into the commit message. A comment in the\ncode seems to fit better to account for this detail. That's what I did, but if\nyou still disagree, please elaborate where in the commit message this sentence\nshould be added.\n\n> You then strip out \"--\" arguments from the combined list, but isn't this\n> something we do need to emit? I.e. it's used as syntax by the bash\n> completion isn't it? (I just skimmed the relevant C code in\n> parse-options.c).\n\nI interpreted that standalone `--` as an extraneous / useless token. If it's\nthere intentionally, then I am reverting my stripping it. At the end of the day\nwhether to include it or not is a small detail, but FYI, when I do:\n\n  git clone -<TAB>\n\nin bash, nothing happens. I would have expected it to be expanded to \"--\"\nbecause of the explicit \"--\", but it doesn't. Therefore my conclusion is that\n\"--\" in the output of \"--git-completion-helper\" is useless. Am I missing\nsomething?\n\nFinally, as per your comments about \"=\": OK, I see what you mean. For the record\nI had produced a quick-and-dirty version earlier (on top of V6), but didn't\ninclude it in V7 because I didn't deem it polished enough, but I'll include it\nhere for reference. I'll take your new comments to see if I can produce a better\npolished version before I send V8:\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 465e9867b9..f0f83330d3 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -123,12 +123,13 @@ sub completion_helper {\n     my @send_email_opts = map {\n       \"--$_\"\n     } map {\n-      s/(?:[:=][si]|!)$//;\n+      s/!$//;\n+      s/[:=][si]$/=/;\n       split /\\|/, $_;\n     } keys %$options;\n-    my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');\n-    my @options = uniq @send_email_opts, @format_patch_opts;\n-    @options = grep !/--git-completion-helper|--h/, @options;\n+    my @format_patch_opts = split(/ /, Git::command('format-patch', '--git-completion-helper'));\n+    my @options = (@send_email_opts, @format_patch_opts);\n+    @options = uniq (grep !/^$|^--$|--git-completion-helper|--h/, @options);\n     print \"@options\\n\";\n     exit(0);\n }\n\n> That it's a map/map/keys is just some off-the-cuff Perl hacking on my\n\npart, I think for validation etc. it's usually better to just turn it\ninto a plain old boring for-loop.\n\nOh, okay, I didn't find it hacky at all, the `map` seemed quite elegant and\nfunctional to me, but then again I am a perl newbie :-P.\n\nDifferences from V7 (so far):\n\nAs per Ævar's comments:\n\n- completely drop 1/3 since we'now using split instead of print to incorporate\n  format-patch options. Side effect: then-extraneous '\\n' is now gone.\n\n- revert indentation (tabs) on GetOptions to eliminate diff noise (as per Ævar's\n  interpretation of original Carlos's comment)\n\n- re-add \"--\" to the output of \"git send-email --git-completion-helper\"\n\n contrib/completion/git-completion.bash | 11 +------\n git-send-email.perl                    | 40 ++++++++++++++++++++------\n t/t9902-completion.sh                  |  3 ++\n 3 files changed, 35 insertions(+), 19 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..b632313192 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -113,9 +113,25 @@ sub usage {\n \texit(1);\n }\n \n+sub uniq {\n+\tmy %seen;\n+\tgrep !$seen{$_}++, @_;\n+}\n+\n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n-    exit(0);\n+\tmy ($original_opts) = @_;\n+\tmy @send_email_opts = map {\n+\t\t\"--$_\"\n+\t} map {\n+\t\ts/(?:[:=][si]|!)$//;\n+\t\tsplit /\\|/;\n+\t} keys %$original_opts;\n+\tmy @format_patch_opts = split(/ /, Git::command('format-patch', '--git-completion-helper'));\n+\tmy @options = (@send_email_opts, @format_patch_opts);\n+\t@options = uniq (grep !/^$|--git-completion-helper|--h/, @options);\n+\t# There's an implicit '\\n' here already, no need to add an explicit one.\n+\tprint \"@options\";\n+\texit(0);\n }\n \n # most mail servers generate the Date: header, but not all...\n@@ -425,10 +441,11 @@ sub config_regexp {\n \tmy $key = \"sendemail.identity\";\n \t$identity = Git::config(@repo, $key) if exists $known_config_keys{$key};\n }\n-my $rc = GetOptions(\n+my %identity_options = (\n \t\"identity=s\" => \\$identity,\n \t\"no-identity\" => \\$no_identity,\n );\n+my $rc = GetOptions(%identity_options);\n usage() unless $rc;\n undef $identity if $no_identity;\n \n@@ -444,14 +461,17 @@ sub config_regexp {\n \n my $help;\n my $git_completion_helper;\n-$rc = GetOptions(\"h\" => \\$help,\n-                 \"dump-aliases\" => \\$dump_aliases);\n+my %dump_aliases_options = (\n+\t\"h\" => \\$help,\n+\t\"dump-aliases\" => \\$dump_aliases,\n+);\n+$rc = GetOptions(%dump_aliases_options);\n usage() unless $rc;\n die __(\"--dump-aliases incompatible with other options\\n\")\n     if !$help and $dump_aliases and @ARGV;\n-$rc = GetOptions(\n+my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n-                    \"in-reply-to=s\" => \\$initial_in_reply_to,\n+\t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n \t\t    \"reply-to=s\" => \\$reply_to,\n \t\t    \"subject=s\" => \\$initial_subject,\n \t\t    \"to=s\" => \\@getopt_to,\n@@ -508,7 +528,8 @@ sub config_regexp {\n \t\t    \"batch-size=i\" => \\$batch_size,\n \t\t    \"relogin-delay=i\" => \\$relogin_delay,\n \t\t    \"git-completion-helper\" => \\$git_completion_helper,\n-\t );\n+);\n+$rc = GetOptions(%options);\n \n # Munge any \"either config or getopt, not both\" variables\n my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);\n@@ -516,7 +537,8 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-completion_helper() if $git_completion_helper;\n+my %all_options = (%options, %dump_aliases_options, %identity_options);\n+completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.0\n\n"},{"id":"439598","messageId":"20211025212707.188151-1-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87fst7lkjx.fsf@evledraar.gmail.com","subject":"[PATCH v8 0/2] send-email: shell completion improvements","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-25T21:27:05Z","receivedAt":"2021-10-25T21:27:26Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"> ...I think that re-indentation is better left alone for the patch\n> readability.\n\nReverted the `GetOptions` indentation. Noise is now gone :-)\n\n> First, in your 1/3 you're adding a \\n, but in 2/3 we end up with \\n\\n. I\n> think you can just skip 1/3, maybe mention \"how it also has a \"\\n\" in\n> the commit message.\n\nI don't quite see how this would fit into the commit message. A comment in the\ncode seems to fit better to account for this detail. That's what I did, but if\nyou still disagree, please elaborate where in the commit message this sentence\nshould be added.\n\n> You then strip out \"--\" arguments from the combined list, but isn't this\n> something we do need to emit? I.e. it's used as syntax by the bash\n> completion isn't it? (I just skimmed the relevant C code in\n> parse-options.c).\n\nI interpreted that standalone `--` as an extraneous / useless token. If it's\nthere intentionally, then I am reverting my stripping of it. At the end of the\nday whether to include it or not is a small detail, but FYI, when I do:\n\n  $ git clone -<TAB>\n\nin bash, nothing happens. I would have expected it to be expanded to \"--\"\nbecause of the explicit \"--\", but it doesn't. Therefore my conclusion is that\n\"--\" in the output of \"--git-completion-helper\" is useless. Am I missing\nsomething? What would be the function of the standalone \"--\" then?\n\nFrom my local testing, whether the options are sorted or not, whether\nthey are repeated or not, whether they follow a specific order with\nrespect to \"--\" or not, all of those details seem not to matter. Bash\ncompletion seems to handle all of those cases just fine interactively.\n\nIn fact, here's another example:\n\n$ git init --git-completion-helper | tr ' ' '\\n'  | grep -C1 '^--$'\n--no-template\n--\n--no-bare\n\n...there are --no-* options both _before_ and _after_ the --. I really\ncannot see the point of the -- in the output, it seems to be just noise.\n\nI readded -- to the output anyway since you requested it, but if it\nneeds to follow a certain spec w.r.t. ordering, we should have tests for\nit. This specific part (the -- and the --no- order thing) of the commit\nis something I am not keen to doing though, at least not in this patch\nseries; sorry, it already goes far beyond the scope of my original\nintent. Anything else you ask for that is inline with the original\nintent (like generating options programatically instead of hard-coding\nthem) I am fine with though, and in fact I believe I have addressed all\ncomments so far, if there's anything else I may have missed let me know.\n\n> I.e. we should not simply strip the trailing \"=\" etc., we need to parse\n> those out of the Perl GetOptions arguments, and come up with mapping to\n> what we do in parse-options.c. I think that's basically adding a \"=\" at\n> the end of all options that end with \"=s\", \":i\", \"=d\", \":s\" etc.\n\nOK, I see. This is a valid point, I updated the code to reflect this desired\nbehavior. PTAL. If needed we could make it more DRY, but as it is now it\nseems quite readable.\n\n> We then don't want to emit \"-h\", but you strip out \"--h\", first we\n> mapped \"h\" to \"--h\" in the loop above, so we should do that there. But\n> better yet we have a \"%dump_aliases_options\" already, maybe it +\n> \"git-completion-helper\" can be moved to another \"%not_for_completion\"\n> hash or something.\n\nOK, done. Introduced a \"not_for_completion\" hash. Doesn't seem to make a\nhuge difference compared to just using `grep` though.\n\n\nDifferences from V7:\n\nAs per Ævar's comments:\n\n- completely drop 1/3 since we'now using split instead of print to incorporate\n  format-patch options. Side effect: then-extraneous '\\n' is now gone.\n\n- revert indentation (tabs) on GetOptions to eliminate diff noise (as per Ævar's\n  interpretation of original Carlos's comment)\n\n- re-add \"--\" to the output of \"git send-email --git-completion-helper\"\n\n- introduce a \"not_for_completion\" hash to remove undesired options from the\n  output\n\n- add trailing = to send-email options that expect a string or an integer\n  argument, consistently with format-patch options\n\nThiago Perrotta (2):\n  send-email: programmatically generate bash completions\n  send-email docs: add format-patch options\n\n Documentation/git-send-email.txt       |  6 ++-\n contrib/completion/git-completion.bash | 11 +----\n git-send-email.perl                    | 56 +++++++++++++++++++++-----\n t/t9902-completion.sh                  |  3 ++\n 4 files changed, 54 insertions(+), 22 deletions(-)\n\n-- \n2.33.1\n\n"},{"id":"439599","messageId":"20211025212707.188151-2-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87fst7lkjx.fsf@evledraar.gmail.com","subject":"[PATCH v8 1/2] send-email: programmatically generate bash completions","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-25T21:27:06Z","receivedAt":"2021-10-25T21:27:26Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"\"git send-email --git-completion-helper\" only prints \"format-patch\"\nflags. Make it print \"send-email\" flags as well, extracting them\nprogrammatically from its three existing \"GetOptions\".\n\nIntroduce a \"uniq\" subroutine, otherwise --cc-cover, --to-cover and\nother flags would show up twice. In addition, deduplicate flags common\nto both \"send-email\" and \"format-patch\", like --from.\n\nRemove extraneous flags: --h and --git-completion-helper.\n\nAdd trailing \"=\" to options that expect an argument, inline with\nthe format-patch implementation.\n\nAdd a completion test for \"send-email --validate\", a send-email flag.\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\nBased-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +-----\n git-send-email.perl                    | 53 +++++++++++++++++++++-----\n t/t9902-completion.sh                  |  3 ++\n 3 files changed, 48 insertions(+), 19 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4bdd27ddc8..1b73a4dcc0 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2359,16 +2359,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp_builtin send-email \"--annotate --bcc --cc --cc-cmd --chain-reply-to\n-\t\t\t--compose --confirm= --dry-run --envelope-sender\n-\t\t\t--from --identity\n-\t\t\t--in-reply-to --no-chain-reply-to --no-signed-off-by-cc\n-\t\t\t--no-suppress-from --no-thread --quiet --reply-to\n-\t\t\t--signed-off-by-cc --smtp-pass --smtp-server\n-\t\t\t--smtp-server-port --smtp-encryption= --smtp-user\n-\t\t\t--subject --suppress-cc= --suppress-from --thread --to\n-\t\t\t--validate --no-validate\n-\t\t\t$__git_format_patch_extra_options\"\n+\t\t__gitcomp_builtin send-email \"$__git_format_patch_extra_options\"\n \t\treturn\n \t\t;;\n \tesac\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex e65d969d0b..b45c7da3ab 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -113,9 +113,38 @@ sub usage {\n \texit(1);\n }\n \n+sub uniq {\n+\tmy %seen;\n+\tgrep !$seen{$_}++, @_;\n+}\n+\n sub completion_helper {\n-    print Git::command('format-patch', '--git-completion-helper');\n-    exit(0);\n+\tmy ($original_opts) = @_;\n+\tmy %not_for_completion = (\n+\t\t\"git-completion-helper\" => undef,\n+\t\t\"h\" => undef,\n+\t);\n+\tmy @send_email_opts = ();\n+\n+\tforeach my $key (keys %$original_opts) {\n+\t\tunless (exists $not_for_completion{$key}) {\n+\t\t\t$key =~ s/!$//;\n+\n+\t\t\tif ($key =~ /[:=][si]$/) {\n+\t\t\t\t$key =~ s/[:=][si]$//;\n+\t\t\t\tpush (@send_email_opts, \"--$_=\") foreach (split (/\\|/, $key));\n+\t\t\t} else {\n+\t\t\t\tpush (@send_email_opts, \"--$_\") foreach (split (/\\|/, $key));\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tmy @format_patch_opts = split(/ /, Git::command('format-patch', '--git-completion-helper'));\n+\tmy @opts = (@send_email_opts, @format_patch_opts);\n+\t@opts = uniq (grep !/^$/, @opts);\n+\t# There's an implicit '\\n' here already, no need to add an explicit one.\n+\tprint \"@opts\";\n+\texit(0);\n }\n \n # most mail servers generate the Date: header, but not all...\n@@ -425,10 +454,11 @@ sub config_regexp {\n \tmy $key = \"sendemail.identity\";\n \t$identity = Git::config(@repo, $key) if exists $known_config_keys{$key};\n }\n-my $rc = GetOptions(\n+my %identity_options = (\n \t\"identity=s\" => \\$identity,\n \t\"no-identity\" => \\$no_identity,\n );\n+my $rc = GetOptions(%identity_options);\n usage() unless $rc;\n undef $identity if $no_identity;\n \n@@ -444,14 +474,17 @@ sub config_regexp {\n \n my $help;\n my $git_completion_helper;\n-$rc = GetOptions(\"h\" => \\$help,\n-                 \"dump-aliases\" => \\$dump_aliases);\n+my %dump_aliases_options = (\n+\t\"h\" => \\$help,\n+\t\"dump-aliases\" => \\$dump_aliases,\n+);\n+$rc = GetOptions(%dump_aliases_options);\n usage() unless $rc;\n die __(\"--dump-aliases incompatible with other options\\n\")\n     if !$help and $dump_aliases and @ARGV;\n-$rc = GetOptions(\n+my %options = (\n \t\t    \"sender|from=s\" => \\$sender,\n-                    \"in-reply-to=s\" => \\$initial_in_reply_to,\n+\t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n \t\t    \"reply-to=s\" => \\$reply_to,\n \t\t    \"subject=s\" => \\$initial_subject,\n \t\t    \"to=s\" => \\@getopt_to,\n@@ -508,7 +541,8 @@ sub config_regexp {\n \t\t    \"batch-size=i\" => \\$batch_size,\n \t\t    \"relogin-delay=i\" => \\$relogin_delay,\n \t\t    \"git-completion-helper\" => \\$git_completion_helper,\n-\t );\n+);\n+$rc = GetOptions(%options);\n \n # Munge any \"either config or getopt, not both\" variables\n my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);\n@@ -516,7 +550,8 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-completion_helper() if $git_completion_helper;\n+my %all_options = (%options, %dump_aliases_options, %identity_options);\n+completion_helper(\\%all_options) if $git_completion_helper;\n unless ($rc) {\n     usage();\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 11573936d5..a4faf64184 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2139,6 +2139,9 @@ test_expect_success PERL 'send-email' '\n \t--cover-from-description=Z\n \t--cover-letter Z\n \tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n \ttest_completion \"git send-email ma\" \"main \"\n '\n \n-- \n2.33.1\n\n"},{"id":"439600","messageId":"20211025212707.188151-3-tbperrotta@gmail.com","threadId":"56329","inReplyTo":"87fst7lkjx.fsf@evledraar.gmail.com","subject":"[PATCH v8 2/2] send-email docs: add format-patch options","fromName":"Thiago Perrotta","fromEmail":"tbperrotta@gmail.com","sentAt":"2021-10-25T21:27:07Z","receivedAt":"2021-10-25T21:27:27Z","isPatch":true,"sender":{"key":"tbperrotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2840106?v=4"},"body":"git-send-email(1) does not mention that \"git format-patch\" options are\naccepted. Augment SYNOPSIS and DESCRIPTION to mention it.\n\nUpdate git-send-email.perl USAGE to be consistent with\ngit-send-email(1).\n\nSigned-off-by: Thiago Perrotta <tbperrotta@gmail.com>\n---\n Documentation/git-send-email.txt | 6 ++++--\n git-send-email.perl              | 3 ++-\n 2 files changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 3db4eab4ba..41cd8cb424 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails\n SYNOPSIS\n --------\n [verse]\n-'git send-email' [<options>] <file|directory|rev-list options>...\n+'git send-email' [<options>] <file|directory>...\n+'git send-email' [<options>] <format-patch options>\n 'git send-email' --dump-aliases\n \n \n@@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.\n Patches can be specified as files, directories (which will send all\n files in the directory), or directly as a revision list.  In the\n last case, any format accepted by linkgit:git-format-patch[1] can\n-be passed to git send-email.\n+be passed to git send-email, as well as options understood by\n+linkgit:git-format-patch[1].\n \n The header of the email is configurable via command-line options.  If not\n specified on the command line, the user will be prompted with a ReadLine\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex b45c7da3ab..ace2dbca1a 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -40,7 +40,8 @@ package main;\n \n sub usage {\n \tprint <<EOT;\n-git send-email [options] <file | directory | rev-list options >\n+git send-email' [<options>] <file|directory>\n+git send-email' [<options>] <format-patch options>\n git send-email --dump-aliases\n \n   Composing:\n-- \n2.33.1\n\n"},{"id":"439612","messageId":"211026.86o87c1zry.gmgdl@evledraar.gmail.com","threadId":"56329","inReplyTo":"20211025212707.188151-1-tbperrotta@gmail.com","subject":"Re: [PATCH v8 0/2] send-email: shell completion improvements","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-25T22:44:37Z","receivedAt":"2021-10-25T22:54:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Oct 25 2021, Thiago Perrotta wrote:\n\n>> ...I think that re-indentation is better left alone for the patch\n>> readability.\n>\n> Reverted the `GetOptions` indentation. Noise is now gone :-)\n\nThanks.\n\n>> First, in your 1/3 you're adding a \\n, but in 2/3 we end up with \\n\\n. I\n>> think you can just skip 1/3, maybe mention \"how it also has a \"\\n\" in\n>> the commit message.\n>\n> I don't quite see how this would fit into the commit message. A comment in the\n> code seems to fit better to account for this detail. That's what I did, but if\n> you still disagree, please elaborate where in the commit message this sentence\n> should be added.\n\nMakes sense I think, will take a look.\n\n>> You then strip out \"--\" arguments from the combined list, but isn't this\n>> something we do need to emit? I.e. it's used as syntax by the bash\n>> completion isn't it? (I just skimmed the relevant C code in\n>> parse-options.c).\n>\n> I interpreted that standalone `--` as an extraneous / useless token. If it's\n> there intentionally, then I am reverting my stripping of it. At the end of the\n> day whether to include it or not is a small detail, but FYI, when I do:\n>\n>   $ git clone -<TAB>\n>\n> in bash, nothing happens. I would have expected it to be expanded to \"--\"\n> because of the explicit \"--\", but it doesn't. Therefore my conclusion is that\n> \"--\" in the output of \"--git-completion-helper\" is useless. Am I missing\n> something? What would be the function of the standalone \"--\" then?\n>\n> From my local testing, whether the options are sorted or not, whether\n> they are repeated or not, whether they follow a specific order with\n> respect to \"--\" or not, all of those details seem not to matter. Bash\n> completion seems to handle all of those cases just fine interactively.\n\nDigging a bit more: It's for folding away options that are negated, not\nfor completing \"-<TAB>\". See the examples at b221b5ab9b9 (completion:\ncollapse extra --no-.. options, 2018-06-06).\n\n> In fact, here's another example:\n>\n> $ git init --git-completion-helper | tr ' ' '\\n'  | grep -C1 '^--$'\n> --no-template\n> --\n> --no-bare\n>\n> ...there are --no-* options both _before_ and _after_ the --. I really\n> cannot see the point of the -- in the output, it seems to be just noise.\n\nRight, because some --no-whatever we define because we've got a\n--whatever and it's boolean, but for others we've got a --no-whatever as\nthe primary, as in th case of --no-template..\n\n> I readded -- to the output anyway since you requested it, but if it\n> needs to follow a certain spec w.r.t. ordering, we should have tests for\n> it. This specific part (the -- and the --no- order thing) of the commit\n> is something I am not keen to doing though, at least not in this patch\n> series; sorry, it already goes far beyond the scope of my original\n> intent. Anything else you ask for that is inline with the original\n> intent (like generating options programatically instead of hard-coding\n> them) I am fine with though, and in fact I believe I have addressed all\n> comments so far, if there's anything else I may have missed let me know.\n\nYeah sorry about the confusion so far, it's also been a voyage of\ndiscovery for me :)\n\nThis time around I tested with:\n\ndiff --git a/parse-options.c b/parse-options.c\nindex 6e0535bdaad..d659309c5e7 100644\n--- a/parse-options.c\n+++ b/parse-options.c\n@@ -515,8 +515,6 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,\n static void show_negated_gitcomp(const struct option *opts, int show_all,\n                                 int nr_noopts)\n {\n-       int printed_dashdash = 0;\n-\n        for (; opts->type != OPTION_END; opts++) {\n                int has_unset_form = 0;\n                const char *name;\n@@ -551,10 +549,6 @@ static void show_negated_gitcomp(const struct option *opts, int show_all,\n                        if (nr_noopts < 0)\n                                printf(\" --%s\", name);\n                } else if (nr_noopts >= 0) {\n-                       if (nr_noopts && !printed_dashdash) {\n-                               printf(\" --\");\n-                               printed_dashdash = 1;\n-                       }\n                        printf(\" --no-%s\", opts->long_name);\n                        nr_noopts++;\n                }\n\nWhich will fail a test in t/t9902-completion.sh showing this specific\nbehavior.\n"},{"id":"439616","messageId":"211026.86k0i01u3c.gmgdl@evledraar.gmail.com","threadId":"56329","inReplyTo":"211026.86o87c1zry.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v8 0/2] send-email: shell completion improvements","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-26T00:48:02Z","receivedAt":"2021-10-26T00:57:16Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Oct 26 2021, Ævar Arnfjörð Bjarmason wrote:\n\n> On Mon, Oct 25 2021, Thiago Perrotta wrote:\n>\n>>> ...I think that re-indentation is better left alone for the patch\n>>> readability.\n>>\n>> Reverted the `GetOptions` indentation. Noise is now gone :-)\n>\n> Thanks.\n>\n>>> First, in your 1/3 you're adding a \\n, but in 2/3 we end up with \\n\\n. I\n>>> think you can just skip 1/3, maybe mention \"how it also has a \"\\n\" in\n>>> the commit message.\n>>\n>> I don't quite see how this would fit into the commit message. A comment in the\n>> code seems to fit better to account for this detail. That's what I did, but if\n>> you still disagree, please elaborate where in the commit message this sentence\n>> should be added.\n>\n> Makes sense I think, will take a look.\n>\n>>> You then strip out \"--\" arguments from the combined list, but isn't this\n>>> something we do need to emit? I.e. it's used as syntax by the bash\n>>> completion isn't it? (I just skimmed the relevant C code in\n>>> parse-options.c).\n>>\n>> I interpreted that standalone `--` as an extraneous / useless token. If it's\n>> there intentionally, then I am reverting my stripping of it. At the end of the\n>> day whether to include it or not is a small detail, but FYI, when I do:\n>>\n>>   $ git clone -<TAB>\n>>\n>> in bash, nothing happens. I would have expected it to be expanded to \"--\"\n>> because of the explicit \"--\", but it doesn't. Therefore my conclusion is that\n>> \"--\" in the output of \"--git-completion-helper\" is useless. Am I missing\n>> something? What would be the function of the standalone \"--\" then?\n>>\n>> From my local testing, whether the options are sorted or not, whether\n>> they are repeated or not, whether they follow a specific order with\n>> respect to \"--\" or not, all of those details seem not to matter. Bash\n>> completion seems to handle all of those cases just fine interactively.\n>\n> Digging a bit more: It's for folding away options that are negated, not\n> for completing \"-<TAB>\". See the examples at b221b5ab9b9 (completion:\n> collapse extra --no-.. options, 2018-06-06).\n>\n>> In fact, here's another example:\n>>\n>> $ git init --git-completion-helper | tr ' ' '\\n'  | grep -C1 '^--$'\n>> --no-template\n>> --\n>> --no-bare\n>>\n>> ...there are --no-* options both _before_ and _after_ the --. I really\n>> cannot see the point of the -- in the output, it seems to be just noise.\n>\n> Right, because some --no-whatever we define because we've got a\n> --whatever and it's boolean, but for others we've got a --no-whatever as\n> the primary, as in th case of --no-template..\n>\n>> I readded -- to the output anyway since you requested it, but if it\n>> needs to follow a certain spec w.r.t. ordering, we should have tests for\n>> it. This specific part (the -- and the --no- order thing) of the commit\n>> is something I am not keen to doing though, at least not in this patch\n>> series; sorry, it already goes far beyond the scope of my original\n>> intent. Anything else you ask for that is inline with the original\n>> intent (like generating options programatically instead of hard-coding\n>> them) I am fine with though, and in fact I believe I have addressed all\n>> comments so far, if there's anything else I may have missed let me know.\n>\n> Yeah sorry about the confusion so far, it's also been a voyage of\n> discovery for me :)\n>\n> This time around I tested with:\n>\n> diff --git a/parse-options.c b/parse-options.c\n> index 6e0535bdaad..d659309c5e7 100644\n> --- a/parse-options.c\n> +++ b/parse-options.c\n> @@ -515,8 +515,6 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,\n>  static void show_negated_gitcomp(const struct option *opts, int show_all,\n>                                  int nr_noopts)\n>  {\n> -       int printed_dashdash = 0;\n> -\n>         for (; opts->type != OPTION_END; opts++) {\n>                 int has_unset_form = 0;\n>                 const char *name;\n> @@ -551,10 +549,6 @@ static void show_negated_gitcomp(const struct option *opts, int show_all,\n>                         if (nr_noopts < 0)\n>                                 printf(\" --%s\", name);\n>                 } else if (nr_noopts >= 0) {\n> -                       if (nr_noopts && !printed_dashdash) {\n> -                               printf(\" --\");\n> -                               printed_dashdash = 1;\n> -                       }\n>                         printf(\" --no-%s\", opts->long_name);\n>                         nr_noopts++;\n>                 }\n>\n> Which will fail a test in t/t9902-completion.sh showing this specific\n> behavior.\n\nFWIW I came up with the below on top while testing this. I think your\npatch series is fine and we should just take it as-is.\n\nThis edge case of \"--no\" behavior isn't something we support in any\nsensible way already, so it can just be left for later.\n\nBut since I think I gave you some bad advice and WIP code (sorry!) early\non I think this is closer to a 1=1 mapping to parse-options.c behavior,\ni.e. we split up \"no\" and \"non-no\" options, put them on either side of\nthe \"--\", but are careful to put /some/ \"--no\" options on the RHS.\n\nThis has at least one bug: A few options have e.g. --no-to= and --no-to,\nso both \"=\" and \"\" forms.\n\nThere's also some unrelated fixes there, e.g. the existing\n--dump-aliases behavior was kind of dumb for what it was trying to do,\nand I changed it since it got in the way of hacking this up.\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 04087221aa7..9d6cdf52cc3 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -120,32 +120,87 @@ sub uniq {\n }\n \n sub completion_helper {\n-\tmy ($original_opts) = @_;\n-\tmy %not_for_completion = (\n-\t\t\"git-completion-helper\" => undef,\n-\t\t\"h\" => undef,\n+\tmy ($options, $no_opt) = @_;\n+\n+\tmy %fp_opt_types;\n+\tmy (@fp_pos_opt, @fp_neg_opt);\n+\tmy $saw_dashdash = 0;\n+\tmy $fp_gch = Git::command('format-patch', '--git-completion-helper');\n+\tfor my $opt (split ' ', $fp_gch) {\n+\t\tif ($opt eq '--') {\n+\t\t\t$saw_dashdash = 1;\n+\t\t\tnext;\n+\t\t}\n+\t\t$opt =~ s/^--//;\n+\t\tmy $str = $opt =~ s/=$//;\n+\t\tif ($saw_dashdash) {\n+\t\t\tpush @fp_neg_opt => $opt;\n+\t\t} else {\n+\t\t\tpush @fp_pos_opt => $opt;\n+\t\t}\n+\t\t$fp_opt_types{$opt} = $str ? '=' : '';\n+\t}\n+\n+\t## Parse options according to Getopt::Long specifications. See\n+\t## \"perldoc Getopt::Long\".\n+\tmy %se_opt_types;\n+\tmy (@se_pos_opt, @se_neg_opt);\n+\tfor my $item ([$options, \\@se_pos_opt], [$no_opt, \\@se_neg_opt]) {\n+\t\tmy ($orig, $new) = @$item;\n+\t\t@$new = map {\n+\t\t\tmy $type;\n+\t\t\t$type = '' if !$type && s/\\!$//;\n+\t\t\t$type = '=' if !$type && s/[=:][sid]$//;\n+\t\t\t$type = '' if !$type; # the default\n+\t\t\t# We don't handle all possible Getopt::Long argument specifications\n+\t\t\tdie \"BUG: unknown argument specification for $_\" if /[=:+]/;\n+\t\t\t$se_opt_types{$_} = $type for split /\\|/;\n+\t\t\tsplit /\\|/;\n+\t\t} keys %$orig;\n+\t}\n+\n+\t## Sanity check that format-patch options and send-email\n+\t## options don't clash. We have existing conflicts, but should\n+\t## not be adding more.\n+\tmy %conflicting;\n+\tmy @conflicting = qw(\n+\t\tcc\n+\t\tfrom\n+\t\tin-reply-to\n+\t\tno-cc\n+\t\tno-thread\n+\t\tno-to\n+\t\tquiet\n+\t\tthread\n+\t\tto\n \t);\n-\tmy @send_email_opts = ();\n-\n-\tforeach my $key (keys %$original_opts) {\n-\t\tunless (exists $not_for_completion{$key}) {\n-\t\t\t$key =~ s/!$//;\n+\t@conflicting{@conflicting} = ();\n+\tfor my $opt (@fp_neg_opt, @fp_pos_opt) {\n+\t\tnext unless exists $se_opt_types{$opt};\n+\t\tnext if exists $conflicting{$opt};\n+\t\twarn \"BUG: have a format-patch option '$opt' clashing with send-email\";\n+\t}\n \n-\t\t\tif ($key =~ /[:=][si]$/) {\n-\t\t\t\t$key =~ s/[:=][si]$//;\n-\t\t\t\tpush (@send_email_opts, \"--$_=\") foreach (split (/\\|/, $key));\n-\t\t\t} else {\n-\t\t\t\tpush (@send_email_opts, \"--$_\") foreach (split (/\\|/, $key));\n-\t\t\t}\n-\t\t}\n+\t## Sanity check that for a --no-foo we have a positive --foo\n+\tmy @se_bool_neg_opt = grep { /^no-/ and $se_opt_types{$_} eq '' } keys %se_opt_types;\n+\tfor my $opt (sort @se_bool_neg_opt) {\n+\t\tmy $pos = $opt; $pos =~ s/^no-//;\n+\t\tnext if exists $se_opt_types{$pos};\n+\t\tdie \"BUG: Should have a '$pos' corresponding to '$opt'\";\n \t}\n \n-\tmy @format_patch_opts = split(/ /, Git::command('format-patch', '--git-completion-helper'));\n-\tmy @opts = (@send_email_opts, @format_patch_opts);\n-\t@opts = uniq (grep !/^$/, @opts);\n-\t# There's an implicit '\\n' here already, no need to add an explicit one.\n-\tprint \"@opts\";\n-\texit(0);\n+\tmy @pos_opts = sort(\n+\t\tmap({ \"--$_$fp_opt_types{$_}\" } @fp_pos_opt),\n+\t\tmap({ \"--$_$se_opt_types{$_}\" } @se_pos_opt),\n+\t);\n+\tmy @neg_opts = sort(\n+\t\tmap({ \"--$_$fp_opt_types{$_}\" } @fp_neg_opt),\n+\t\tmap({ \"--$_$se_opt_types{$_}\" } @se_neg_opt),\n+\t);\n+\tmy @all_opts = (uniq(@pos_opts), \"--\", uniq(@neg_opts));\n+\n+\tprint \"@all_opts\\n\";\n+\texit;\n }\n \n # most mail servers generate the Date: header, but not all...\n@@ -470,20 +525,14 @@ sub config_regexp {\n     read_config(\\%known_config_keys, \\%configured, \"sendemail\");\n }\n \n-# Begin by accumulating all the variables (defined above), that we will end up\n-# needing, first, from the command line:\n-\n-my $help;\n-my $git_completion_helper;\n-my %dump_aliases_options = (\n-\t\"h\" => \\$help,\n-\t\"dump-aliases\" => \\$dump_aliases,\n+my $help = 0;\n+my $git_completion_helper = 0;\n+my %options_no_completion = (\n+\t\t    \"h\" => \\$help,\n+\t\t    \"git-completion-helper\" => \\$git_completion_helper,\n );\n-$rc = GetOptions(%dump_aliases_options);\n-usage() unless $rc;\n-die __(\"--dump-aliases incompatible with other options\\n\")\n-    if !$help and $dump_aliases and @ARGV;\n my %options = (\n+\t\t    \"dump-aliases\" => \\$dump_aliases,\n \t\t    \"sender|from=s\" => \\$sender,\n \t\t    \"in-reply-to=s\" => \\$initial_in_reply_to,\n \t\t    \"reply-to=s\" => \\$reply_to,\n@@ -528,9 +577,7 @@ sub config_regexp {\n \t\t    \"dry-run\" => \\$dry_run,\n \t\t    \"envelope-sender=s\" => \\$envelope_sender,\n \t\t    \"thread!\" => \\$thread,\n-\t\t    \"no-thread\" => sub {$thread = 0},\n \t\t    \"validate!\" => \\$validate,\n-\t\t    \"no-validate\" => sub {$validate = 0},\n \t\t    \"transfer-encoding=s\" => \\$target_xfer_encoding,\n \t\t    \"format-patch!\" => \\$format_patch,\n \t\t    \"no-format-patch\" => sub {$format_patch = 0},\n@@ -538,12 +585,23 @@ sub config_regexp {\n \t\t    \"compose-encoding=s\" => \\$compose_encoding,\n \t\t    \"force\" => \\$force,\n \t\t    \"xmailer!\" => \\$use_xmailer,\n-\t\t    \"no-xmailer\" => sub {$use_xmailer = 0},\n \t\t    \"batch-size=i\" => \\$batch_size,\n \t\t    \"relogin-delay=i\" => \\$relogin_delay,\n-\t\t    \"git-completion-helper\" => \\$git_completion_helper,\n );\n-$rc = GetOptions(%options);\n+# --no-* options that disable a default that's otherwise enabled by\n+# default. Matters for --git-completion-helper.\n+my %no_options = (\n+\t\t    \"no-thread\" => sub {$thread = 0},\n+\t\t    \"no-validate\" => sub {$validate = 0},\n+\t\t    \"no-xmailer\" => sub {$use_xmailer = 0},\n+);\n+my @ORIG_ARGV = @ARGV;\n+$rc = GetOptions(%options_no_completion, %options);\n+usage() unless $rc;\n+\n+# Option compatibility\n+die __(\"--dump-aliases incompatible with other options\\n\")\n+    if $dump_aliases and @ORIG_ARGV > 1;\n \n # Munge any \"either config or getopt, not both\" variables\n my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);\n@@ -551,11 +609,7 @@ sub config_regexp {\n my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);\n \n usage() if $help;\n-my %all_options = (%options, %dump_aliases_options, %identity_options);\n-completion_helper(\\%all_options) if $git_completion_helper;\n-unless ($rc) {\n-    usage();\n-}\n+completion_helper({%options, %identity_options}, \\%no_options) if $git_completion_helper;\n \n if ($forbid_sendmail_variables && grep { /^sendmail/s } keys %known_config_keys) {\n \tdie __(\"fatal: found configuration options for 'sendmail'\\n\" .\n"},{"id":"439892","messageId":"xmqqcznpt8kc.fsf@gitster.g","threadId":"56329","inReplyTo":"211026.86k0i01u3c.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH v8 0/2] send-email: shell completion improvements","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-10-28T16:31:31Z","receivedAt":"2021-10-28T16:31:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> FWIW I came up with the below on top while testing this. I think your\n> patch series is fine and we should just take it as-is.\n>\n> This edge case of \"--no\" behavior isn't something we support in any\n> sensible way already, so it can just be left for later.\n\nI was kind of surprised to see --no-suppress-from was among the\ncompletions offered by the new code (given that nothing special\ncases a boolean and adds --no-$_ variant to the output), but then\nfound that some options are listed with \"no-\" prefix, which is, eh,\n\"Yuck\" in the existing code, perhaps.\n\nBut I think this is good to take.  Let's apply it.\n\nThanks, both.\n"}]}