Skip to content

Commit 22b5050

Browse files
AdityaGarg8gitster
authored andcommitted
send-email: add ability to send a copy of sent emails to an IMAP folder
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 the all emails are sent via SMTP and the SMTP server has been closed. Signed-off-by: Aditya Garg <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3f2a948 commit 22b5050

File tree

4 files changed

+61
-9
lines changed

4 files changed

+61
-9
lines changed

Documentation/config/sendemail.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ sendemail.smtpServer::
8888
sendemail.smtpServerPort::
8989
sendemail.smtpServerOption::
9090
sendemail.smtpUser::
91+
sendemail.imapSentFolder::
9192
sendemail.thread::
9293
sendemail.transferEncoding::
9394
sendemail.validate::

Documentation/git-send-email.adoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,18 @@ must be used for each option.
299299
commands and replies will be printed. Useful to debug TLS
300300
connection and authentication problems.
301301

302+
--imap-sent-folder=<folder>::
303+
Some email providers (e.g. iCloud) do not send a copy of the emails sent
304+
using SMTP to the `Sent` folder or similar in your mailbox. Use this option
305+
to use `git imap-send` to send a copy of the emails to the folder specified
306+
using this option. You can run `git imap-send --list` to get a list of
307+
valid folder names, including the correct name of the `Sent` folder in
308+
your mailbox. You can also use this option to send emails to a dedicated
309+
IMAP folder of your choice.
310+
+
311+
This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1]
312+
to get instructions for the same.
313+
302314
--batch-size=<num>::
303315
Some email servers (e.g. 'smtp.163.com') limit the number of emails to be
304316
sent per session (connection) and this will lead to a failure when

git-send-email.perl

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ sub usage {
7373
--no-smtp-auth * Disable SMTP authentication. Shorthand for
7474
`--smtp-auth=none`
7575
--smtp-debug <0|1> * Disable, enable Net::SMTP debug.
76+
--imap-sent-folder <str> * IMAP folder where a copy of the emails should be sent.
77+
Make sure `git imap-send` is setup to use this feature.
7678
7779
--batch-size <int> * send max <int> message per connection.
7880
--relogin-delay <int> * delay <int> seconds between two successive login.
@@ -200,7 +202,7 @@ sub format_2822_time {
200202

201203
# Variables we fill in automatically, or via prompting:
202204
my (@to,@cc,@xh,$envelope_sender,
203-
$initial_in_reply_to,$reply_to,$initial_subject,@files,
205+
$initial_in_reply_to,$reply_to,$initial_subject,@files,@imap_copy,
204206
$author,$sender,$smtp_authpass,$annotate,$compose,$time);
205207
# Things we either get from config, *or* are overridden on the
206208
# command-line.
@@ -277,6 +279,7 @@ sub do_edit {
277279
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
278280
my ($batch_size, $relogin_delay);
279281
my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
282+
my ($imap_sent_folder);
280283
my ($confirm);
281284
my (@suppress_cc);
282285
my ($auto_8bit_encoding);
@@ -322,6 +325,7 @@ sub do_edit {
322325
"smtpauth" => \$smtp_auth,
323326
"smtpbatchsize" => \$batch_size,
324327
"smtprelogindelay" => \$relogin_delay,
328+
"imapsentfolder" => \$imap_sent_folder,
325329
"to" => \@config_to,
326330
"tocmd" => \$to_cmd,
327331
"cc" => \@config_cc,
@@ -527,6 +531,7 @@ sub config_regexp {
527531
"smtp-domain:s" => \$smtp_domain,
528532
"smtp-auth=s" => \$smtp_auth,
529533
"no-smtp-auth" => sub {$smtp_auth = 'none'},
534+
"imap-sent-folder=s" => \$imap_sent_folder,
530535
"annotate!" => \$annotate,
531536
"compose" => \$compose,
532537
"quiet" => \$quiet,
@@ -1829,6 +1834,17 @@ sub send_message {
18291834
print "\n";
18301835
}
18311836

1837+
if ($imap_sent_folder) {
1838+
my $imap_header = $header;
1839+
if (@initial_bcc) {
1840+
# Bcc is not a part of $header, so we add it here.
1841+
# This is only for the IMAP copy, not for the actual email
1842+
# sent to the recipients.
1843+
$imap_header .= "Bcc: " . join(", ", @initial_bcc) . "\n";
1844+
}
1845+
push @imap_copy, "From git-send-email\n$imap_header\n$message";
1846+
}
1847+
18321848
return 1;
18331849
}
18341850

@@ -2223,6 +2239,19 @@ sub cleanup_compose_files {
22232239

22242240
$smtp->quit if $smtp;
22252241

2242+
if ($imap_sent_folder && @imap_copy) {
2243+
my $imap_input = join("\n", @imap_copy);
2244+
eval {
2245+
print "\nStarting git imap-send...\n";
2246+
my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_sent_folder]);
2247+
print $fh $imap_input;
2248+
Git::command_close_pipe($fh, $ctx);
2249+
1;
2250+
} or do {
2251+
warn "Warning: failed to send messages to IMAP folder $imap_sent_folder: $@";
2252+
};
2253+
}
2254+
22262255
sub apply_transfer_encoding {
22272256
my $message = shift;
22282257
my $from = shift;

imap-send.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,14 +1441,24 @@ static int count_messages(struct strbuf *all_msgs)
14411441

14421442
while (1) {
14431443
if (starts_with(p, "From ")) {
1444-
p = strstr(p+5, "\nFrom: ");
1445-
if (!p) break;
1446-
p = strstr(p+7, "\nDate: ");
1447-
if (!p) break;
1448-
p = strstr(p+7, "\nSubject: ");
1449-
if (!p) break;
1450-
p += 10;
1451-
count++;
1444+
if (starts_with(p, "From git-send-email")) {
1445+
p = strstr(p+5, "\nFrom: ");
1446+
if (!p) break;
1447+
p += 7;
1448+
p = strstr(p, "\nTo: ");
1449+
if (!p) break;
1450+
p += 5;
1451+
count++;
1452+
} else {
1453+
p = strstr(p+5, "\nFrom: ");
1454+
if (!p) break;
1455+
p = strstr(p+7, "\nDate: ");
1456+
if (!p) break;
1457+
p = strstr(p+7, "\nSubject: ");
1458+
if (!p) break;
1459+
p += 10;
1460+
count++;
1461+
}
14521462
}
14531463
p = strstr(p+5, "\nFrom ");
14541464
if (!p)

0 commit comments

Comments
 (0)