Skip to content

Commit 7802fc9

Browse files
committed
Merge branch 'ag/send-email-imap-sent' into jch
"git send-email" learned to drive "git imap-send" to store already sent e-mails in an IMAP folder. Comments? * ag/send-email-imap-sent: 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
2 parents 403469d + 480f67f commit 7802fc9

File tree

4 files changed

+83
-10
lines changed

4 files changed

+83
-10
lines changed

Documentation/config/sendemail.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ sendemail.smtpServer::
8888
sendemail.smtpServerPort::
8989
sendemail.smtpServerOption::
9090
sendemail.smtpUser::
91+
sendemail.imapSentFolder::
92+
sendemail.useImapOnly::
9193
sendemail.thread::
9294
sendemail.transferEncoding::
9395
sendemail.validate::

Documentation/git-send-email.adoc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,31 @@ 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+
for instructions.
313+
314+
--[no-]use-imap-only::
315+
If this is set, all emails will only be copied to the IMAP folder specified
316+
with `--imap-sent-folder` or `sendemail.imapSentFolder` and will not be sent
317+
to the recipients. Useful if you just want to create a draft of the emails
318+
and use another email client to send them.
319+
If disabled with `--no-use-imap-only`, the emails will be sent like usual.
320+
Disabled by default, but the `sendemail.useImapOnly` configuration
321+
variable can be used to enable it.
322+
323+
+
324+
This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1]
325+
for instructions.
326+
302327
--batch-size=<num>::
303328
Some email servers (e.g. 'smtp.163.com') limit the number of emails to be
304329
sent per session (connection) and this will lead to a failure when

git-send-email.perl

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ sub usage {
6262
--smtp-user <str> * Username for SMTP-AUTH.
6363
--smtp-pass <str> * Password for SMTP-AUTH; not necessary.
6464
--smtp-encryption <str> * tls or ssl; anything else disables.
65-
--smtp-ssl * Deprecated. Use '--smtp-encryption ssl'.
65+
--smtp-ssl * Deprecated. Use `--smtp-encryption ssl`.
6666
--smtp-ssl-cert-path <str> * Path to ca-certificates (either directory or file).
6767
Pass an empty string to disable certificate
6868
verification.
@@ -73,6 +73,10 @@ 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 set up to use this feature.
78+
--[no-]use-imap-only * Only copy emails to the IMAP folder specified by
79+
`--imap-sent-folder` instead of actually sending them.
7680
7781
--batch-size <int> * send max <int> message per connection.
7882
--relogin-delay <int> * delay <int> seconds between two successive login.
@@ -200,7 +204,7 @@ sub format_2822_time {
200204

201205
# Variables we fill in automatically, or via prompting:
202206
my (@to,@cc,@xh,$envelope_sender,
203-
$initial_in_reply_to,$reply_to,$initial_subject,@files,
207+
$initial_in_reply_to,$reply_to,$initial_subject,@files,@imap_copy,
204208
$author,$sender,$smtp_authpass,$annotate,$compose,$time);
205209
# Things we either get from config, *or* are overridden on the
206210
# command-line.
@@ -277,6 +281,7 @@ sub do_edit {
277281
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
278282
my ($batch_size, $relogin_delay);
279283
my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
284+
my ($imap_sent_folder);
280285
my ($confirm);
281286
my (@suppress_cc);
282287
my ($auto_8bit_encoding);
@@ -293,6 +298,7 @@ sub do_edit {
293298
my $target_xfer_encoding = 'auto';
294299
my $forbid_sendmail_variables = 1;
295300
my $outlook_id_fix = 'auto';
301+
my $use_imap_only = 0;
296302

297303
my %config_bool_settings = (
298304
"thread" => \$thread,
@@ -309,6 +315,7 @@ sub do_edit {
309315
"forbidsendmailvariables" => \$forbid_sendmail_variables,
310316
"mailmap" => \$mailmap,
311317
"outlookidfix" => \$outlook_id_fix,
318+
"useimaponly" => \$use_imap_only,
312319
);
313320

314321
my %config_settings = (
@@ -322,6 +329,7 @@ sub do_edit {
322329
"smtpauth" => \$smtp_auth,
323330
"smtpbatchsize" => \$batch_size,
324331
"smtprelogindelay" => \$relogin_delay,
332+
"imapsentfolder" => \$imap_sent_folder,
325333
"to" => \@config_to,
326334
"tocmd" => \$to_cmd,
327335
"cc" => \@config_cc,
@@ -527,6 +535,8 @@ sub config_regexp {
527535
"smtp-domain:s" => \$smtp_domain,
528536
"smtp-auth=s" => \$smtp_auth,
529537
"no-smtp-auth" => sub {$smtp_auth = 'none'},
538+
"imap-sent-folder=s" => \$imap_sent_folder,
539+
"use-imap-only!" => \$use_imap_only,
530540
"annotate!" => \$annotate,
531541
"compose" => \$compose,
532542
"quiet" => \$quiet,
@@ -1678,6 +1688,8 @@ sub send_message {
16781688

16791689
if ($dry_run) {
16801690
# We don't want to send the email.
1691+
} elsif ($use_imap_only) {
1692+
die __("The destination IMAP folder is not properly defined.") if !defined $imap_sent_folder;
16811693
} elsif (defined $sendmail_cmd || file_name_is_absolute($smtp_server)) {
16821694
my $pid = open my $sm, '|-';
16831695
defined $pid or die $!;
@@ -1829,6 +1841,17 @@ sub send_message {
18291841
print "\n";
18301842
}
18311843

1844+
if ($imap_sent_folder && !$dry_run) {
1845+
my $imap_header = $header;
1846+
if (@initial_bcc) {
1847+
# Bcc is not a part of $header, so we add it here.
1848+
# This is only for the IMAP copy, not for the actual email
1849+
# sent to the recipients.
1850+
$imap_header .= "Bcc: " . join(", ", @initial_bcc) . "\n";
1851+
}
1852+
push @imap_copy, "From git-send-email\n$imap_header\n$message";
1853+
}
1854+
18321855
return 1;
18331856
}
18341857

@@ -2223,6 +2246,19 @@ sub cleanup_compose_files {
22232246

22242247
$smtp->quit if $smtp;
22252248

2249+
if ($imap_sent_folder && @imap_copy && !$dry_run) {
2250+
my $imap_input = join("\n", @imap_copy);
2251+
eval {
2252+
print "\nStarting git imap-send...\n";
2253+
my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_sent_folder]);
2254+
print $fh $imap_input;
2255+
Git::command_close_pipe($fh, $ctx);
2256+
1;
2257+
} or do {
2258+
warn "Warning: failed to send messages to IMAP folder $imap_sent_folder: $@";
2259+
};
2260+
}
2261+
22262262
sub apply_transfer_encoding {
22272263
my $message = shift;
22282264
my $from = shift;

imap-send.c

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

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

0 commit comments

Comments
 (0)