Git development
 help / color / mirror / Atom feed
From: "Wolfgang Faust" <contrib-git@wolfgangfaust.com>
To: git@vger.kernel.org
Cc: "Aditya Garg" <gargaditya08@live.com>
Subject: [PATCH] imap-send: add --draft to set IMAP \Draft flag
Date: Tue, 01 Sep 2026 17:13:21 -0700	[thread overview]
Message-ID: <761c3f1b-e280-48b1-a2ad-770b68be3434@slotpi01m90> (raw)

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>
---
 Documentation/git-imap-send.adoc |  9 ++++++++-
 git-curl-compat.h                |  8 ++++++++
 imap-send.c                      | 15 +++++++++++++--
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-imap-send.adoc b/Documentation/git-imap-send.adoc
index 1814d94491..cf415df45a 100644
--- a/Documentation/git-imap-send.adoc
+++ b/Documentation/git-imap-send.adoc
@@ -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.
 
diff --git a/git-curl-compat.h b/git-curl-compat.h
index dccdd4d6e5..032aaf7126 100644
--- a/git-curl-compat.h
+++ b/git-curl-compat.h
@@ -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
diff --git a/imap-send.c b/imap-send.c
index 0d16d02029..bf1d2cf74d 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -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) {
-- 
2.52.0


             reply	other threads:[~2026-09-02  0:14 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02  0:13 Wolfgang Faust [this message]
2026-09-02  3:25 ` [PATCH] imap-send: add --draft to set IMAP \Draft flag Junio C Hamano
2026-09-02  4:28   ` Wolfgang Faust
2026-09-02 14:37     ` Junio C Hamano
2026-09-03  5:42 ` Aditya Garg
2026-09-03 13:42   ` Junio C Hamano
2026-09-03 14:37     ` Aditya Garg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=761c3f1b-e280-48b1-a2ad-770b68be3434@slotpi01m90 \
    --to=contrib-git@wolfgangfaust.com \
    --cc=gargaditya08@live.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox