Merge branch 'wf/imap-send-draft'

The 'git imap-send' command has been taught to take the '--draft'
option to mark uploaded messages as drafts, which helps some email
clients render them properly for editing and sending.

* wf/imap-send-draft:
  imap-send: add --draft to set IMAP \Draft flag
main
Junio C Hamano 2026-09-14 14:02:52 -07:00
commit 88b068eb33
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) {