In 2009, I wrote a blog post How to submit a patch by email, which became popular at the time and also ended up in the PostgreSQL wiki. That article was written pre-Git and pre-cfbot, so maybe it’s time for a refresher, as we head into the next PostgreSQL development cycle.
The short answer is: Use
format-patch. That takes
care of almost all of the conventions and details. Looking at the
upcoming commit fests, it
appears that the vast majority of patch submissions already use that.
But I suspect that in some cases people produce the patches in some
other way and then rename them to look like what other people are
doing, without knowing about
Here is the basic workflow:
$ git checkout -b my-feature-branch # hack hack hack $ git commit ... $ git format-patch master 0001-Add-my-feature.patch
And if you later update your patch and want to send in a new version, you can do:
# hack hack hack $ git commit --amend --reset $ git format-patch -v2 master v2-0001-Add-my-feature.patch
(You can also version your first patch as
-v1. Or you can try to be
optimistic and hope your patch won’t require a second version. ;-) )
You can also split up your submission into multiple commits:
$ git checkout -b my-feature-branch # hack hack hack $ git add ... $ git commit ... $ git add ... $ git commit ... $ git format-patch master 0001-Some-refactoring.patch 0002-Add-my-feature.patch
Exactly how to split up a submission into commits sensibly is perhaps the subject of another article, but in general it’s something that is encouraged and welcome.
Note the following features of what
git format-patch produces:
Patch files automatically get a descriptive name.
Patch files get the correct file extension.
Patch files are numbered so they sort easily.
When using versions, files belonging to a version sort together. (The alternative manual naming like “my-feature-v2.patch” is therefore wrong.)
git format-patch is based on commits, not working
tree state (like
git diff), it requires you to write a commit
message, which is highly encouraged, even if you are not a committer.
Obviously, the accompanying email will normally explain the patch as
well, but as threads get longer, it is no longer easy to find that
information. Having an up-to-date explanation in the patch itself is
vastly preferrable. Also, some committer will eventually have to
write the commit message. Getting that process started early makes
the final commit easier.
Also note that the output of
git format-patch is designed to be fed
git am to apply the patches.
I can easily apply a sequence of patches like this:
v5-*.patch. Doing it any other way takes much longer and is much
git format-patch has a lot of options, and trying to understand them
all can be overwhelming. For PostgreSQL work, you need almost none of
them. Here are a few options can you play with:
-2, etc.: This specifies how many commits from the HEAD to make patches for. In the invocation that I have shown,
git format-patch master, it starts from where your development branch forked off the
masterbranch. This is usually the best way to do it. But in some cases, if you have a complicated branch structure or made a mess, specifying it numerically is a good workaround.
--patience, and other diff algorithm options: This is optional, but in some cases choosing a different diff algorithm can make the patch look a bit nicer.
-Oorderfile: This can change the order of the files in the patch. See this blog post for an example. Personally, I wouldn’t go quite as far as that article suggests, because then it will make it harder for a reviewer to find the files in the patch if they don’t know the orderfile. The normal order that ends up being, doc, code, tests, is usually pretty sensible. Maybe move
contribto the end if your patch has to touch it but it’s not the primary focus of the patch.
--base: This option records what commit your patch series was based on. So someone who wants to apply the patch can use the same commit to apply it on, to avoid merge conflicts and guessing. To invoke it, just do something like
git format-patch master --base master.
I do want to retract from my previous article the point about diffstats. I have come to find them useful. Leave them in, they don’t take up much space and don’t hurt anything.
Now finally, here is the most important thing when sending a patch,
git format-patch cannot help you with. Make sure
your email program sends the attachments with an appropriate content
type. It should be
text/something, but not
application/octet-stream. The latter
makes it harder to look at the patch in the email client or in the
email archives on
the web. If I’m casually browing patches, if an attachment is sent as
application/octet-stream, I’m much less likely to look at it. There
are plenty of other patches to look at that don’t have that problem.
- patches generated with
git format-patchand applicable with
- sent using suitable email content type