Hi all This patch series introduces integration of `git send-email` with `git imap-send`. The first patch adds the ability to send a copy of sent emails to an IMAP folder specified by the user, which is useful for email providers that do not support sending a copy of sent emails to the "Sent" folder via SMTP. The second patch allows users to copy emails to an IMAP folder without actually sending them. v2 - Fix indentation in patch for imap-send.c - Minor edits to commit message v3 - Rename imap folder to imap sent folder - Make an error message shorter by removing unecessary details v4 - Fix a bug causing emails to be copied to an IMAP folder even if --dry-run is specified. - Minor edits to commit messages and docs. - Add another patch that enables copying emails to an IMAP folder without actually sending them. v5 - Avoid using -[no-]parameter. Aditya Garg (2): send-email: add ability to send a copy of sent emails to an IMAP folder send-email: enable copying emails to an IMAP folder without actually sending them Documentation/config/sendemail.adoc | 2 ++ Documentation/git-send-email.adoc | 26 +++++++++++++++++++ git-send-email.perl | 40 +++++++++++++++++++++++++++-- imap-send.c | 26 +++++++++++++------ 4 files changed, 84 insertions(+), 10 deletions(-) Range-diff against v4: 1: 2ad311502d ! 1: 27b5eb33bb send-email: enable copying emails to IMAP folder without actually sending them @@ Metadata Author: Aditya Garg <gargaditya08@xxxxxxxx> ## Commit message ## - send-email: enable copying emails to IMAP folder without actually sending them + send-email: add ability to send a copy of sent emails to an IMAP folder - `git imap-send` was built on the idea of copying emails to an IMAP folder - like drafts, and sending them later using an email client. Currently - the only way to do it is by piping output of `git format-patch` to IMAP - send. + Some email providers like Apple iCloud Mail do not support sending a copy + of sent emails to the "Sent" folder if SMTP server is used. As a + workaround, various email clients like Thunderbird which rely on SMTP, + use IMAP to send a copy of sent emails to the "Sent" folder. Something + similar can be done if sending emails via `git send-email`, by using + the `git imap-send` command to send a copy of the sent email to an IMAP + folder specified by the user. - Add another way to do it by using `git send-email` with the - `--use-imap-only` or `sendmail.useImapOnly` option. This allows users to - use the advanced features of `git send-email` like tweaking Cc: list - programmatically, compose the cover letter, etc. and then send the well - formatted emails to an IMAP folder using `git imap-send`. - - While at it, use `` instead of '' for --smtp-encryption ssl in help - section of `git send-email`. + Add this functionality to `git send-email` by introducing a new + configuration variable `sendemail.imapfolder` and command line option + `--imap-folder` which specifies the IMAP folder to send a copy of the + sent emails to. If specified, a copy of the sent emails will be sent + by piping the emails to `git imap-send` command, after all emails are + sent via SMTP and the SMTP server has been closed. Signed-off-by: Aditya Garg <gargaditya08@xxxxxxxx> ## Documentation/config/sendemail.adoc ## -@@ Documentation/config/sendemail.adoc: sendemail.smtpServerPort:: +@@ Documentation/config/sendemail.adoc: sendemail.smtpServer:: + sendemail.smtpServerPort:: sendemail.smtpServerOption:: sendemail.smtpUser:: - sendemail.imapSentFolder:: -+sendemail.useImapOnly:: ++sendemail.imapSentFolder:: sendemail.thread:: sendemail.transferEncoding:: sendemail.validate:: ## Documentation/git-send-email.adoc ## @@ Documentation/git-send-email.adoc: must be used for each option. - This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1] - for instructions. + commands and replies will be printed. Useful to debug TLS + connection and authentication problems. -+--[no-]use-imap-only:: -+ If this is set, all emails will only be copied to the IMAP folder specified -+ with `--imap-sent-folder` or `sendemail.imapSentFolder` and will not be sent -+ to the recipients. Useful if you just want to create a draft of the emails -+ and use another email client to send them. -+ If disabled with `--no-use-imap-only`, the emails will be sent like usual. -+ Disabled by default, but the `sendemail.useImapOnly` configuration -+ variable can be used to enable it. -+ ++--imap-sent-folder=<folder>:: ++ Some email providers (e.g. iCloud) do not send a copy of the emails sent ++ using SMTP to the `Sent` folder or similar in your mailbox. Use this option ++ to use `git imap-send` to send a copy of the emails to the folder specified ++ using this option. You can run `git imap-send --list` to get a list of ++ valid folder names, including the correct name of the `Sent` folder in ++ your mailbox. You can also use this option to send emails to a dedicated ++ IMAP folder of your choice. ++ +This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1] +for instructions. @@ Documentation/git-send-email.adoc: must be used for each option. ## git-send-email.perl ## @@ git-send-email.perl: sub usage { - --smtp-user <str> * Username for SMTP-AUTH. - --smtp-pass <str> * Password for SMTP-AUTH; not necessary. - --smtp-encryption <str> * tls or ssl; anything else disables. -- --smtp-ssl * Deprecated. Use '--smtp-encryption ssl'. -+ --smtp-ssl * Deprecated. Use `--smtp-encryption ssl`. - --smtp-ssl-cert-path <str> * Path to ca-certificates (either directory or file). - Pass an empty string to disable certificate - verification. -@@ git-send-email.perl: sub usage { + --no-smtp-auth * Disable SMTP authentication. Shorthand for + `--smtp-auth=none` --smtp-debug <0|1> * Disable, enable Net::SMTP debug. - --imap-sent-folder <str> * IMAP folder where a copy of the emails should be sent. - Make sure `git imap-send` is set up to use this feature. -+ --[no-]use-imap-only * Only copy emails to the IMAP folder specified by -+ `--imap-sent-folder` instead of actually sending them. ++ --imap-sent-folder <str> * IMAP folder where a copy of the emails should be sent. ++ Make sure `git imap-send` is set up to use this feature. --batch-size <int> * send max <int> message per connection. --relogin-delay <int> * delay <int> seconds between two successive login. -@@ git-send-email.perl: sub do_edit { - my $target_xfer_encoding = 'auto'; - my $forbid_sendmail_variables = 1; - my $outlook_id_fix = 'auto'; -+my $use_imap_only = 0; +@@ git-send-email.perl: sub format_2822_time { - my %config_bool_settings = ( - "thread" => \$thread, + # Variables we fill in automatically, or via prompting: + my (@to,@cc,@xh,$envelope_sender, +- $initial_in_reply_to,$reply_to,$initial_subject,@files, ++ $initial_in_reply_to,$reply_to,$initial_subject,@files,@imap_copy, + $author,$sender,$smtp_authpass,$annotate,$compose,$time); + # Things we either get from config, *or* are overridden on the + # command-line. @@ git-send-email.perl: sub do_edit { - "forbidsendmailvariables" => \$forbid_sendmail_variables, - "mailmap" => \$mailmap, - "outlookidfix" => \$outlook_id_fix, -+ "useimaponly" => \$use_imap_only, - ); - - my %config_settings = ( + my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path); + my ($batch_size, $relogin_delay); + my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth); ++my ($imap_sent_folder); + my ($confirm); + my (@suppress_cc); + my ($auto_8bit_encoding); +@@ git-send-email.perl: sub do_edit { + "smtpauth" => \$smtp_auth, + "smtpbatchsize" => \$batch_size, + "smtprelogindelay" => \$relogin_delay, ++ "imapsentfolder" => \$imap_sent_folder, + "to" => \@config_to, + "tocmd" => \$to_cmd, + "cc" => \@config_cc, @@ git-send-email.perl: sub config_regexp { + "smtp-domain:s" => \$smtp_domain, "smtp-auth=s" => \$smtp_auth, "no-smtp-auth" => sub {$smtp_auth = 'none'}, - "imap-sent-folder=s" => \$imap_sent_folder, -+ "use-imap-only!" => \$use_imap_only, ++ "imap-sent-folder=s" => \$imap_sent_folder, "annotate!" => \$annotate, "compose" => \$compose, "quiet" => \$quiet, @@ git-send-email.perl: sub send_message { + print "\n"; + } + ++ if ($imap_sent_folder && !$dry_run) { ++ my $imap_header = $header; ++ if (@initial_bcc) { ++ # Bcc is not a part of $header, so we add it here. ++ # This is only for the IMAP copy, not for the actual email ++ # sent to the recipients. ++ $imap_header .= "Bcc: " . join(", ", @initial_bcc) . "\n"; ++ } ++ push @imap_copy, "From git-send-email\n$imap_header\n$message"; ++ } ++ + return 1; + } + +@@ git-send-email.perl: sub cleanup_compose_files { + + $smtp->quit if $smtp; + ++if ($imap_sent_folder && @imap_copy && !$dry_run) { ++ my $imap_input = join("\n", @imap_copy); ++ eval { ++ print "\nStarting git imap-send...\n"; ++ my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_sent_folder]); ++ print $fh $imap_input; ++ Git::command_close_pipe($fh, $ctx); ++ 1; ++ } or do { ++ warn "Warning: failed to send messages to IMAP folder $imap_sent_folder: $@"; ++ }; ++} ++ + sub apply_transfer_encoding { + my $message = shift; + my $from = shift; + + ## imap-send.c ## +@@ imap-send.c: static int count_messages(struct strbuf *all_msgs) - if ($dry_run) { - # We don't want to send the email. -+ } elsif ($use_imap_only) { -+ die __("The destination IMAP folder is not properly defined.") if !defined $imap_sent_folder; - } elsif (defined $sendmail_cmd || file_name_is_absolute($smtp_server)) { - my $pid = open my $sm, '|-'; - defined $pid or die $!; + while (1) { + if (starts_with(p, "From ")) { +- p = strstr(p+5, "\nFrom: "); +- if (!p) break; +- p = strstr(p+7, "\nDate: "); +- if (!p) break; +- p = strstr(p+7, "\nSubject: "); +- if (!p) break; +- p += 10; +- count++; ++ if (starts_with(p, "From git-send-email")) { ++ p = strstr(p+5, "\nFrom: "); ++ if (!p) break; ++ p += 7; ++ p = strstr(p, "\nTo: "); ++ if (!p) break; ++ p += 5; ++ count++; ++ } else { ++ p = strstr(p+5, "\nFrom: "); ++ if (!p) break; ++ p = strstr(p+7, "\nDate: "); ++ if (!p) break; ++ p = strstr(p+7, "\nSubject: "); ++ if (!p) break; ++ p += 10; ++ count++; ++ } + } + p = strstr(p+5, "\nFrom "); + if (!p) -: ---------- > 2: 1d74a857df send-email: enable copying emails to an IMAP folder without actually sending them -- 2.50.1