Say you have to contribute to some project run by Unix bros who want the 90s back, so they don't use GitHub or its many self-hosted alternatives to accept pull requests, and you need to email them a patch. I would find it entirely understandable to want to get a quill pen and write a letter on paper for fun instead of dealing with mailing lists and emailing a patch.
Unfortunately, sometimes one needs to engage in the much less pleasant form of anachronism of contributing to this kind of software anyway, as mailing lists with patches are still very common in the land of older system software under the C. The patch-emailing features of git are some of its most infamous for poor usability, which is saying something, because git as a whole is known for being hard to use.
For those who are unfamiliar with the email-patch infrastructure, git is
extremely picky about emails being the exact format it likes and not getting
modified at all by the client. This means that in practice, you need to send
your patch emails using
git send-email as your email client.
Theoretically, https://git-send-email.io/ (by someone who made their own new
git source hosting service that mysteriously uses emails to submit patches)
will tell you how to set it up. Well, except if
git send-email has other
ideas: it would not send through my email provider for reasons that must have
been a bug: I seem to recall it was something to do with either a TLS or SMTP
implementation being broken.
I ended up needing to use a separate Mail Transfer Agent (SMTP-speak for
"SMTP client") and plumb it into git. For this, I used
First, store your SMTP email password in the system keyring:
# on KDE $ kwallet-query -w email@example.com kdewallet -f mail # on GNOME/other things supporting freedesktop secrets $ secret-tool store --label=msmtp host smtp.migadu.com service smtp user firstname.lastname@example.org # on macOS $ security add-internet-password -s smtp.migadu.com -r smtp -a email@example.com -w
I use KDE, so this setup uses the KDE wallet to store the password. If you use
macOS, GNOME or the future version of KDE that supports the freedesktop secrets
system, remove the
passwordeval line from the sample config here as
msmtp can get the password from your keyring by itself.
Then write a
msmtp configuration file:
# Used to identify which account you are using in the msmtp command line account myaccountname # Tunneled-TLS email configuration. Probably correct for most modern servers, # but check your email provider documentation. This is correct for migadu. host smtp.migadu.com port 465 tls on tls_starttls off auth on user firstname.lastname@example.org # From address on the envelope. Probably your email, but not necessarily # (note that this is distinct from the "from" address in the message body that # will be shown to recipients. it needs to match the address subscribed to the # mailing list) from email@example.com # Use kwallet-query to get the password because kwallet does not support the # freedesktop secrets protocol # NOTE!! If you are on macOS or GNOME or the future version of KDE that # supports freedesktop secrets, delete the following line! passwordeval kwallet-query -r firstname.lastname@example.org kdewallet -f mail
Then configure git (I keep this in
~/.gitconfig as I don't really want to
check it in for spam reasons, whereas most of my git config is checked in and
[sendemail] sendmailcmd = /usr/bin/msmtp smtpserveroption = -a smtpserveroption = myaccountname confirm = always # don't send yourself emails suppresscc = self
Finally, you can send an email:
/tmp/nya » git init Initialized empty Git repository in /tmp/nya/.git/ /tmp/nya - [main] » echo nyaa > README.md /tmp/nya - [main●] » git add -A /tmp/nya - [main●] » git commit -m 'initial commit' [main (root-commit) 5e2e44d] initial commit 1 file changed, 1 insertion(+) create mode 100644 README.md /tmp/nya - [main] » echo nyaaaaaaaaaaaaaaaaaaaaa >> README.md /tmp/nya - [main●] » git commit -am 'more nya' [main 3df1f2d] more nya 1 file changed, 1 insertion(+) # NOTE: you probably want to use --compose to write a message to include with # your patch. You can also use --dry-run to do a dry run. /tmp/nya - [main] » git send-email --email@example.com' --firstname.lastname@example.org HEAD^ /tmp/jade/jKCO7nnORw/0001-more-nya.patch (mbox) Adding cc: Jade Lovelace <email@example.com> from line 'From: Jade Lovelace <firstname.lastname@example.org>' From: email@example.com To: firstname.lastname@example.org Cc: Jade Lovelace <email@example.com> Subject: [PATCH] more nya Date: Fri, 22 Apr 2022 20:45:30 -0700 Message-Id: <firstname.lastname@example.org> X-Mailer: git-send-email 2.35.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): y OK. Log says: Sendmail: /usr/bin/msmtp -a email@example.com -i firstname.lastname@example.org email@example.com From: firstname.lastname@example.org To: email@example.com Cc: Jade Lovelace <firstname.lastname@example.org> Subject: [PATCH] more nya Date: Fri, 22 Apr 2022 20:45:30 -0700 Message-Id: <email@example.com> X-Mailer: git-send-email 2.35.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Result: OK
And, yes, it was received:
See? That was
sooooo easy very hard for no reason.