]> git.ipfire.org Git - thirdparty/git.git/commitdiff
send-email: add ability to send a copy of sent emails to an IMAP folder
authorAditya Garg <gargaditya08@live.com>
Tue, 12 Aug 2025 06:44:35 +0000 (06:44 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 12 Aug 2025 15:59:35 +0000 (08:59 -0700)
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 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@live.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/sendemail.adoc
Documentation/git-send-email.adoc
git-send-email.perl
imap-send.c

index 47223346579727d295df09505e3ad014227d4ef3..dd2dbc87a06f176fe0d8fce20906ccde752748e4 100644 (file)
@@ -88,6 +88,7 @@ sendemail.smtpServer::
 sendemail.smtpServerPort::
 sendemail.smtpServerOption::
 sendemail.smtpUser::
+sendemail.imapSentFolder::
 sendemail.thread::
 sendemail.transferEncoding::
 sendemail.validate::
index 5335502d68fc7b84889e48d66daefd65d48a5d47..d1c41a0dbd4c3f8e049f47a22b3ac01ce10e0e9c 100644 (file)
@@ -299,6 +299,18 @@ must be used for each option.
        commands and replies will be printed. Useful to debug TLS
        connection and authentication problems.
 
+--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.
+
 --batch-size=<num>::
        Some email servers (e.g. 'smtp.163.com') limit the number of emails to be
        sent per session (connection) and this will lead to a failure when
index 437f8ac46a85dd301ca01ddc6722ac9c1ec4c510..b3cc237baac2c106450e540a0f6377dc57b230d9 100755 (executable)
@@ -73,6 +73,8 @@ git send-email --translate-aliases
     --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.
 
     --batch-size            <int>  * send max <int> message per connection.
     --relogin-delay         <int>  * delay <int> seconds between two successive login.
@@ -200,7 +202,7 @@ my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/;
 
 # 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.
@@ -277,6 +279,7 @@ my ($smtp_server, $smtp_server_port, @smtp_server_options);
 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);
@@ -322,6 +325,7 @@ my %config_settings = (
     "smtpauth" => \$smtp_auth,
     "smtpbatchsize" => \$batch_size,
     "smtprelogindelay" => \$relogin_delay,
+    "imapsentfolder" => \$imap_sent_folder,
     "to" => \@config_to,
     "tocmd" => \$to_cmd,
     "cc" => \@config_cc,
@@ -527,6 +531,7 @@ my %options = (
                    "smtp-domain:s" => \$smtp_domain,
                    "smtp-auth=s" => \$smtp_auth,
                    "no-smtp-auth" => sub {$smtp_auth = 'none'},
+                   "imap-sent-folder=s" => \$imap_sent_folder,
                    "annotate!" => \$annotate,
                    "compose" => \$compose,
                    "quiet" => \$quiet,
@@ -1829,6 +1834,17 @@ EOF
                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;
 }
 
@@ -2223,6 +2239,19 @@ 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;
index f5a656ac71dc2db06e087f4bfce486418724284e..44de0c5a77e75ecccb28f734e56e9e579e4b42ce 100644 (file)
@@ -1441,14 +1441,24 @@ static int count_messages(struct strbuf *all_msgs)
 
        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)