imap-send: add --draft to set IMAP \Draft flag

The documented purpose of imap-send is to upload draft emails for sending
later, but it did not have any way to mark the messages as \Draft, so some
email clients presented the result as an un-editable, un-sendable email
even if it happened to be in a "Drafts" folder.

Signed-off-by: Wolfgang Faust <contrib-git@wolfgangfaust.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Wolfgang Faust 2026-09-01 17:13:21 -07:00 committed by Junio C Hamano
parent e9019fcafe
commit 609d2a8834
3 changed files with 29 additions and 3 deletions

View File

@ -9,7 +9,7 @@ git-imap-send - Send a collection of patches from stdin to an IMAP folder
SYNOPSIS
--------
[synopsis]
git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]
git imap-send [-v] [-q] [--[no-]curl] [--[no-]draft] [(--folder|-f) <folder>]
git imap-send --list


@ -55,6 +55,13 @@ OPTIONS
using libcurl. Ignored if Git was built with the NO_OPENSSL option
set.

`--draft`::
`--no-draft`::
Mark uploaded messages with the IMAP `\Draft` flag. The default is `--no-draft`.
+
With libcurl, `--draft` requires version 8.13.0 or later.
Older libcurl still uploads the message but cannot set the flag.

`--list`::
Run the IMAP LIST command to output a list of all the folders present.


View File

@ -67,4 +67,12 @@
#define GIT_CURL_HAVE_CURLOPT_TCP_KEEPCNT
#endif

/**
* CURLOPT_UPLOAD_FLAGS and CURLULFLAG_* were added in 8.13.0,
* released in April 2025.
*/
#if LIBCURL_VERSION_NUM >= 0x080D00
#define GIT_CURL_HAVE_CURLOPT_UPLOAD_FLAGS
#endif

#endif

View File

@ -35,6 +35,7 @@
#include "setup.h"
#include "strbuf.h"
#ifdef USE_CURL_FOR_IMAP_SEND
#include "git-curl-compat.h"
#include "http.h"
#endif

@ -49,10 +50,11 @@
static int verbosity;
static int list_folders;
static int use_curl = USE_CURL_DEFAULT;
static int opt_draft;
static char *opt_folder;

static char const * const imap_send_usage[] = {
N_("git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>"),
N_("git imap-send [-v] [-q] [--[no-]curl] [--[no-]draft] [(--folder|-f) <folder>] < <mbox>"),
"git imap-send --list",
NULL
};
@ -60,6 +62,7 @@ static char const * const imap_send_usage[] = {
static struct option imap_send_options[] = {
OPT__VERBOSITY(&verbosity),
OPT_BOOL(0, "curl", &use_curl, "use libcurl to communicate with the IMAP server"),
OPT_BOOL(0, "draft", &opt_draft, "mark uploaded messages with the IMAP \\Draft flag"),
OPT_STRING('f', "folder", &opt_folder, "folder", "specify the IMAP folder"),
OPT_BOOL(0, "list", &list_folders, "list all folders on the IMAP server"),
OPT_END()
@ -1416,7 +1419,8 @@ static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)

box = ctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" ", prefix, box);
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" %s", prefix, box,
opt_draft ? "(\\Draft) " : "");
imap->caps = imap->rcaps;
if (ret != DRV_OK)
return ret;
@ -1718,6 +1722,13 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server,

curl_easy_setopt(curl, CURLOPT_READDATA, &msgbuf);

if (opt_draft) {
#ifdef GIT_CURL_HAVE_CURLOPT_UPLOAD_FLAGS
curl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, CURLULFLAG_DRAFT);
#else
warning("--draft requires libcurl 8.13.0 or later");
#endif
}
fprintf(stderr, "Sending %d message%s to %s folder...\n",
total, (total != 1) ? "s" : "", server->folder);
while (1) {