email + git = <3

Git ships with built-in tools for collaborating over email. With this guide, you'll be contributing to email-driven projects like the Linux kernel, PostgreSQL, or even git itself in no time.

Step two Configuration

You only need to complete this step once for each machine you intend to send emails from.

Use git config --global --edit to open your global configuration file in your default editor.

There are two possible ways of using Gmail with git send-email:

  1. First, make sure that two-factor authentication is enabled for your Google account. Then, obtain an application-specific password for git from the app passwords page. To store this password with git, run this command:
    git config --global sendemail.smtpPass 'your password'
    Next step is to add these details to your global configuration file:
    [sendemail]
           smtpserver = smtp.gmail.com
           smtpuser = you@gmail.com
           smtpencryption = tls
           smtpserverport = 587
    Be sure to fill in your own email address under smtpuser.
  2. It is still possible to use git send-email without two-factor authentication and application-specific password, but this requires installation and configuration of the special tool, which mimics regular sendmail.

Also, if you haven't yet, run these commands - again, making the appropriate changes:

git config --global user.email "you@gmail.com"
git config --global user.name "Your Name"
Next

Protonmail does not support the open, industry-standard protocols necessary for git send-email to work out-of-the-box. To solve this, Protonmail offers Protonmail Bridge. Otherwise, you need to install & configure Hydroxide to connect to Protonmail with SMTP. Once you have configured Protonmail Bridge or Hydroxide, use its SMTP details along with the generic instructions below.

Protonmail bridge users: the bridge uses SSL authentication, but it self-signs the certificate used for SSL, so you will need to disable SSL verification with the daemon in your git config by setting an empty value for sendemail.smtpsslcertpath.

Be advised that Protonmail is generally known to be a pretty bad email host. They will munge up your outgoing emails and your patches may fail to apply when received by the other end. Not to mention their mistreatment of open source and false promises of security! You should consider a different mail provider.
Next

Visit the Fastmail instructions for adding a new third-party app. Add the following details, making the appropriate changes, including the "app password" that was generated from following those Fastmail instructions:

[sendemail]
    smtpserver = smtp.fastmail.com
    smtpuser = your-username@fastmail.whatev
    smtpencryption = ssl
    smtpserverport = 465
    smtppass = whatwasautogenerated

Also, if you haven't yet, run these commands - again making the appropriate changes:

git config --global user.email "you@example.org"
git config --global user.name "Your Name"

Next

If you already have an SMTP client installed, you can configure git send-email to use it by setting its command with sendemail.sendmailCmd. For example, to use msmtp you could add this to your global configuration file:

[sendemail]
    sendmailCmd = /usr/bin/msmtp

If you have multiple accounts configured for your SMTP client and want to specify one, you can add the required command parameters in the sendemail.sendmailCmd setting. For example, to choose an account named work configured for msmtp:

[sendemail]
    sendmailCmd = /usr/bin/msmtp -a work

Please note that the sendemail.sendmailCmd setting was added in Git 2.33. If you use an older version of Git, you must add the path to your SMTP client as sendemail.smtpserver, and parameters as multiple sendemail.smtpserveroption. For example, the previous msmtp configuration would be:

[sendemail]
    smtpserver = /usr/bin/msmtp
    smtpserveroption = -a
    smtpserveroption = work

Next

Your email provider should have instructions somewhere for SMTP access. Look these details up, and then add the following details from your mail provider:

[sendemail]
	smtpserver = mail.example.org
	smtpuser = you@example.org
	smtpencryption = ssl
	smtpserverport = 465

Be sure to fill in the appropriate values for your email provider - you will probably only have to fill in smtpserver and smtpuser. Also, if you haven't yet, run these commands - again, making the appropriate changes:

git config --global user.email "you@example.org"
git config --global user.name "Your Name"
Next

This configuration assumes direct TLS. If your provider only offers STARTTLS, set smtpencryption = tls and smtpserverport = 587.

If your system is already set up with sendmail, you may skip the [sendemail] git configuration instructions.

Step three Give it a shot!

It's time to take it for a spin - we're going to send a patch. Ready?

  1. Clone the upstream repository. No need to make a fork! We have prepared a repository for you to test with:
    git clone https://git.sr.ht/~sircmpwn/email-test-drive
    cd email-test-drive
  2. Make your changes. Let's add a file with your progress so far:
    echo "I'm about to try git send-email" >your-name
    Be sure to change your-name to your own!
  3. Commit your changes. Check out the official (and free) Pro Git book if you don't know how to do this.
    git add your-name
    git commit -m "Demonstrate that I can use git send-email"
  4. Send the patch! If you check out the README.md file, you'll note that patches should be sent to ~sircmpwn/email-test-drive@lists.sr.ht.
    git send-email --to="~sircmpwn/email-test-drive@lists.sr.ht" HEAD^
    If prompted for an In-Reply-To, you can ignore it for now (just press enter). Follow the rest of the prompts and you've done it! If you have any problems at this step, feel free to email us for help. If it worked, you should see your email appear in the mailing list archives momentarily!
  5. Check your inbox... someone has some feedback on your patch!
Next
Warning! Some people think that they can get away with sending patches through some means other than git send-email, but you can't. Your patches will be broken and a nuisance to the maintainers whose inbox they land in. Follow the golden rule: just use git send-email.

Step four Dealing with feedback

No one ever gets it right on the first try. Don't worry, it's all part of the process! You may receive some feedback on your patch from the maintainers of the software. This feedback will arrive in the form of a reply to your email. If you have any questions, just reply back - and remember to "reply all"! In the meantime, let's fix the patch.

In this tutorial, the feedback was generated by a bot, but feel free to reply to get the hang of it. You need to make sure your email client is configured to write emails in plain text before you do, and please try to avoid top posting. We also have an etiquette guide that'll help you avoid any faux pas.
  1. Make the changes. Update the files to match the changes requested by the maintainers. We'll leave this to you.
  2. Amend your commit. Git is designed for you to edit your commit history. It's not set in stone! The maintainers reviewing your work don't want to merge a patch which has mistakes, even if it's followed up by a fix, so you'll have to amend your previous commit:
    git commit -a --amend

    First time amending a commit? Amending and rebasing commits is an essential skill in this workflow. Check out our comprehensive guide to git rebase if you'd like to learn more.

  3. Set the default "to" address. Let's make this easier on ourselves by setting the default email address for this repo, so we needn't enter it every time:
    git config sendemail.to "~sircmpwn/email-test-drive@lists.sr.ht"
  4. Send the new patch! This time we'll use -v2 to indicate that this is the second version of this patch. If we do this again, we'll use -v3.
    git send-email --annotate -v2 HEAD^

    Note that we also specified the "--annotate" flag. This is going to open the email in our editor before sending it out, so we can make any changes. We're going to add some "timely commentary". Look for the "---" and add a short summary of the differences since the first patch on the next line. It should look something like this:

    Subject: [PATCH v2] Demonstrate that I can use git send-email
    
    ---
    This fixes the issues raised from the first patch.
    
    your-name | 1 +
    1 file changed, 1 insertion(+)

    This text gives the maintainers some extra context about your patch, but doesn't make it into the final git log. Close your editor, follow the prompts again, and that's it - you're done! Congratulations!

    If you want some more tips on using git send-email, check out the next page.

Next

Tips & tricks

Here are a few more tips and tricks which may serve you well as you use git send-email.

Reviewing patches you've received via email

Now you know the contributor workflow. Ready to learn about the other side?

Check out our next tutorial: Reviewing git contributions via email on git-am.io

Sending several patches at once

Use this to send the last 3 commits:

git send-email HEAD~3

Or all commits since a particular one:

git send-email 209210d

Or just the second-to-last commit:

git send-email -1 HEAD^^

See Revision Selection for more.

Sending patches with a cover letter

Not all changes are straightforward and self-contained. When a change requires several commits, a cover letter can be added as the starting point of the email thread.

git send-email --cover-letter origin/master
The --cover-letter option belongs to the git format-patch command and is not documented in the git-send-email(1) manual.

This will generate an extra email template with placeholders for the subject and main body:

Subject: [PATCH 0/3] *** SUBJECT HERE ***

*** BLURB HERE ***

your-name (3):
  core: Move reusable foo logic to a new function
  core: Add new flag to the aforementioned foo()
  cmd: New foo subcommand similar to bar

 core.c  |  38 ++++++++------
 cmd.c   |  13 ++++
 2 files changed, 34 insertions(+), 17 deletions(-)

--

In the example above, the subject could become:

Subject: [PATCH 0/3] Derive a foo subcommand from bar

The cover letter could then explain why a new subcommand is needed, and why it cannot or should not be implemented as an option to the existing subcommand that shares some aspects. A cover letter offers a convenient place to provide the rationale behind a change.

Since the default template includes a short log, it can also be useful to add a summary of the structure of a patch series. It could for example start with refactoring commits to prepare the actual change, and that change could also span multiple commits. A complicated change is likely easier to implement and review when decomposed into smaller logical chunks with a clear progression.

Other relevant information that does not necessarily belong in a commit log can be added to a cover letter, such as benchmark results, links to discussions on other forums or literature on the topic. As such, even a single patch submission may benefit from a cover letter.

Specifying a sub-project

Some projects use a single mailing list for several git repositories. Try this to clarify that you're working on the "foobar" project:

git config format.subjectPrefix "PATCH foobar"

Using --annotate every time

git config --global sendemail.annotate yes

"Signing off" on your commits

Some projects, such as the Linux kernel, will ask you to "sign off" on your commits. To do this, add --signoff (or -s) to git send-email. To set it as the default for that git repository:

git config format.signOff yes

The meaning of a signoff depends on the project to which you’re committing. For example, it may certify that the committer has the rights to submit the work under the project’s license or agrees to a Developer Certificate of Origin (DCO). Consult the documentation or leadership of the project to which you’re contributing to understand how the signoffs are used in that project.

More approaches to authentication

Some of the setups in this tutorial cause send-email to prompt for your password, which you may find annoying. There are other ways to authenticate - the simplest of which is:

git config --global sendemail.smtpPass 'your password'

You can also have your password cached in memory for a certain period of time. To cache it for one hour, use:

git config --global credential.helper 'cache --timeout 3600'

For more sophisticated solutions, such as integration with your keyring, see the git-credential man page.

Step one Installation

Let's start by installing the appropriate packages for your operating system.

The git package includes the git email tools, though you might need to install a few additional packages to get it fully working. Run this to install it:

sudo pacman -Syu --needed git perl-authen-sasl perl-io-socket-ssl
Next

The git-email package includes the git email tools. Run this to install it:

sudo apk add git git-email
Next

The git-email package includes the git email tools. Run this to install it:

sudo yum install git git-email
Next

The git-email package includes the git email tools. Run this to install it:

sudo apt install git git-email
Next

The git-email package includes the git email tools. Run this to install it:

sudo dnf install git git-email
Next

The git package includes the git email tools. Run this to install it:

pkg install git

Or, to install from ports:

cd /usr/ports/devel/git && make install clean
Next

The git package includes the git email tools. Run this to install it:

emerge dev-vcs/git
Next

The git package's send-email output contains the git email tools. Run this to install both git and the email tools:

guix package -i git git:send-email
Next

All of the usual ways to install git on macOS include the git email tools by default, including Apple's developer tools as well as Homebrew, MacPorts, and the official git bundle from git-scm.com.


The easiest way is to just run:

git

If git is not installed already, you will be prompted to install the Apple command line developer tools.

It may be necessary to install missing perl SSL modules by hand:

sudo -H cpan Net::SMTP::SSL IO::Socket::SSL

Next

The gitFull package includes the git email tools. To install it imperatively, run:

nix-env -iA nixos.gitFull

Alternatively, to install it declaratively, add:

programs.git.package = pkgs.gitFull;

to configuration.nix, or home.nix if you use home-manager. Make sure programs.git.enable is enabled.

Next

The git package includes the git email tools. Run this to install it:

pkg install git
Next

The git package includes the git email tools. Run this to install it:

pkg_add git p5-Authen-SASL p5-Net-SMTP-SSL

Or, to install from ports:

cd /usr/ports/devel/git && make install clean && cd ../../security/p5-Authen-SASL && make install clean && cd ../../net/p5-Net-SMTP-SSL && make install clean
                
Next

The git-email package includes the git email tools. Run this to install it:

sudo dnf install git-email
Next

The git-email package includes the git email tools. Run this to install it:

sudo zypper install git-email
Next

The devel/git package includes the git email tools. Run this to install it:

sudo pkg_add git

Or, to build from source:

cd /usr/pkgsrc/devel/git && make install 
Next

The git-email package includes the git email tools. Run this to install it:

sudo dnf install git git-email
Next

The git package includes the git email tools. Run this to install it:

sudo eopkg install git
Next

The git-email package includes the git email tools. Run this to install it:

sudo apt install git git-email
Next

The git package includes the git email tools. Run this to install it:

sudo xbps-install -S git
Next

The official git bundle from git-scm.com includes the git email tools.

Next
Don't see your OS here? Consult your OS documentation for installation, and once you finish this tutorial, send a patch adding yours to our git repository.