Sensible Git mail for the occasional user
This entry is mostly for my own benefit, since – being an occasional user – I keep having to figure this out from scratch. What I was aiming for is a workflow that gives me both convenience and full control.
I don’t like
git send-email. The command assembles and sends mail all in one go, so you have to know what it will do blindly. Running
git format-patch manually first only helps a little, since
git send-email still performs its own mail assembly on top of its input. It needs practice – using it frequently for a while and looking at the results. I don’t use it enough for that.
Unfortunately the patchmail I do send every once in a while goes to places with many subscribers, and I’m unwilling to rattle their inboxes with my (repeat!) learning process. I want to be sure I’ll send exactly the mail I mean to, on the very first try. Of course I could dry-run my patchmails by sending them to myself first – fiddly and always one command line typo away from making any mistake public.
I also have msmtp set up on my home server with all the details of my SMTP accounts and really don’t want to maintain another copy of that information on my laptop, especially on a per-repository basis.
So for me, the answer is to avoid
git send-email entirely.
The key realisation is that once a mail is properly formatted, sending it is nothing more than piping it to
/usr/bin/sendmail (or whatever equivalent you employ) – so you actually need only
There is just one little wrinkle to take care of:
git format-patch produces output that cannot be piped to
sendmail verbatim, because it starts with a “
From ” line. This is easily removed using
formail, which can also split mboxes – a natural companion to
git format-patch --stdout. Bottom line:
git format-patch --to email@example.com --stdout origin | formail -I 'From ' -s sendmail -t
git format-patch produces an mbox-format mail folder. (Season that to taste with the
--cc/etc. switches you require.) This is processed using
formail, which splits it into individual mails and pipes them individually to
-s sendmail -t”) after deleting the
From line (“
-I 'From '”).
This essentially replicates
git send-email – but note what I gained here:
I can omit the pipe to
If I just call
git format-patch by itself, I can inspect the exact mail that will be sent. In fact, if you don’t pipe the output anywhere, Git will invoke the pager for you and even highlight the diffs within the attachments: excellent. Very convenient for careful reading.
Then if I’m satisfied, I add the pipe and out go the patches.
I know exactly what is being mailed out. There is no blackbox. This is much like sending a dry-run to myself first, then sending for real, except with all the friction removed.
And if there was a cover letter I needed to edit? Then I just pipe to a file first, before piping to
formail. In between those steps, I can edit the file – whether in Vim directly, or using
mutt -f mbox.
Of course, this isn’t necessarily for everyone. You need a machine with procmail installed (to get
formail) and a
sendmail-compatible MTA set up. You also need to be comfortable working with mail in the raw. There is, after all, no blackbox.
But it works for me. Sending patchmail is no longer something I put off.