Reviewing git contributions via email

You may have read our interactive guide on sending patches with git send-email and wondered — what does the other side of this workflow look like? This guide will introduce you to the tools and skills you need to efficiently review code via email.

Note: The tools and workflows maintainers use to manage this side of the git email workflow are much more diverse than the contributor side. This guide will teach you just one of many ways to approach the problem, and equip you with the tools and knowledge to develop your own personal workflow from this starting point.

The git email workflow is powerful and flexible — it is used by the largest free software projects in the world to manage extremely high volumes of contributions effectively. Let's get you acquainted with the tools of the trade so you can dive right in.

Table of Contents

  1. Introduction
  2. Introducing aerc
  3. Preparing the sandbox
  4. Reviewing a patch
  5. Applying and testing a patch
  6. Dealing with merge conflicts
  7. Advanced aerc usage
  8. Further resources

Introduction

Reviewing code via email is one of the simplest, most efficient, and most scalable approaches to code review. It can also be one of the most intimidating to get started with.

However, the crux of the workflow is simple: reviewing patches via email works the same way emails already work. You know how to use email — to review a patch you receive by email, you just reply to it with your feedback. There are some other tools we will familiarize you with, and some conventions and cultural norms to learn, but getting started with the basics is as easy as hitting "reply all".

Ultimately, everyone's email workflow is a bit different. No two maintainers agree on the best approach, and many people use different email clients, tools, custom scripts, workflows, and conventions. We'll just get you situated with an easy way to start in this tutorial and you can learn more and build a workflow that suits your needs over time. And, to any established mail users reading along: we're all sure that your preferred workflow is much better than the one explained here — but we can't please everyone 🙂

Introducing aerc

Effective use of the git email workflow requires you to choose an email client for which the workflow is comfortably accommodated for. This tutorial recommends aerc, an email client specifically designed to accommodate code reviews in your terminal emulator. It allows you to review patches comfortably, handles plain text emails well, and supports writing reviews in your editor of choice — vim, emacs, etc.

Wait, what? You probably already have an email client that you prefer, and switching to another is a lot to ask. You may also be uncomfortable with mixing code reviews into your personal or work email alongside everything else. Fair enough!

Just keep this in mind: you don't have to switch from your current email client of choice. You can just use both! aerc is lightweight and well-suited to being launched on-demand as a tool you only use during code reviews. Many people also use a separate email address just for development, or use mail filters to organize patches separately from other emails. Relax — you don't have to change your entire approach to email overnight to get started with code reviews via email.

aerc is probably available via your system package manager, and this is the recommended way to install it. The initial configuration is straightforward — just run `aerc` and follow the steps on screen. The built-in tutorial is sufficient to get you quickly acquainted with its usage, enough to move on to the rest of this tutorial. Here's a short screencast showing you what the process is like:

Warning: The screencast player is known to work poorly on mobile devices.

There are many other email clients you could choose, but this tutorial will assume you use aerc. Here are some other options you can research that work well with git:

Hey! Do you want to write a similar tutorial for your preferred mail client or email workflow to appear on this site? Email us with your proposal!

Let's move on to the next step: getting some code to review.

Preparing the sandbox

We have prepared a sandbox environment for you to experiment with the email workflow in, including a git repository based on real-world software prepared for you to experiment with and a sample of some real-world patches and discussions.

Tip: The sandbox is based on scdoc, a free software tool for authoring man pages, and the example emails are real-world discussions and contributions to this project. It was chosen for this purpose because it has no dependencies other than a POSIX and C11 compatible build environment, which most programmers already have available — so you can easily try compiling it and running the test suite if you want to get comfortable with the process.

Start by cloning the sandbox project on your machine:

git clone https://git.sr.ht/~sircmpwn/git-email-demo
cd git-email-demo
You can press Ctrl + T in aerc to open an embedded terminal to run these commands in.

Feel free to explore the code if you like — but don't worry if you're not comfortable with C, you don't need to be for this tutorial. You can compile it by running make and run the test suite with make check.

Next, we're going to import some sample emails into aerc. Start by downloading the sample archive and using the following aerc commands to import it:

  1. :mkdir sandbox — create a sandbox folder (:rmdir -f to remove it later)
  2. :import-mbox ~/Downloads/sample.mbox — edit the path as necessary
Note: The sample emails have been modified to remove the original senders' email addresses, so that you can reply to them without bothering the original participants — your replies will instead be sent to a public mailing list where you can review them online or see what others are up to.

You should see the sample emails appear in your sandbox folder now. You can press Shift + T to toggle a threaded view if you prefer.

Reviewing a patch

Feel free to browse the discussions in this mailbox and familiarize yourself with the aerc interface. Try a little code review — read some of these patches and their revisions.

Let's try re-enacting the feedback Rene Kita offered on version 1 of Kirill Chibisov's patch. Press rq to prepare a "quoted reply" to this patch and type in some feedback:

Note that I'm editing the quoted text of Chibisov's email here to narrow in on the specific parts that I have feedback for. You can freely edit the email you're replying to to include feedback inline, between quoted sections, in whatever manner makes your code review easiest to understand. Unlike some common email workflows, the git approach encourages you to make as many edits to the text you're quoting as necessary to make your feedback clear. You can see Rene Kita doing something similar in their own review.

Applying and testing a patch

The tool we use to merge these patches into our git repositories is called git amapply from mailbox. This tool accepts one or more email-formatted patches via the standard input and imports them onto the current branch of a git repository.

To import patches from aerc, you will first need to navigate aerc to the directory containing the git repository. You can see aerc's current working directory on the bottom right corner, in the status bar. To update it, use the :cd <directory> command, e.g. :cd git-email-demo. You can also navigate your shell to the directory you want beforehand and start aerc there.

Tip: New terminals you open (Ctrl + T) will open in aerc's current working directory.

Once we're situated in the appropriate git repository (maybe touching it up with git pull first), we can import the patches using aerc's pipe command. Pressing the pipe key | will prompt you to enter a command to pipe the selected email into. Move the cursor to a patch to import (try PATCH v3 from Chibisov), press the pipe key, and enter "git am" as the desired command. Press q once it completes to dismiss the command output.

You can also import several patches at once. Press v to mark one or more messages, then use the same pipe command to pass all of them at once to git am. Try this to import eschwartz's patches.

Once the patches you want are all imported, you can open a new terminal tab to review them more closely — running tests and so on. If you want to remove the patches, use git reset --hard, for instance git reset --hard origin/master will remove all patches which haven't yet been pushed to the upstream master branch.

Here's what the whole process looks like:

Once you've applied all of the patches you're satisfied with, run git push to send them upstream, and don't forget to thank the contributors for their patch! Note, however, that you don't have push access to the demo repository — just keep this in mind for when the time comes to review patches for your own projects.

Dealing with merge conflicts

Sometimes a patch will not apply cleanly if there have been changes to the upstream repository between the time the patch was written and the time of your code review. To address this case, we can use a three-way merge with git am, similar to git merge.

Simply run git am -3 instead of git am to request a three-way merge from git. This will allow git to resolve trivial conflicts itself, and leave any other conflicts for you to address on your own.

In case a patch did not apply cleanly with git am or git am -3, git will leave the repository in an intermediate state to allow you to examine it and resolve conflicts. To revert your course without applying a troublesome patch, use git am --abort to restore the repository to its prior state. Otherwise, as you resolve merge conflicts manually, use git add to mark each conflict as resolved, and finally git am --continue when all conflicts are resolved.

If you don't care to resolve the merge conflicts yourself, it's perfectly reasonable to ask the contributor to handle the rebase and to send you a new revision.

Advanced aerc usage

Here are some additional tips for getting the most out of aerc for code review.

aerc-patch(7)

aerc offers additional features for local management of patch sets which may be useful to those for whom the workflow is intuitive, particularly when managing many patches or many patch revisions. Consult aerc-patch(7) for more details.

Recommended keybindings for quick git use

You can add additional custom keybindings to ~/.config/aerc/binds.conf. Here are a few extra recommendations:

[messages]
# Apply the selected patch(es) and flag the email
ga = :flag<Enter>:pipe -mb git am -3<Enter>
# Run git push
gp = :term git push<Enter>
# Browse the git log
gl = :term git log<Enter>

Replying "thanks!"

Many aerc users have an email template which "thanks" contributors for their patch once applied and summarizes the git push that included it upstream. Add the following to ~/.config/aerc/templates/thanks:

Thanks!

{{exec "{ git remote get-url --push origin; git reflog -2 origin/master --pretty=format:%h | xargs printf '%s\n' | tac; } | xargs printf 'To %s\n   %s..%s  master -> master'" ""}}

And ~/.config/aerc/templates/quoted_thanks:

Thanks!

{{exec "{ git remote get-url --push origin; git reflog -2 origin/master --pretty=format:%h | xargs printf '%s\n' | tac; } | xargs printf 'To %s\n   %s..%s  master -> master'" ""}}

On {{dateFormat (.OriginalDate | toLocal) "Mon Jan 2, 2006 at 3:04 PM MST"}}, {{(index .OriginalFrom 0).Name}} wrote:
{{wrapText .OriginalText 72 | quote}}

Use :reply -Tthanks to reply to a patch with this template, or update binds.conf accordingly:

[messages]
rt = :reply -a -Tthanks<Enter>
Rt = :reply -qa -Tquoted_thanks<Enter>

Use rt to send a simple "thanks" message, or Rt to include a quote from the original message for further comment.

Further resources

Articles:

Videos:

Other: