So I've been using the Github flow for some years now from both the maintainer side and contributor side to open source projects. I've also been using the email workflow for git from both sides for about a year now. Using email for git sounded quite horrible before I actually started using it. Now I prefer it so I thought I would document my experience here.

The Github flow

This isn't strictly for Github, it's the flow many developers are accustomed to:

  1. Fork the project repo
  2. Make a change on your fork
  3. Create a pull request from a branch on your fork to the main repository
  4. Get comments on the pull request
  5. Force-push to the same branch to update the state of the pull request
  6. Somebody clicks merge

Basically the same flow is also used on Gitlab and the other smaller git hosting services. This flow works reasonably well. It gets slightly more annoying after the first pull request because you actually have to keep your own local branch up to date.

In theory this also gives some nice discoverability of people working on the project by looking at the forks of the project. In practice this is a bunch of outdated copies of the project by people who have mistaken the fork button for a like button.

From a maintainer point of view this flow also works alright, unless your project starts to grow. For example when postmarketOS was still on Github we ran into the issue that the merge button isn't really useful. Once you have a reasonable volume of pull requests the branches of those pull requests get outdated quickly meaning they have to be rebased before merging or every change will have an extra merge commit in the history.

In the postmarketOS case it was decided that merge commits are extra noise in the git history we'd like to avoid so we'd need to rebase things, and to properly rebase we have to do it from the command line because Github can't deal at all with conflicts. Rebasing from the command line also gives a lot more flexibility with squashing and having a nice commit message.

The only reason that merge button was used on Github was because Github can't seem to mark the pull request as merged if it isn't done by the button.

The all-knowing button from Github

The old workflow documentation postmarketOS had when Github was used can be read in the wiki history:

Now we've moved to Gitlab we're basically dealing with the same issue, we have to mess with the commits before merging so we're always force-pushing to the git fork of the author of the pull request (which they have to enable on the merge request, if they don't we first have to tell them to enable that checkbox) and then finally merge them with the button in the web UI so Gitlab doesn't lose track of what happened.

The git-send-email flow

The flow for pull requests in github isn't the original way to make pull requests. Since git was originally written for the development of the Linux kernel it has been designed with the workflow of the kernel in mind. The kernel uses mailing lists.

[insert image of horrified developers here]

The first patch I emailed was with the assistence of, I needed to learn how to use the email flow because at the time I was working on my very first kernel patch. This was quite a daunting task involing triple-checking everything against the patch submission documentation for Linux which describes the easy 16 step process.

Then after the final step the email gets sent out and you wait... for response emails.

Since then I've made contributions to projects hosted on Sourcehut, which also uses the email workflow, and now I also maintain some projects on this platform. For example Megapixels.

This is the workflow for submitting a patch to a project using the email flow:

  1. Clone the repository locally
  2. Make your changes on your local checkout
  3. Run git send-email with a ref pointing to one or a range of commits
  4. Get comments as response to the patch as emails, mirrored on the webpage of the mailing list
  5. Fix up your previous mistakes, run git send-email again with the -v2 argument to send an updated version
  6. The maintainer applies the patch from the email.

As a maintainer getting the patches like this is quite nice since unless there's a conflict you don't have to merge branches or rebase things, the patches is just ... a patch, it only has the changes from the author, not the full git history.

Also, one thing to note about the process above is that, except for receiving the feedback, it will never touch your mail client. Git does SMTP itself and make sure the emails you send out are up-to-spec so maintainers can apply the changes directly by feeding the email into git am

If your main complaint is that email is horrible to work with, the issue is most likely not email, it's probably your mail client.

One of the other main issues with the email workflow is that you can't just see the full state of the "pull request" because there's no nice pull request page to see what's happening. This is one of the main reasons I like the mailing lists on Sourcehut, the patch view fixes most of the visibility issues, for example this simple patch:

The overview of a patch submitted to a Sourcehut mailing list

There you see the patch description in the first block, which is in this case didn't have any extra text added in the git send-email stage, so it only shows a summary of the changes in this patch.

Below that is the actual patch, with the subject of the patch as header and then showing the full commit message below that if there were more lines and then the full diff. This patch can also be exported directly as a .patch file using the link right of the subject.

Finally, below the diff is a comment from Eyal who applied this patch to the development branch and thanked the author; the mailing list will generate a nice threaded view here if there's more discussion.

The block on the right will show the status of the patch, APPLIED in this case and gives some extra tools to get a copy of the full patchset that can be applied using git am


I personally prefer the e-mail workflow now, it saves me from keeping branches/forks up to date as with this workflow only diffs are sent around. Also after working in Gitlab for most of the things I do on postmarketOS I really like how quickly sourcehut pages load and that I just can get all info from the patch without clicking on tabs to switch between comments, diffs and commit messages with loading times in between.

Also one nice improvement is that instead of doing half the maintainer flow in the browser by clicking things and half by patching stuff up in my local git branch and force pushing that, it just lets me do everything in the shell and then just send an email back telling the author their patch got merged.

All together people are most likely already used to having all the comments and info emailed to them as notifications, it's just that in the gitlab/hub case it will send you a link to continue on their website and in the sourcehut/email flow case the email is everything you need to continue without ever opening the browser.