Subject: [PATCH v4 0/2] send-email: fix threads breaking in case user edits emails and improvements to outlook ID fix.

From: Aditya Garg <[email-masked]>
Date: Mon, 26 May 2025 15:51:41 +0000

Hi all,

This patch series fixes two minor issues with git-send-email.

The first patch fixes a bug that caused the message number to increase
when a user edits an email. As a result of this bug, threads would
break when a user edits an email.

The second patch improves the logging of the new message ID assigned by
Outlook when a user edits an email.

v2 - Change the bugfix logic used to fix the threading bug.
v3 - Add additional patch to improve the logging of the new
     message ID assigned by Outlook.
v4 - Completely rewrite the commit message of the first patch to
     explain the bug in detail and how it is fixed. Also, add
     example logs to explain the second patch.

Aditya Garg (2):
  send-email: fix bug resulting in increased message number if a message
    is edited
  send-email: show the new message id assigned by outlook in the logs

 git-send-email.perl | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

Range-diff:
1:  259e20261e ! 1:  63addf9d9b send-email: fix bug resulting in increased message number if a message is edited
    @@ Metadata
      ## Commit message ##
         send-email: fix bug resulting in increased message number if a message is edited
     
    -    In case a message is edited before it is sent, its message number gets
    -    increased by 1, and so does its order in the message id. The cause of
    -    this bug was that when a person attempts to edit the message, the whole
    -    sub process_file gets terminated, and the user is asked to edit the message.
    -    After necessary edits are done, the whole sub process_file is executed again.
    -    The way sub process_file is designed, every time is runs, it increases the
    -    $message_num variable by 1. The reason for this was that the function ran
    -    again everytime a next message was sent in a thread, and thus we need to
    -    increase the message number for that message. In case a user edits the message,
    -    there is no check for the same and the new message gets treated as a subsequent
    -    message of a thread, therefore increasing its message number by one. This
    -    breaks the shallow thread logic which relies on $message_num being 1 for the
    -    first message, and it gets changed in case the user edits the first message.
    -
    -    So, upon scanning the whole code, there are two significant variables at play
    -    here. First is $message_num, responsible for the message number and second
    -    is $message_id_serial, responsible for showing the message number in the
    -    Message-ID header. So, whenever we edit a message, lets just decrease them
    -    by 1, so that when the whole process to compose and send the message starts,
    -    these variables increase by 1 again, thus get set to the original values for
    -    that message.
    -
    -    We also are doing the same thing in case the user chooses to not send a message
    -    out of many messages in a thread. By doing so, we will simply decrease these
    -    variables by 1 for further messages, thus ensuring the whole thread doesn't
    -    break.
    +    Whenever we send a thread of emails using send-email, a message number
    +    is internally assigned to each email. This number is used to track the
    +    order of the emails in the thread. Whenever a new message is processed
    +    in a thread, the current script logic increases the message number by
    +    one, which is intended.
    +
    +    But, if a message is edited and then resent, its message number again
    +    gets increased. This is because the script uses the same logic to
    +    process the edited message, which is uses the send the next message.
    +
    +    This minor bug is usually harmless unless some special situations arise.
    +    One such situation is when the first message in a thread is edited
    +    and resent, and an `--in-reply-to` argument is also passed to send-email.
    +    In this case if the user has chosen shallow threading, the threading
    +    does not work as expected, and all messaged become as replies to the
    +    Message-ID specified in the `--in-reply-to` argument.
    +
    +    The reason for this bug is hidden in the code for threading itself.
    +
    +    if ($thread) {
    +            if ($message_was_sent &&
    +              ($chain_reply_to || !defined $in_reply_to || length($in_reply_to) == 0 ||
    +              $message_num == 1)) {
    +                    $in_reply_to = $message_id;
    +                    if (length $references > 0) {
    +                            $references .= "\n $message_id";
    +                    } else {
    +                            $references = "$message_id";
    +                    }
    +            }
    +    }
    +
    +    Here $message_num is the current message number, and $in_reply_to is
    +    the Message-ID of the message to which the current message is a reply.
    +    In case `--in-reply-to` is specified, the `$in_reply_to` variable
    +    is set to the value of the `--in-reply-to` argument.
    +
    +    Whenever this whole set of conditions is true, the script sets the
    +    `$in_reply_to` variable to the current message's ID. This is done to
    +    ensure that the next message in the thread is a reply to this message.
    +
    +    In case we specify an `--in-reply-to` argument, and have shallow
    +    threading, the only condition that can make this true is
    +    `$message_num == 1`, which is true for the first message in a thread.
    +    Thus the $in_reply_to variable gets set to the first message's ID.
    +    For subsequent messages, the `$message_num` variable is always
    +    greater than 1, and the whole set of conditions is false, and thus the
    +    $in_reply_to variable remains as the first message's ID. This is what
    +    we expect in shallow threading. But, in case the user edits the first
    +    message and resends it, the `$message_num` variable gets increased by 1,
    +    and thus the condition `$message_num == 1` becomes false. This means
    +    that the `$in_reply_to` variable is not set to the first message's ID,
    +    and thus the next message in the thread is not a reply to the first
    +    message, but to the `--in-reply-to` argument, effectively breaking
    +    the threading.
    +
    +    In case the user does not specify an `--in-reply-to` argument, the
    +    !defined $in_reply_to condition is true, and thus the `$in_reply_to`
    +    variable is set to the first message's ID, and the threading works
    +    as expected, irrespective of what the message number is.
    +
    +    Just like $message_num, $message_id_serial variable also increases by 1
    +    whenever a new message is sent. This variable displays the message
    +    number is the Message-ID of the email.
    +
    +    So, in order to fix this bug, we need to ensure that the $message_num
    +    variable is not increased by 1 when a message is edited and resent.
    +    We do this by decreasing the $message_num and $message_id_serial
    +    variable by 1 whenever the request to edit a message is received. This
    +    way, the next message in the thread will have the same message number as
    +    the edited message, and thus the threading will work as expected.
    +
    +    The same logic has also been applied in case the user drops a single
    +    message from the thread by choosing the "[n]o" option during
    +    confirmation. By doing this, the next message in the thread is assigned
    +    the message number of the dropped message, and thus the threading
    +    works as expected.
     
         Signed-off-by: Aditya Garg <[email-masked]>
     
2:  65619ac4d7 ! 2:  72b3cd1bfb send-email: show the new message id assigned by outlook in the logs
    @@ Commit message
         send-email: show the new message id assigned by outlook in the logs
     
         Whenever an email is sent, send-email shows a log at last, which
    -    contains all the headers of the email that was send successfully.
    -    In case outlook changes the Message-ID, a log for the same is
    -    shown to the user, but that change is not reflected when the log
    -    containing all the headers is displayed.
    +    contains all the headers of the email that were received by the
    +    receipients.
    +
    +    In case outlook changes the Message-ID, a log for the same is shown to
    +    the user, but that change is not reflected when the log containing all
    +    the headers is displayed. Here is an example of the log that is shown
    +    when outlook changes the Message-ID:
    +
    +    Outlook reassigned Message-ID to: <[email-masked]>
    +    OK. Log says:
    +    Server: smtp.office365.com
    +    MAIL FROM:<[email-masked]>
    +    RCPT TO:<[email-masked]>
    +    From: Aditya Garg <[email-masked]>
    +    To: [email-masked]
    +    Subject: [PATCH] send-email: show the new message id assigned by outlook in the logs
    +    Date: Mon, 26 May 2025 20:28:36 +0530
    +    Message-ID: <[email-masked]>
    +    X-Mailer: git-send-email @GIT_VERSION@
    +    MIME-Version: 1.0
    +    Content-Transfer-Encoding: 8bit
    +
    +    Result: 250
     
         This patch fixes this by modifying the $header variable, which is
    -    responsible for showing the logs at the end. Also, the log which
    -    states that the Message-ID has been changed will now be shown only
    -    when smtp-debug is enabled, since the main log having all of the
    -    headers is anyways displaying the new Message-ID.
    +    responsible for showing the logs at the end. Also, the log which states
    +    that the Message-ID has been changed will now be shown only when
    +    smtp-debug is enabled, since the main log having all of the headers is
    +    anyways displaying the new Message-ID. It should look like this after
    +    this patch:
    +
    +    OK. Log says:
    +    Server: smtp.office365.com
    +    MAIL FROM:<[email-masked]>
    +    RCPT TO:<[email-masked]>
    +    From: Aditya Garg <[email-masked]>
    +    To: [email-masked]
    +    Subject: [PATCH] send-email: show the new message id assigned by outlook in the logs
    +    Date: Mon, 26 May 2025 20:29:22 +0530
    +    Message-ID: <[email-masked]>
    +    X-Mailer: git-send-email @GIT_VERSION@
    +    MIME-Version: 1.0
    +    Content-Transfer-Encoding: 8bit
    +
    +    Result: 250
     
         Signed-off-by: Aditya Garg <[email-masked]>
     
-- 
2.43.0