Sending patches by email with git

Written by Matheus Tavares

If you are a newcomer in the kernel or git development community (or others), you may find it odd that contributions aren’t sent via fancy user interfaces such as the ones provided by Github (Pull Requests) and Gitlab (Merge Request). All patches, as they are called, are sent by email to the respective mailing list.

Ok, so you got your first commit and you already figured out whom to send it to, now how do you send it? Some email clients insert html code and convert tabs to whitespaces, to make the text prettier. And that, as a result, messes up with the code you are trying to send :( So some good options are: neomutt (a terminal based email client) or git send-email! Yes, git can send your patches! In this tutorial, we are going to see a little step-by-step guide on how to set up and use git send-email to send a single patch and patchsets.

Most of what I’ll show comes from here. I encourage you to take a look there too. Also, if you are, indeed, starting to make patches for the kernel, you may find the patch philosophy, the first kernel patch post and how to write good commit messages very useful.

Without further ado, let’s get to it!

Reference

Note: This section is for reference only. There are several nuances of setting up and using git-send-email. So read the tutorial completely.

## Configure with:
git config --global user.name "<your name>"
git config --global user.email "<your email>"
git config --global sendemail.smtpencryption tls
git config --global sendemail.smtpserver "<your_email_smtp_server_address>"
git config --global sendemail.smtpuser "<your_email>"
git config --global sendemail.smtpserverport "<your_email_smtp_server_port>"

## Send patches with:
git send-email --annotate --to="teste@email.com" --cc="mailing@list.com" -1 # for a single patch
git send-email --annotate --cover-letter --thread --no-chain-reply-to --to="teste@email.com" --cc="mailing@list.com" -3 # for a patchset


Setting it up

1) Instalation

You probably already have git installed (if not, that’s the first thing), but depending on your distro, you may need some additional packages. In ubuntu, for example, you need git-email, in Manjaro you need perl-io-socket-ssl and perl-net-ssleay and in Arch you need perl-authen-sasl.

2) If you haven’t told git your name and email yet, do that:

git config --global user.name "<your name>"
git config --global user.email "<your email>"


Note: use you full name (or at least partial) here. For example, “Johnathan F. Hanks” and “Michael Stuart” are ok. But “Johnathan” and “Stuart” are not.

3) Configure the sending email SMTP server:

For this section, you may have to check some values depending on your email service. For gmail, for example, the SMTP server address is smtp.gmail.com and the port is 587. Also, note that, for gmail, you will have to allow less secure apps. You can do that here. Another option is to sign in using app passwords, but I haven’t tried that.

git config --global sendemail.smtpencryption tls
git config --global sendemail.smtpserver "<your_email_smtp_server_address>"
git config --global sendemail.smtpuser "<your_email>"
git config --global sendemail.smtpserverport "<your_email_smtp_server_port>"


You can also set your email password with:

git config --global sendemail.smtppass "<your password>"


But that will store your password as plain text at ~/.gitconfig, so I don’t recommend it. If you don’t set your password, you will be asked for it when you try to send an email.

4) [Optional] Supress yourself in cc:

By default, git will add the author of the commit(s) to cc. This means that when you are the author, you will send the email to yourself too. To suppress this behavior (of sending to yourself), run:

git config --global sendemail.suppresscc self


How to use it

You can send patches by different means. You can use git format-patch to write the patch to a file and then send this file using git send-email. Another option is to let git send-email deal with both patch formatting and sending (which I personally prefer).

1) Basic usage:

If you want to send your last N patches run:

git send-email -N # Replace N with the number of patches


If you want to send the commits from hash d2901 to hash 89e73:

git send-email d2901..89e73


You can specify who to send the emails to with --to and --cc, but if you don’t use them, git will prompt you the recipient.

2) A more complete/real usage:

There is a lot of other useful options, and you can check them all with a man git-send-email, but what I usually use, for a single patch, is this:

git send-email --annotate --to="teste@email.com" --cc="mailing@list.com" -1


And for a patchset (i.e. a series of patches), is something like this:

git send-email --annotate --cover-letter --thread --no-chain-reply-to --to="teste@email.com" --cc="mailing@list.com" -3


The options used are:

• --annotate: open the emails in your text editor to be edited/annotated before sending. Even when you won’t make any annotations, this is an excellent option to use so that you can do a final check in the patch before sending.
• --cover-letter: make a cover letter, where you can explain the overall modifications your patches make. Useful when you are sending more than one patch.
• --thread: send all the emails in the same thread, either making each one a reply to the last one or making all replying to the first one (the cover letter, if you used --cover-letter). You can specify which behavior you want with the --[no-]chain-reply-to option.
• --[no-]chain-reply-to: use no- if you want all the emails to reply the first one (the expected behavior when sending emails to linux kernel).

More tips on patch sending

1) Dry-run: A safe way to test send-email

You can use the --dry-run option to make git-send-email do all the process but without actually sending the emails. It’s a good option to test everything before sending. You can see in the command’s output, for example, if all the people you desired to be at TO or CC really got there.

2) Prefixing emails’ subjects

Numbering
When sending a patchset, the subject of each email, which will be each commits’ message title, will already be prefixed with a [PATCH 1/N], [PATCH 2/N] and so on.

Versioning
When you receive a review for your patch, you’ll probably want to send a new modified version. In this case you can use a -v2 (or -v3, and so on), in order to make git send-email prefix the email subjects with [PATCH v2 X/N].

Custom prefix
You can also change the default “PATCH” in the prefix with --subject-prefix="<your_prefix_here>"

3) Annotating the patch

Sometimes you want to add comments to your patch that are not meant to be in the final patch message. For example, a comment saying “This patch depends on patch XYZ” or a patch version comment. To do that, you may use the --annotate option, which will open the email in the set editor to be edited before sending.

The --annotate option can also be used so that one can do a final check in the patch and email before sending (which is always very nice :)

Usually, when sending a v2, v3, etc., it’s good to add comments explaining the modifications made, like this:

---
Changes in V3:
- Add xpto call

Changes in v3:
- Removed foo increment
- Refactor patch message


The --- is called “scissors separator”. Eveything you add below it, until the beginning of the diff, will be ignored when applying the patch to a git repository. That’s the place to add any comment.

4) A note about patchsets and cover letter

Patchsets are series of patches sent each one in its own email. It is common to send an extra mail before the patch mails with a little abstract introducing them. This email is called cover letter, and usually it usually takes the index 0 in the series. To make a cover letter, just use the --cover-letter option. Tip: take a look at mailing list archives to see how contributors usually write cover letters.

All the following email patches in a patchset should be a reply to the first email (which usually is the cover letter). To make git do that, you must use the options --thread --no-chain-reply-to.

5) The editor set for git

You can configure which editor git will open when using the --annotate option, editing a commit message and everything that needs and editor. One way of doing that is by running:

git config --global core.editor <your_editor>


But git also supports the standardized VISUAL and EDITOR environment variables, so you can run these commands in your bash:

export VISUAL=<your_editor>
export EDITOR=<your_editor>


Note: The above command will set the editor for git and other programs that follow these environment variables standards.