summaryrefslogtreecommitdiff
path: root/git-send-email.perl
AgeCommit message (Collapse)Author
2025-07-14Merge branch 'mc/netrc-service-names'Junio C Hamano
"netrc" credential helper has been improved to understand textual service names (like smtp) in addition to the numeric port numbers (like 25). * mc/netrc-service-names: contrib: better support symbolic port names in git-credential-netrc contrib: warn for invalid netrc file ports in git-credential-netrc contrib: use a more portable shebang for git-credential-netrc
2025-06-25contrib: better support symbolic port names in git-credential-netrcMaxim Cournoyer
To improve support for symbolic port names in netrc files, this changes does the following: - Treat symbolic port names as ports, not protocols in git-credential-netrc - Validate the SMTP server port provided to send-email - Convert the above symbolic port names to their numerical values. Before this change, it was not possible to have a SMTP server port set to "smtps" in a netrc file (e.g. Emacs' ~/.authinfo.gpg), as it would be registered as a protocol and break the match for a "smtp" protocol host, as queried for by git-send-email. Signed-off-by: Maxim Cournoyer <maxim@guixotic.coop> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-04send-email: show the new message id assigned by outlook in the logsAditya Garg
Whenever an email is sent, send-email shows a log at last, which 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: <PN3PR01MB95973E5ACD7CCFADCB4E298CB865A@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM> OK. Log says: Server: smtp.office365.com MAIL FROM:<gargaditya08@live.com> RCPT TO:<negahe7142@nomrista.com> From: Aditya Garg <gargaditya08@live.com> To: negahe7142@nomrista.com 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: <20250526145836.4825-1-gargaditya08@live.com> X-Mailer: git-send-email @GIT_VERSION@ MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Result: 250 Fix this by updating the $header variable, which has the message ID we internally assigned on the "Message-ID:" header, with the message ID the Outlook server assigned. It should look like this after this patch: OK. Log says: Server: smtp.office365.com MAIL FROM:<gargaditya08@live.com> RCPT TO:<negahe7142@nomrista.com> From: Aditya Garg <gargaditya08@live.com> To: negahe7142@nomrista.com 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: <PN3PR01MB95977486061BD2542BD09B67B865A@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM> X-Mailer: git-send-email @GIT_VERSION@ MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Result: 250 Signed-off-by: Aditya Garg <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-04send-email: fix bug resulting in broken threads if a message is editedAditya Garg
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 increments the message number by one, which is intended. But, if a message is edited and then resent, its message number again gets incremented. This is because the script uses the same logic to process the edited message, which it uses to send the next message. This minor bug is usually harmless, unless a special situations arises. That 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 messages become 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. Therefore, the `$in_reply_to` variable remains as the first message's ID. This is what we expect in shallow threading. But if the user edits the first message and resends it, the `$message_num` variable gets incremented 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. As a result 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, regardless of the message number. To fix this bug, we need to ensure that the `$message_num` variable is not incremented by 1 when a message is edited and resent. We do this by decreasing the `$message_num` 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. Therefore 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 <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-05-23Merge branch 'ag/send-email-hostname-f'Junio C Hamano
Teach "git send-email" to also consult `hostname -f` for mail domain to compute the identity given to SMTP servers. * ag/send-email-hostname-f: send-email: try to get fqdn by running hostname -f on Linux and macOS
2025-05-19Merge branch 'ag/doc-send-email'Junio C Hamano
The `send-email` documentation has been updated with OAuth2.0 related examples. * ag/doc-send-email: docs: add credential helper for outlook and gmail in OAuth list of helpers docs: improve send-email documentation send-mail: improve checks for valid_fqdn
2025-05-13send-email: try to get fqdn by running hostname -f on Linux and macOSAditya Garg
`hostname` is a popular command available on both Linux and macOS. As per the man-page[1], `hostname -f` command returns the fully qualified domain name (FQDN) of the system. The current Net::Domain perl module being used in the script for the same has been quite unrealiable in many cases. Thankfully, we now have a better check for valid_fqdn, which does reject the invalid FQDNs given by this module properly, but at the same time, it will result in a fallback to 'localhost.localdomain' being used. `hostname -f` has been quite reliable (probably even more reliable than the Net::Domain module) and before falling back to 'localhost.localdomain', we should try to use it. Interestingly, the `hostname` command is actually used by perl modules like Net::Domain[2] and Sys::Hostname[3] to get the hostname. So, lets give `hostname -f` a chance as well! [1]: https://man7.org/linux/man-pages/man1/hostname.1.html [2]: https://github.com/Perl/perl5/blob/blead/cpan/libnet/lib/Net/Domain.pm#L88 [3]: https://github.com/Perl/perl5/blob/blead/ext/Sys-Hostname/Hostname.pm#L93 Signed-off-by: Aditya Garg <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-05-08send-mail: improve checks for valid_fqdnAditya Garg
The current implementation of a valid Fully Qualified Domain Name is not that strict. It just checks whether it has a dot (.) and if using macOS, it should not end with .local. As per RFC1035[1], from what I understood, the following checks need to be done: - The domain must contain atleast one dot - Each label (separated by dots) must be 1-63 characters long - Labels must start and end with an alphanumeric character - Labels can contain alphanumeric characters and hyphens Here are some examples of valid and invalid labels: 'example.com', # Valid 'sub.example.com', # Valid 'my-domain.org', # Valid 'localhost', # Invalid (no dot) 'MacBook..', # Invalid (double dots) '-example.com', # Invalid (starts with a hyphen) 'example-.com', # Invalid (ends with a hyphen) 'example..com', # Invalid (double dots) 'example', # Invalid (no TLD) 'example.local', # Invalid on macOS 'valid-domain.co.uk', # Valid '123.example.com', # Valid 'example.com.', # Invalid (trailing dot) 'toolonglabeltoolonglabeltoolonglabeltoolonglabeltoolonglabeltoolonglabel.com', # Invalid (label > 63 chars) Due to current implementation, I was not able to send emails from Ubuntu. Upon debugging, I found that the SMTP domain being passed to Outlook's servers was not valid. Net::SMTP=GLOB(0x5db4351225f8)>>> EHLO MacBook.. Net::SMTP=GLOB(0x5db4351225f8)<<< 501 5.5.4 Invalid domain name Net::SMTP=GLOB(0x5db4351225f8)>>> HELO MacBook.. Notice that an invalid domain name "MacBook.." is sent by git-send-email. We have a fallback code that checks output from Net::Domain::domainname() or asking domain method of an Net::SMTP instance to detect a misconfigured hostname and replace it with fallback "localhost.localdomain", but the valid_fqdn apparently is failing to say "MacBook.." is not a valid fqdn. With this patch, the rule used in valid_fqdn is tightened, the beginning part of the SMTP exchange looked like this: Net::SMTP=GLOB(0x58c8af71e930)>>> EHLO localhost.localdomain Net::SMTP=GLOB(0x58c8af71e930)<<< 250-PN4P287CA0064.outlook.office365.com Hello [1]: https://datatracker.ietf.org/doc/html/rfc1035 Signed-off-by: Aditya Garg <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-29send-email: add --[no-]outlook-id-fix optionAditya Garg
Add an option to allow users to specifically enable or disable retrieving the Message-ID from the Outlook SMTP server. This can be used for other hosts mimicking the behaviour of Outlook, or for users who set a custom domain to be a CNAME for the Outlook SMTP server. While at it, lets also add missing * in description of --no-smtp-auth. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Aditya Garg <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-25send-email: retrieve Message-ID from outlook SMTP serverAditya Garg
The script generates a Message-ID alongwith the other headers when gen_header is called, and is sent alongwith the email. For most email providers, including gmail, the Message-ID goes unchanged to the recipient. But, this does not seem to be a case with Outlook. In Outlook, when we send our own Message-ID as a part of the headers, it discards it. Then it generates a new random Message-ID and that is what the recipient gets. This is a problem because the Message-ID is crucial when we are sending multiple emails in a thread. The current implementation for threads in the script replies to the Message-ID it generated, but due to Outlook's behavior, it is not the same as the one that the recipient got, thus breaking threads. So a need arises to retrieve the Message-ID from the server response and set it in the In-Reply-To and References email headers instead of using the self generated one for the purpose of replies. The $smtp->message variable in this script for outlook is something like this: 2.0.0 OK <Message-ID> [Hostname=Some-hostname] The Message-ID here is the one the recipient gets, rather than the one the script generated. This patch uses the fact above and retrieves the Message-ID from the server response. It then changes the value of the $message_id variable to the one received from the server. This value will be used when next and subsequent messages are sent as replies to the message, thus preserving the threading of the messages. Signed-off-by: Aditya Garg <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-07send-email: finer-grained SMTP error handlingZheng Yuting
Code captured errors but did not process them further. This treated all failures the same without distinguishing SMTP status. Add handle-smtp_error to extract SMTP status codes using a regex (as defined in RFC 5321) and handle errors as follows: - No error present: - If a result is provided, return 1 to indicate success. - Otherwise, return 0 to indicate failure. - Error present with a captured three-digit status code: - For 4yz (transient errors), return 1 and allow retries. - For 5yz (permanent errors), return 0 to indicate failure. - For any other recognized status code, return 1, treating it as a transient error. - Error present but no status code found: - Return 1 as a transient error. Signed-off-by: Zheng Yuting <05ZYT30@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-07send-email: capture errors in an eval {} blockZheng Yuting
Auth relied solely on return values without catching errors. This misjudges non-credential errors as auth failure without error info. Patch wraps the entire auth process in an eval {} block to catch all exceptions, including non-credential errors. It adds a new $error var, uses 'or do' to prevent flow break, and returns $result ? 1 : 0. And merges if/else branches, integrates SASL and basic auth, with comments for future status code handling. Signed-off-by: Zheng Yuting <05ZYT30@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-07Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt
We have a bunch of placeholders in our scripts that we replace at build time, for example by using sed(1). These placeholders come in three different formats: @PLACEHOLDER@, @@PLACEHOLDER@@ and ++PLACEHOLDER++. Next to being inconsistent it also creates a bit of a problem with CMake, which only supports the first syntax in its `configure_file()` function. To work around that we instead manually replace placeholders via string operations, which is a hassle and removes safeguards that CMake has to verify that we didn't forget to replace any placeholders. Besides that, other build systems like Meson also support the CMake syntax. Unify our codebase to consistently use the syntax supported by such build systems. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-23Require Perl 5.26.0brian m. carlson
Our platform support policy states that we require "versions of dependencies which are generally accepted as stable and supportable, e.g., in line with the version used by other long-term-support distributions". Of Debian, Ubuntu, RHEL, and SLES, the four most common distributions that provide LTS versions, the version with mainstream long-term security support with the oldest Perl is 5.26.0 in SLES 15.6. This is a major upgrade, since Perl 5.8.1, according to the Perl documentation, was released in September of 2003. It brings a lot of new features that we can choose to use, such as s///r to return the modified string, the postderef functionality, and subroutine signatures, although the latter was still considered experimental until 5.36. This change was made with the following one-liner, which intentionally excludes modifying the vendored modules we include to avoid conflicts: git grep -l 'use 5.008001' | grep -v 'LoadCPAN/' | xargs perl -pi -e 's/use 5.008001/require v5.26/' Use require instead of use to avoid changing the behavior as the latter enables features and the former does not. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2024-09-06Merge branch 'jk/send-email-mailmap'Junio C Hamano
"git send-email" learned "--mailmap" option to allow rewriting the recipient addresses. * jk/send-email-mailmap: send-email: add mailmap support via sendemail.mailmap and --mailmap check-mailmap: add options for additional mailmap sources check-mailmap: accept "user@host" contacts
2024-08-27send-email: add mailmap support via sendemail.mailmap and --mailmapJacob Keller
In some cases, a user may be generating a patch for an old commit which now has an out-of-date author or other identity. For example, consider a team member who contributes to an internal fork of an upstream project, but leaves before this change is submitted upstream. In this case, the team members company address may no longer be valid, and will thus bounce when sending email. This can be manually avoided by editing the generated patch files, or by carefully using --suppress-<cc|to> options. This requires a lot of manual intervention and is easy to forget. Git has support for mapping old email addresses and names to a canonical name and address via the .mailmap file (and its associated mailmap.file, mailmap.blob, and log.mailmap options). Teach git send-email to enable mailmap support for all addresses. This ensures that addresses point to the canonical real name and email address. Add the sendemail.mailmap configuration option and its associated --mailmap (and --use-mailmap for compatibility with git log) options. For now, the default behavior is to disable the mailmap in order to avoid any surprises or breaking any existing setups. These options support per-identity configuration via the sendemail.identity configuration blocks. This enables identity-specific configuration in cases where users may not want to enable support. In addition, support send-email specific mailmap data via sendemail.mailmap.file, sendemail.mailmap.blob and their identity-specific variants. The intention of these options is to enable mapping addresses which are no longer valid to a current project or team maintainer. Such mappings may change the actual person being referred to, and may not make sense in a traditional mailmap file which is intended for updating canonical name and address for the same individual. Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-08-17send-email: teach git send-email option to translate aliasesJacob Keller
git send-email has support for converting shorthand alias names to canonical email addresses via the alias file. It supports a wide variety of alias file formats based on popular email program file formats. Other programs, such as b4, would like the ability to convert aliases in the same way as git send-email without needing to re-implement the logic for understanding the many file formats. Teach git send-email a new option, --translate-aliases, which will enable this functionality. Similar to --dump-aliases, this option works like a new mode of operation for git send-email. When run with --translate-aliases, git send-email reads from standard input and converts any provided alias into its canonical name and email according to the alias file. Each expanded name and address is printed to standard output, one per line. Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-07-16Merge branch 'cb/send-email-sanitize-trailer-addresses'Junio C Hamano
Address-looking strings found on the trailer are now placed on the Cc: list after running through sanitize_address by "git send-email". * cb/send-email-sanitize-trailer-addresses: git-send-email: use sanitized address when reading mbox body
2024-07-01git-send-email: use sanitized address when reading mbox bodyCsókás, Bence
Addresses that are mentioned on the trailers in the commit log messages (e.g., "Reviewed-by") are added to the "Cc:" list by "git send-email". These hand-written addresses, however, may be malformed (e.g., having unquoted "." and other punctutation marks in the display-name part) and can upset MTA. The code does use the sanitize_address() helper on these address-looking strings to turn them into valid addresses, but it is used only to see if the address should be suppressed. The original string taken from the message is added to the @cc list if the code decides the address is not suppressed. Because the addresses on trailer lines are hand-written and more likely to contain malformed addresses, when adding to the @cc list, use the result from sanitize_address, not the original. Note that we do not modify the behaviour for addresses taken from the e-mail headers, as they are more likely to be machine generated and well-formed. Signed-off-by: Csókás, Bence <csokas.bence@prolan.hu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-10send-email: move newline characters out of a few translatable stringsDragan Simic
Move the already existing newline characters out of a few translatable strings, to help a bit with the translation efforts. Signed-off-by: Dragan Simic <dsimic@manjaro.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-12-09Merge branch 'tz/send-email-negatable-options'Junio C Hamano
Newer versions of Getopt::Long started giving warnings against our (ab)use of it in "git send-email". Bump the minimum version requirement for Perl to 5.8.1 (from September 2002) to allow simplifying our implementation. * tz/send-email-negatable-options: send-email: avoid duplicate specification warnings perl: bump the required Perl version to 5.8.1 from 5.8.0
2023-11-20Merge branch 'tz/send-email-helpfix'Junio C Hamano
Typoes in "git send-email -h" have been corrected. * tz/send-email-helpfix: send-email: remove stray characters from usage
2023-11-17send-email: avoid duplicate specification warningsTodd Zullinger
A warning is issued for options which are specified more than once beginning with perl-Getopt-Long >= 2.55. In addition to causing users to see warnings, this results in test failures which compare the output. An example, from t9001-send-email.37: | +++ diff -u expect actual | --- expect 2023-11-14 10:38:23.854346488 +0000 | +++ actual 2023-11-14 10:38:23.848346466 +0000 | @@ -1,2 +1,7 @@ | +Duplicate specification "no-chain-reply-to" for option "no-chain-reply-to" | +Duplicate specification "to-cover|to-cover!" for option "to-cover" | +Duplicate specification "cc-cover|cc-cover!" for option "cc-cover" | +Duplicate specification "no-thread" for option "no-thread" | +Duplicate specification "no-to-cover" for option "no-to-cover" | fatal: longline.patch:35 is longer than 998 characters | warning: no patches were sent | error: last command exited with $?=1 | not ok 37 - reject long lines Remove the duplicate option specs. These are primarily the explicit '--no-' prefix opts which were added in f471494303 (git-send-email.perl: support no- prefix with older GetOptions, 2015-01-30). This was done specifically to support perl-5.8.0 which includes Getopt::Long 2.32[1]. Getopt::Long 2.33 added support for the '--no-' prefix natively by appending '!' to the option specification string, which was included in perl-5.8.1 and is not present in perl-5.8.0. The previous commit bumped the minimum supported Perl version to 5.8.1 so we no longer need to provide the '--no-' variants for negatable options manually. Teach `--git-completion-helper` to output the '--no-' options. They are not included in the options hash and would otherwise be lost. Signed-off-by: Todd Zullinger <tmz@pobox.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-17perl: bump the required Perl version to 5.8.1 from 5.8.0Todd Zullinger
The following commit will make use of a Getopt::Long feature which is only present in Perl >= 5.8.1. Document that as the minimum version we support. Many of our Perl scripts will continue to run with 5.8.0 but this change allows us to adjust them as needed without breaking any promises to our users. The Perl requirement was last changed in d48b284183 (perl: bump the required Perl version to 5.8 from 5.6.[21], 2010-09-24). At that time, 5.8.0 was 8 years old. It is now over 21 years old. Signed-off-by: Todd Zullinger <tmz@pobox.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-16send-email: remove stray characters from usageTodd Zullinger
A few stray single quotes crept into the usage string in a2ce608244 (send-email docs: add format-patch options, 2021-10-25). Remove them. Signed-off-by: Todd Zullinger <tmz@pobox.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-07Merge branch 'ms/send-email-validate-fix'Junio C Hamano
"git send-email" did not have certain pieces of data computed yet when it tried to validate the outging messages and its recipient addresses, which has been sorted out. * ms/send-email-validate-fix: send-email: move validation code below process_address_list
2023-10-30Merge branch 'jk/send-email-fix-addresses-from-composed-messages'Junio C Hamano
The codepath to handle recipient addresses `git send-email --compose` learns from the user was completely broken, which has been corrected. * jk/send-email-fix-addresses-from-composed-messages: send-email: handle to/cc/bcc from --compose message Revert "send-email: extract email-parsing code into a subroutine" doc/send-email: mention handling of "reply-to" with --compose
2023-10-26send-email: move validation code below process_address_listMichael Strawbridge
Move validation logic below processing of email address lists so that email validation gets the proper email addresses. As a side effect, some initialization needed to be moved down. In order for validation and the actual email sending to have the same initial state, the initialized variables that get modified by pre_process_file are encapsulated in a new function. This fixes email address validation errors when the optional perl module Email::Valid is installed and multiple addresses are passed in on a single to/cc argument like --to=foo@example.com,bar@example.com. A new test was added to t9001 to expose failures with this case in the future. Reported-by: Bagas Sanjaya <bagasdotme@gmail.com> Signed-off-by: Michael Strawbridge <michael.strawbridge@amd.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-10-20send-email: handle to/cc/bcc from --compose messageJeff King
If the user writes a message via --compose, send-email will pick up various headers like "From", "Subject", etc and use them for other patches as if they were specified on the command-line. But we don't handle "To", "Cc", or "Bcc" this way; we just tell the user "those aren't interpeted yet" and ignore them. But it seems like an obvious thing to want, especially as the same feature exists when the cover letter is generated separately by format-patch. There it is gated behind the --to-cover option, but I don't think we'd need the same control here; since we generate the --compose template ourselves based on the existing input, if the user leaves the lines unchanged then the behavior remains the same. So let's fill in the implementation; like those other headers we already handle, we just need to assign to the initial_* variables. The only difference in this case is that they are arrays, so we'll feed them through parse_address_line() to split them (just like we would when reading a single string via prompting). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-10-20Revert "send-email: extract email-parsing code into a subroutine"Jeff King
This reverts commit b6049542b97e7b135e0e82bf996084d461224d32. Prior to that commit, we read the results of the user editing the "--compose" message in a loop, picking out parts we cared about, and streaming the result out to a ".final" file. That commit split the reading/interpreting into two phases; we'd now read into a hash, and then pick things out of the hash. The goal was making the code more readable. And in some ways it did, because the ugly regexes are confined to the reading phase. But it also introduced several bugs, because now the two phases need to match each other. In particular: - we pick out headers like "Subject: foo" with a case-insensitive regex, and then use the user-provided header name as the key in a case-sensitive hash. So if the user wrote "subject: foo", we'd no longer recognize it as a subject. - the namespace for the hash keys conflates header names with meta information like "body". If you put "body: foo" in your message, it would be misinterpreted as the actual message body (nobody is likely to do that in practice, but it seems like an unnecessary danger). - the handling for to/cc/bcc is totally broken. The behavior before that commit is to recognize and skip those headers, with a note to the user that they are not yet handled. Not great, but OK. But after the patch, the reading side now splits the addresses into a perl array-ref. But the interpreting side doesn't handle this at all, and blindly prints the stringified array-ref value. This leads to garbage like: (mbox) Adding to: ARRAY (0x555b4345c428) from line 'To: ARRAY(0x555b4345c428)' error: unable to extract a valid address from: ARRAY (0x555b4345c428) What to do with this address? ([q]uit|[d]rop|[e]dit): Probably not a huge deal, since nobody should even try to use those headers in the first place (since they were not implemented). But the new behavior is worse, and indicative of the sorts of problems that come from having the two layers. The revert had a few conflicts, due to later work in this area from 15dc3b9161 (send-email: rename variable for clarity, 2018-03-04) and d11c943c78 (send-email: support separate Reply-To address, 2018-03-04). I've ported the changes from those commits over as part of the conflict resolution. The new tests show the bugs. Note the use of GIT_SEND_EMAIL_NOTTY in the second one. Without it, the test is happy to reach outside the test harness to the developer's actual terminal (when run with the buggy state before this patch). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-18git-send-email.perl: avoid printing undef when validating addressesTaylor Blau
When validating email addresses with `extract_valid_address_or_die()`, we print out a helpful error message when the given input does not contain a valid email address. However, the pre-image of this patch looks something like: my $address = shift; $address = extract_valid_address($address): die sprintf(__("..."), $address) if !$address; which fails when given a bogus email address by trying to use $address (which is undef) in a sprintf() expansion, like so: $ git.compile send-email --to="pi <pi@pi>" /tmp/x/*.patch --force Use of uninitialized value $address in sprintf at /home/ttaylorr/src/git/git-send-email line 1175. error: unable to extract a valid address from: This regression dates back to e431225569 (git-send-email: remove invalid addresses earlier, 2012-11-22), but became more noticeable in a8022c5f7b (send-email: expose header information to git-send-email's sendemail-validate hook, 2023-04-19), which validates SMTP headers in the sendemail-validate hook. Avoid trying to format an undef by storing the given and cleaned address separately. After applying this fix, the error contains the invalid email address, and the warning disappears: $ git.compile send-email --to="pi <pi@pi>" /tmp/x/*.patch --force error: unable to extract a valid address from: pi <pi@pi> Reported-by: Bagas Sanjaya <bagasdotme@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-08-08send-email: avoid creating more than one Term::ReadLine objectJeff King
Every time git-send-email calls its ask() function to prompt the user, we call term(), which instantiates a new Term::ReadLine object. But in v1.46 of Term::ReadLine::Gnu (which provides the Term::ReadLine interface on some platforms), its constructor refuses to create a second instance[1]. So on systems with that version of the module, most git-send-email instances will fail (as we usually prompt for both "to" and "in-reply-to" unless the user provided them on the command line). We can fix this by keeping a single instance variable and returning it for each call to term(). In perl 5.10 and up, we could do that with a "state" variable. But since we only require 5.008, we'll do it the old-fashioned way, with a lexical "my" in its own scope. Note that the tests in t9001 detect this problem as-is, since the failure mode is for the program to die. But let's also beef up the "Prompting works" test to check that it correctly handles multiple inputs (if we had chosen to keep our FakeTerm hack in the previous commit, then the failure mode would be incorrectly ignoring prompts after the first). [1] For discussion of why multiple instances are forbidden, see: https://github.com/hirooih/perl-trg/issues/16 Signed-off-by: Jeff King <peff@peff.net> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-08-08send-email: drop FakeTerm hackJeff King
Back in 280242d1cc (send-email: do not barf when Term::ReadLine does not like your terminal, 2006-07-02), we added a fallback for when Term::ReadLine's constructor failed: we'd have a FakeTerm object instead, which would then die if anybody actually tried to call readline() on it. Since we instantiated the $term variable at program startup, we needed this workaround to let the program run in modes when we did not prompt the user. But later, in f4dc9432fd (send-email: lazily load modules for a big speedup, 2021-05-28), we started loading Term::ReadLine lazily only when ask() is called. So at that point we know we're trying to prompt the user, and we can just die if ReadLine instantiation fails, rather than making this fake object to lazily delay showing the error. This should be OK even if there is no tty (e.g., we're in a cron job), because Term::ReadLine will return a stub object in that case whose "IN" and "OUT" functions return undef. And since 5906f54e47 (send-email: don't attempt to prompt if tty is closed, 2009-03-31), we check for that case and skip prompting. And we can be sure that FakeTerm was not kicking in for such a situation, because it has actually been broken since that commit! It does not define "IN" or "OUT" methods, so perl would barf with an error. If FakeTerm was in use, we were neither honoring what 5906f54e47 tried to do, nor producing the readable message that 280242d1cc intended. So we're better off just dropping FakeTerm entirely, and letting the error reported by constructing Term::ReadLine through. Signed-off-by: Jeff King <peff@peff.net> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-19Merge branch 'jc/send-email-pre-process-fix'Junio C Hamano
When "git send-email" that uses the validate hook is fed a message without and then with Message-ID, it failed to auto-assign a unique Message-ID to the former and instead reused the Message-ID from the latter, which has been corrected. This was a fix for a recent regression caught before the release, so no need to mention it in the release notes. * jc/send-email-pre-process-fix: t9001: mark the script as no longer leak checker clean send-email: clear the $message_id after validation
2023-05-17send-email: clear the $message_id after validationJunio C Hamano
Recently git-send-email started parsing the same message twice, once to validate _all_ the message before sending even the first one, and then after the validation hook is happy and each message gets sent, to read the contents to find out where to send to etc. Unfortunately, the effect of reading the messages for validation lingered even after the validation is done. Namely $message_id gets assigned if exists in the input files but the variable is global, and it is not cleared before pre_process_file runs. This causes reading a message without a message-id followed by reading a message with a message-id to misbehave---the sub reports as if the message had the same id as the previously written one. Clear the variable before starting to read the headers in pre_process_file. Tested-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-15Merge branch 'mc/send-email-header-cmd'Junio C Hamano
"git send-email" learned "--header-cmd=<cmd>" that can inject arbitrary e-mail header lines to the outgoing messages. * mc/send-email-header-cmd: send-email: detect empty blank lines in command output send-email: add --header-cmd, --no-header-cmd options send-email: extract execute_cmd from recipients_cmd
2023-05-10Merge branch 'ms/send-email-feed-header-to-validate-hook'Junio C Hamano
"git send-email" learned to give the e-mail headers to the validate hook by passing an extra argument from the command line. * ms/send-email-feed-header-to-validate-hook: send-email: expose header information to git-send-email's sendemail-validate hook send-email: refactor header generation functions
2023-05-01send-email: detect empty blank lines in command outputMaxim Cournoyer
The email format does not allow blank lines in headers; detect such input and report it as malformed and add a test for it. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-01send-email: add --header-cmd, --no-header-cmd optionsMaxim Cournoyer
Sometimes, adding a header different than CC or TO is desirable; for example, when using Debbugs, it is best to use 'X-Debbugs-Cc' headers to keep people in CC; this is an example use case enabled by the new '--header-cmd' option. The header unfolding logic is extracted to a subroutine so that it can be reused; a test is added for coverage. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-01send-email: extract execute_cmd from recipients_cmdMaxim Cournoyer
This refactor is to pave the way for the addition of the new '--header-cmd' option to the send-email command. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-19send-email: expose header information to git-send-email's sendemail-validate ↵Michael Strawbridge
hook To allow further flexibility in the Git hook, the SMTP header information of the email which git-send-email intends to send, is now passed as the 2nd argument to the sendemail-validate hook. As an example, this can be useful for acting upon keywords in the subject or specific email addresses. Cc: Luben Tuikov <luben.tuikov@amd.com> Cc: Junio C Hamano <gitster@pobox.com> Cc: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Acked-by: Luben Tuikov <luben.tuikov@amd.com> Signed-off-by: Michael Strawbridge <michael.strawbridge@amd.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-19send-email: refactor header generation functionsMichael Strawbridge
Split process_file and send_message into easier to use functions. Making SMTP header information widely available. Cc: Luben Tuikov <luben.tuikov@amd.com> Cc: Junio C Hamano <gitster@pobox.com> Cc: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Acked-by: Luben Tuikov <luben.tuikov@amd.com> Signed-off-by: Michael Strawbridge <michael.strawbridge@amd.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-14send-email: export patch counters in validate environmentRobin Jarry
When sending patch series (with a cover-letter or not) sendemail-validate is called with every email/patch file independently from the others. When one of the patches depends on a previous one, it may not be possible to use this hook in a meaningful way. A hook that wants to check some property of the whole series needs to know which patch is the final one. Expose the current and total number of patches to the hook via the GIT_SENDEMAIL_PATCH_COUNTER and GIT_SENDEMAIL_PATCH_TOTAL environment variables so that both incremental and global validation is possible. Sharing any other state between successive invocations of the validate hook must be done via external means. For example, by storing it in a git config sendemail.validateWorktree entry. Add a sample script with placeholder validations and update tests to check that the counters are properly exported. Suggested-by: Phillip Wood <phillip.wood123@gmail.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-11Merge branch 'jc/spell-id-in-both-caps-in-message-id'Junio C Hamano
Consistently spell "Message-ID" as such, not "Message-Id". * jc/spell-id-in-both-caps-in-message-id: e-mail workflow: Message-ID is spelled with ID in both capital letters
2023-04-03e-mail workflow: Message-ID is spelled with ID in both capital lettersJunio C Hamano
We used to write "Message-Id:" and "Message-ID:" pretty much interchangeably, and the header name is defined to be case insensitive by the RFCs, but the canonical form "Message-ID:" is used throughout the RFC documents, so let's imitate it ourselves. Signed-off-by: Junio C Hamano <gitster@pobox.com> Reviewed-by: Elijah Newren <newren@gmail.com>
2022-11-27send-email: relay '-v N' to format-patchKyle Meyer
send-email relays unrecognized arguments to its format-patch call. Passing '-v N' leads to an error because -v is consumed as send-email's --validate. For example, git send-email -v 3 @{u} fails with fatal: ambiguous argument '3': unknown revision or path not in the working tree. [...] To prevent this, add the short --reroll-count option to send-email's main option list and explicitly provide it to the format-patch call. There other format-patch options that send-email doesn't relay properly, including at least -n, -N, and the diff option -D. Punt on these because dealing with them is more complicated: * they would require configuring send-email to not ignore option case * send-email makes three GetOptions() calls with different sets of options, the last being the main set of options. Unlike -v, which is consumed by the last GetOptions call, the -n, -N, and -D options are consumed as abbreviations by the earlier calls. Signed-off-by: Kyle Meyer <kyle@kyleam.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-11i18n: fix some badly formatted i18n stringsJean-Noël Avila
String in submodule--helper is not correctly formatting placeholders. The string in git-send-email is partial. Signed-off-by: Jean-Noël Avila <jn.avila@free.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-07send-email: use 'git hook run' for 'sendemail-validate'Emily Shaffer
Change the "sendmail-validate" hook to be run via the "git hook run" wrapper instead of via a direct invocation. This is the smallest possibly change to get "send-email" using "git hook run". We still check the hook itself with "-x", and set a "GIT_DIR" variable, both of which are asserted by our tests. We'll need to get rid of this special behavior if we start running N hooks, but for now let's be as close to bug-for-bug compatible as possible. Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Reviewed-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-10-28send-email docs: add format-patch optionsThiago Perrotta
git-send-email(1) does not mention that "git format-patch" options are accepted. Augment SYNOPSIS and DESCRIPTION to mention it. Update git-send-email.perl USAGE to be consistent with git-send-email(1). Signed-off-by: Thiago Perrotta <tbperrotta@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-10-28send-email: programmatically generate bash completionsThiago Perrotta
"git send-email --git-completion-helper" only prints "format-patch" flags. Make it print "send-email" flags as well, extracting them programmatically from its three existing "GetOptions". Introduce a "uniq" subroutine, otherwise --cc-cover, --to-cover and other flags would show up twice. In addition, deduplicate flags common to both "send-email" and "format-patch", like --from. Remove extraneous flags: --h and --git-completion-helper. Add trailing "=" to options that expect an argument, inline with the format-patch implementation. Add a completion test for "send-email --validate", a send-email flag. Signed-off-by: Thiago Perrotta <tbperrotta@gmail.com> Based-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>