I recently found out a few awesome tricks for git send-email that have made my life much easier, so I decided to share them here
First, git send-email is an essential tool in every git guru’s arsenal, as it’s the preferred way of submitting patches. All you need to do is generate your patches with git format-patch (preferably with a cover letter), and then use git send-email to send those patches inlined in a nicely formatted email thread with your MTA.
But do you know about the different threading formats, address-book queries, or the cc-cmd option? No? Well, let’s get started.
Threading formats
By default git uses the deep threading format, which looks somewhat like this:
foobar patch 0 +-foobar patch 1 +-foobar patch 2 | +-foobar patch 3 | +-foobar patch 4 | | +-foobar patch 5 | +-comment on patch 3 +-comment on patch 1
This looks really nasty, specially for very big patch series. That’s why for v1.7.0 the default format would be the shallow one:
foobar patch 0 (usually a summary/overview) +-foobar patch 1 | +-comment on patch 1 +-foobar patch 2 +-foobar patch 3 | +-comment on patch 3 +-foobar patch 4 +-foobar patch 5
So, if you want to be nice with your patch reviewers, all you have to do is:
git config --global sendemail.chainreplyto false
Read Junio’s email for more details.
Address-book
Sometimes it becomes tedious to manually specify each person’s name and email address in the command line, such as:
git send-email --to "John Doe <john.doe@gmail.com>" *.patch
That’s why git send-email has a nice feature called ‘aliases’. With this, you can use your address-book from MUA’s such as mutt, mailrc, pine, elm, and gnus. Once you configure ‘sendemail.aliasesfile’ and ‘sendemail.aliasfiletype’ properly you don’t have to type emails again:
git send-email --to juha --cc mark --cc rene --cc marco *.patch
cc-cmd
Now, sending an email to a mailing list might not be enough to get your patch accepted, so you probably want to CC the right people, but finding them usually takes some effort. That’s when ‘cc-cmd’ comes to the rescue. With the ‘cc-cmd’ option you can specify a command to run for each patch being sent; each line generated by this tool will be a person to be CC’ed.
For example, suppose I have a script that magically finds the people to CC:
magic-script 0001-simplify-the-user-configuration.patch
"Dan McGee" <foo@bar.com>
"J. Bruce Fields" <foo@bar.edu>
When I run:
git semd-email --cc-cmd magic-script 0001-simplify-the-user-configuration.patch
Dan and Bruce will be automatically CC’ed.
Pretty neat, huh? Now the only missing piece is the actual magic script. The Linux kernel has one called ‘get_maintainer.pl’, which is awesome, but it only works on their code-base, and unfortunately there doesn’t seem to be a generic one… until now.
The magic cc-cmd script
Suppose we have the following patch:
--- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -985,9 +985,8 @@ easiest way to do so is to make sure the following lines appear in a file named .gitconfig in your home directory: ------------------------------------------------ -[user] - name = Your Name Comes Here - email = you@yourdomain.example.com +$ git config --global user.name "Your Name Comes Here" +$ git config --global user.email you@yourdomain.example.com ------------------------------------------------ (See the "CONFIGURATION FILE" section of linkgit:git-config[1] for
Who should we CC in order to get this patch accepted? Well, probably the people that have touched those lines before. Fortunately git blame makes it easy:
git blame -L985,+9 -- Documentation/user-manual.txt
58c19d1f J. Bruce Fields file named .gitconfig in your home directory:
d19fbc3c J. Bruce Fields
d19fbc3c J. Bruce Fields ------------------------------------------------
d19fbc3c J. Bruce Fields [user]
d19fbc3c J. Bruce Fields name = Your Name Comes Here
d19fbc3c J. Bruce Fields email = you@yourdomain.example.com
d19fbc3c J. Bruce Fields ------------------------------------------------
d19fbc3c J. Bruce Fields
5162e697 Dan McGee (See the "CONFIGURATION FILE" section of linkgit:git-config[1] for
Bang! That’s exactly what we need. For each chunk the patch is touching, we get the authors, and put them in the CC list. That way not only we make sure that the patch gets accepted, but also that the changes are properly reviewed.
I wrote a script that does exactly that, you can find it on gist.github.com.
Final notes
Here’s my example configuration for the git project:
sendemail.aliasesfile=/home/felipec/.mutt/aliases sendemail.aliasfiletype=mutt sendemail.chainreplyto=false sendemail.to=git@vger.kernel.org sendemail.cccmd=git-cc
Usually my patches are on top of the ‘master’ branch, I always add a cover-letter, and review them before sending, so:
git format-patch --cover-letter master
git send-email --annotate *.patch
Update, I found this shorter way:
git send-email --annotate --cover-letter master
If you don’t have a decent MTA, you can use msmtp to send your patches through Gmail, so really there’s no excuse not to send your patches properly
So let’s march and send patches all over the Interwebs™ powered by git
Nice article. I learnt about the cc-cmd.
Regarding the chainreply option, one reason I can think of using it is that the thread always appears ‘in-order’.
In the shallow version, the sequence of patches is often changed due to the nature of underlying IP network (mails might take different routes).
But for big patch series, I do prefer to read in the shallow format.
Lovely post. Speaking of which, truncated posts on planet.maemo.org are really annoying, could you please switch to a full feed?
@Marius Thanks. And, indeed, the truncated posts are really annoying, but they only appear that way in planet maemo.
I don’t see any option to change the feed format in WordPress but I’ll keep looking.
Pingback: felipec’s installation notes « Felipe Contreras
Just to let you know the “msmtp to send your patches” is broken.
@stefan Works for me… The kernel wiki has a lot of problems regularly.
BTW. I found that ‘git send-email’ can also do ‘git format-patch’ at the same time.
Ohh, if you meant that it was not linking to the proper subsection; fixed.