Sending patches by email with git
Written by Matheus Tavares
Written on , last modified onIf 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
: useno-
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 :)
Note about patch version comments
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.
comments powered by Disqus