{"thread":{"id":"63831","subject":"[PATCH] imap-send: add option to mark sent messages as read or unread","startedAt":"2025-07-23T12:29:15Z","lastAt":"2025-07-23T18:00:20Z","messageCount":8,"participants":["Aditya Garg","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"522545","messageId":"7108764f437a25079c95a25c227eb79f9f4aee6a.1753273554.git.gargaditya08@live.com","threadId":"63831","inReplyTo":null,"subject":"[PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-07-23T12:29:10Z","receivedAt":"2025-07-23T12:29:15Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"The current behaviour of `git imap-send` is to mark sent messages as read\nif curl is used, and unread if OpenSSL is used.\n\nFix this inconsistency by marking the message as read by default in both\ncases. Also introduce `--[no-]mark-as-read` and `imap.markAsRead` option\nto allow users to change this behaviour.\n\nWhile at it, also clarify that `imap.folder` will be used if --folder is\nnot specified.\n\nSigned-off-by: Aditya Garg <gargaditya08@live.com>\n---\n Documentation/config/imap.adoc   |  4 ++++\n Documentation/git-imap-send.adoc | 10 +++++++++-\n imap-send.c                      | 18 ++++++++++++++++--\n 3 files changed, 29 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config/imap.adoc b/Documentation/config/imap.adoc\nindex 4682a6bd03..afae49391c 100644\n--- a/Documentation/config/imap.adoc\n+++ b/Documentation/config/imap.adoc\n@@ -45,3 +45,7 @@ imap.authMethod::\n \toption, the only supported methods are `PLAIN`, `CRAM-MD5`, `OAUTHBEARER`\n \tand `XOAUTH2`. If this is not set then `git imap-send` uses the basic IMAP\n \tplaintext `LOGIN` command.\n+\n+imap.markAsRead::\n+\tChoose whether to mark the sent message as read or not.\n+\tDefault is `true`.\ndiff --git a/Documentation/git-imap-send.adoc b/Documentation/git-imap-send.adoc\nindex 17147f93c3..3976c128c7 100644\n--- a/Documentation/git-imap-send.adoc\n+++ b/Documentation/git-imap-send.adoc\n@@ -9,7 +9,7 @@ git-imap-send - Send a collection of patches from stdin to an IMAP folder\n SYNOPSIS\n --------\n [verse]\n-'git imap-send' [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]\n+'git imap-send' [-v] [-q] [--[no-]curl] [--[no-]mark-as-read] [(--folder|-f) <folder>]\n 'git imap-send' --list\n \n \n@@ -44,6 +44,8 @@ OPTIONS\n --folder=<folder>::\n \tSpecify the folder in which the emails have to saved.\n \tFor example: `--folder=[Gmail]/Drafts` or `-f INBOX/Drafts`.\n+\tIf not specified, the folder assigned using `imap.folder`\n+\twill be used.\n \n --curl::\n \tUse libcurl to communicate with the IMAP server, unless tunneling\n@@ -58,6 +60,12 @@ OPTIONS\n --list::\n \tRun the IMAP LIST command to output a list of all the folders present.\n \n+--[no-]mark-as-read::\n+\tChoose whether to mark the sent message as read or not.\n+\t`--mark-as-read` will mark the message as read, and `--no-mark-as-read`\n+\twill mark it as unread. If not specified, the default behaviour will\n+\tbe decided by the value of `imap.markAsRead`.\n+\n CONFIGURATION\n -------------\n \ndiff --git a/imap-send.c b/imap-send.c\nindex 44de0c5a77..a242119164 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -47,11 +47,12 @@\n \n static int verbosity;\n static int list_folders;\n+static int mark_seen = 1;\n static int use_curl = USE_CURL_DEFAULT;\n static char *opt_folder;\n \n static char const * const imap_send_usage[] = {\n-\tN_(\"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>\"),\n+\tN_(\"git imap-send [-v] [-q] [--[no-]curl] [--[no-]mark-as-read] [(--folder|-f) <folder>] < <mbox>\"),\n \t\"git imap-send --list\",\n \tNULL\n };\n@@ -61,6 +62,7 @@ static struct option imap_send_options[] = {\n \tOPT_BOOL(0, \"curl\", &use_curl, \"use libcurl to communicate with the IMAP server\"),\n \tOPT_STRING('f', \"folder\", &opt_folder, \"folder\", \"specify the IMAP folder\"),\n \tOPT_BOOL(0, \"list\", &list_folders, \"list all folders on the IMAP server\"),\n+\tOPT_BOOL(0, \"mark-as-read\", &mark_seen, \"mark messages as read after sending\"),\n \tOPT_END()\n };\n \n@@ -1402,7 +1404,11 @@ static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)\n \n \tbox = ctx->name;\n \tprefix = !strcmp(box, \"INBOX\") ? \"\" : ctx->prefix;\n-\tret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" \", prefix, box);\n+\tif (mark_seen) {\n+\t\tret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" (\\\\Seen) \", prefix, box);\n+\t} else {\n+\t\tret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" \", prefix, box);\n+\t}\n \timap->caps = imap->rcaps;\n \tif (ret != DRV_OK)\n \t\treturn ret;\n@@ -1513,6 +1519,8 @@ static int git_imap_config(const char *var, const char *val,\n \t\tcfg->ssl_verify = git_config_bool(var, val);\n \t} else if (!strcmp(\"imap.preformattedhtml\", var)) {\n \t\tcfg->use_html = git_config_bool(var, val);\n+\t} else if (!strcmp(\"imap.markasread\", var)) {\n+\t\tmark_seen = git_config_bool(var, val);\n \t} else if (!strcmp(\"imap.folder\", var)) {\n \t\tFREE_AND_NULL(cfg->folder);\n \t\treturn git_config_string(&cfg->folder, var, val);\n@@ -1702,6 +1710,12 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server,\n \tcurl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);\n \n+\tif (mark_seen) {\n+\t\tcurl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, CURLULFLAG_SEEN);\n+\t} else {\n+\t\tcurl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, 0L);\n+\t}\n+\n \tcurl_easy_setopt(curl, CURLOPT_READDATA, &msgbuf);\n \n \tfprintf(stderr, \"Sending %d message%s to %s folder...\\n\",\n-- \n2.50.1.320.g2ad311502d\n\n"},{"id":"522584","messageId":"xmqqecu6om3t.fsf@gitster.g","threadId":"63831","inReplyTo":"7108764f437a25079c95a25c227eb79f9f4aee6a.1753273554.git.gargaditya08@live.com","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-23T17:25:42Z","receivedAt":"2025-07-23T17:25:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Aditya Garg <gargaditya08@live.com> writes:\n\n> +imap.markAsRead::\n> +\tChoose whether to mark the sent message as read or not.\n\nIs this something user typically want to use a single setting,\nor would it often be per invocation?  Especially with the new\ninvoker in send-email, wouldn't it become more like \"if I use\nimap-send to stuff things in my outgoing folder, they shouldn't be\nmarked as read, but fcc copies send-email stuffs via imap-send\nshould be marked as read\" or something like that?\n\n> +\tDefault is `true`.\n\nIf we never marked these messages as read, then this default is a\nbreaking change, isn't it?\n\n> @@ -47,11 +47,12 @@\n>  \n>  static int verbosity;\n>  static int list_folders;\n> +static int mark_seen = 1;\n\nIOW, this smells problematic.\n\n> +\tif (mark_seen) {\n> +\t\tret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" (\\\\Seen) \", prefix, box);\n> +\t} else {\n> +\t\tret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" \", prefix, box);\n> +\t}\n\nWhy so many braces around single-statement blocks?\n\n> @@ -1702,6 +1710,12 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server,\n>  \tcurl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n>  \tcurl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);\n>  \n> +\tif (mark_seen) {\n> +\t\tcurl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, CURLULFLAG_SEEN);\n> +\t} else {\n> +\t\tcurl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, 0L);\n> +\t}\n> +\n\nWhy so many braces around single-statement blocks?\n\nAccording to\n\nhttps://github.com/curl/curl/blob/master/docs/libcurl/symbols-in-versions\n\nCURLULFLAG_SEEN first appeared in 8.13.0; INSTALL says we require 7.61.0\nor later, so this may be OK.\n\n"},{"id":"522585","messageId":"PN3PR01MB95970E44092A27F47AF25CF8B85FA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","threadId":"63831","inReplyTo":"xmqqecu6om3t.fsf@gitster.g","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-07-23T17:33:36Z","receivedAt":"2025-07-23T17:33:43Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"\n\n> On 23 Jul 2025, at 10:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> ﻿Aditya Garg <gargaditya08@live.com> writes:\n> \n>> +imap.markAsRead::\n>> +    Choose whether to mark the sent message as read or not.\n> \n> Is this something user typically want to use a single setting,\n> or would it often be per invocation?  Especially with the new\n> invoker in send-email, wouldn't it become more like \"if I use\n> imap-send to stuff things in my outgoing folder, they shouldn't be\n> marked as read, but fcc copies send-email stuffs via imap-send\n> should be marked as read\" or something like that?\n\nSo whenever the user changes the folder, he can change this option too?\n\nAlso, we have a command line way as well.\n\n> \n>> +    Default is `true`.\n> \n> If we never marked these messages as read, then this default is a\n> breaking change, isn't it?\n\nCurl always marked the messages as read, so how would it be a breaking change? As far as OpenSSL is concerned, it marks the messages as unread, but due to issues with the license, as long as people are compiling git themselves, I doubt people are using it.\n\nAlso, were people really using imap-send itself?\n\n> \n>> @@ -47,11 +47,12 @@\n>> \n>> static int verbosity;\n>> static int list_folders;\n>> +static int mark_seen = 1;\n> \n> IOW, this smells problematic.\n> \n>> +    if (mark_seen) {\n>> +        ret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" (\\\\Seen) \", prefix, box);\n>> +    } else {\n>> +        ret = imap_exec_m(ctx, &cb, \"APPEND \\\"%s%s\\\" \", prefix, box);\n>> +    }\n> \n> Why so many braces around single-statement blocks?\n\nWill fix\n\n> \n>> @@ -1702,6 +1710,12 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server,\n>>    curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n>>    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);\n>> \n>> +    if (mark_seen) {\n>> +        curl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, CURLULFLAG_SEEN);\n>> +    } else {\n>> +        curl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, 0L);\n>> +    }\n>> +\n> \n> Why so many braces around single-statement blocks?\n> \n> According to\n> \n> https://github.com/curl/curl/blob/master/docs/libcurl/symbols-in-versions\n> \n> CURLULFLAG_SEEN first appeared in 8.13.0; INSTALL says we require 7.61.0\n> or later, so this may be OK.\n> \n"},{"id":"522586","messageId":"PN3PR01MB9597A88A3CFCF9EC84ECCCC3B85FA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","threadId":"63831","inReplyTo":"PN3PR01MB95970E44092A27F47AF25CF8B85FA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-07-23T17:35:49Z","receivedAt":"2025-07-23T17:35:54Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"\n\n> On 23 Jul 2025, at 11:03 PM, Aditya Garg <gargaditya08@live.com> wrote:\n> \n> ﻿\n> \n>> On 23 Jul 2025, at 10:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> \n>> ﻿Aditya Garg <gargaditya08@live.com> writes:\n>> \n>>> +imap.markAsRead::\n>>> +    Choose whether to mark the sent message as read or not.\n>> \n>> Is this something user typically want to use a single setting,\n>> or would it often be per invocation?  Especially with the new\n>> invoker in send-email, wouldn't it become more like \"if I use\n>> imap-send to stuff things in my outgoing folder, they shouldn't be\n>> marked as read, but fcc copies send-email stuffs via imap-send\n>> should be marked as read\" or something like that?\n> \n> So whenever the user changes the folder, he can change this option too?\n> \n> Also, we have a command line way as well.\n\nFor send-email integration, maybe add another option over there as well?\n"},{"id":"522591","messageId":"xmqqy0sen6ak.fsf@gitster.g","threadId":"63831","inReplyTo":"xmqqecu6om3t.fsf@gitster.g","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-23T17:52:35Z","receivedAt":"2025-07-23T17:52:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Aditya Garg <gargaditya08@live.com> writes:\n>\n>> +\tif (mark_seen) {\n>> +\t\tcurl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, CURLULFLAG_SEEN);\n>> +\t} else {\n>> +\t\tcurl_easy_setopt(curl, CURLOPT_UPLOAD_FLAGS, 0L);\n>> +\t}\n>> +\n>\n> Why so many braces around single-statement blocks?\n>\n> According to\n>\n> https://github.com/curl/curl/blob/master/docs/libcurl/symbols-in-versions\n>\n> CURLULFLAG_SEEN first appeared in 8.13.0; INSTALL says we require 7.61.0\n> or later, so this may be OK.\n\nIt might be obvious, but I meant \"may not be OK\" here.\n"},{"id":"522593","messageId":"xmqqtt32n65h.fsf@gitster.g","threadId":"63831","inReplyTo":"PN3PR01MB95970E44092A27F47AF25CF8B85FA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-23T17:55:38Z","receivedAt":"2025-07-23T17:55:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Aditya Garg <gargaditya08@live.com> writes:\n\n>> On 23 Jul 2025, at 10:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> \n>> ﻿Aditya Garg <gargaditya08@live.com> writes:\n>> \n>>> +imap.markAsRead::\n>>> +    Choose whether to mark the sent message as read or not.\n>> \n>> Is this something user typically want to use a single setting,\n>> or would it often be per invocation?  Especially with the new\n>> invoker in send-email, wouldn't it become more like \"if I use\n>> imap-send to stuff things in my outgoing folder, they shouldn't be\n>> marked as read, but fcc copies send-email stuffs via imap-send\n>> should be marked as read\" or something like that?\n>\n> So whenever the user changes the folder, he can change this option too?\n\nI am not sure what you mean.  If it is primarily per invocation, we\ndo not want a new configuration variable.  A new feature should be\nintroduced behind a command line option (disabled by default) first,\nand then if it proves useful enough to wide audience, a configuration\nis added for enhanced usability.  Adding a new configuration variable\nat the same time an option is introduced smelled more like a spinal\nreflection than a well thought out design.\n"},{"id":"522594","messageId":"xmqqpldqn64c.fsf@gitster.g","threadId":"63831","inReplyTo":"PN3PR01MB9597A88A3CFCF9EC84ECCCC3B85FA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-23T17:56:19Z","receivedAt":"2025-07-23T17:56:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Aditya Garg <gargaditya08@live.com> writes:\n\n> For send-email integration, maybe add another option over there as well?\n\nNo, let's scrap this step, as it requires way too new version of\ncURL.\n"},{"id":"522595","messageId":"PN3PR01MB959724CCE0747A885E5B0B14B85FA@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM","threadId":"63831","inReplyTo":"xmqqpldqn64c.fsf@gitster.g","subject":"Re: [PATCH] imap-send: add option to mark sent messages as read or unread","fromName":"Aditya Garg","fromEmail":"gargaditya08@live.com","sentAt":"2025-07-23T18:00:15Z","receivedAt":"2025-07-23T18:00:20Z","isPatch":true,"sender":{"key":"gargaditya08@live.com","avatar":"https://avatars.githubusercontent.com/u/85610623?v=4"},"body":"\n\n> On 23 Jul 2025, at 11:26 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> ﻿Aditya Garg <gargaditya08@live.com> writes:\n> \n>> For send-email integration, maybe add another option over there as well?\n> \n> No, let's scrap this step, as it requires way too new version of\n> cURL.\n\nYes I got that. Btw, so I just keep the inconsistency that OpenSSL marks it as unread and curl as read that way, or make OpenSSL mark it as read (it doesn't need any new api)?"}]}