Patch workflow with mutt and git

1st

It's easy to grab a patch from a mailing list with mutt and get it merged on your local git tree.
The steps are quite simple:

1. Save a copy of the e-mail
mutt: shift+c (to copy), it will ask:
Copy to mailbox ('?' for list): =mailboxname
then you just need to provide the path, for example: /tmp/testing.mbox

2. Go to your git tree and merge the patch:
cd /path/to/your/git
git am /tmp/testing.mbox

3. If there is no conflict, you are good! Now you can build everything.

2nd

However, if you deal with more patches, then these steps above become annoying. Also, usually people have the e-mail on one system and the git tree one another build system. So, I tried to make life easier using a mutt's macro and a pair of scripts. 

The work flow is: You just need to tag every patch you like to apply using 't'. Then you run the new macro which in my case is 'ctrl+h' and all patches show up in the build system.

The first script is called 'procmail' which just call the real procmail passing a custom configuration:
$ cat mailtogit/procmail
/usr/bin/procmail -m ~/mailtogit/procmailrc -
----8<-----

and the custom configuration saves the e-mail in the ~/incoming directory which can be an autofs dir from your build system. Also, it saves the e-mail on a mbox with the name based on the email's subject.
$ cat mailtogit/procmailrc
SHELL=/bin/bash
VERBOSE=off
MAILDIR=$HOME/incoming/
LOGFILE=$HOME/incoming/.procmaillog

:0
`formail -xSubject: | sed -e '{ s/Subject: //; s@\[@@g; s@\]@@g; s@[()]@_@g; s@[/:]@-@g; s@"@_@g; s@^ \+@@; s@\.\.@.@g; s@ \+@_@g; s@-_@_@g; s@__@_@g; s@\.$@@; }'`.mbox

----8<-----
But mutt delivers all tagged messages at once, so instead of changing default's mutt behaviour, I wrote another script to deliver one e-mail at a time to procmail.

$ cat mailtogit/frommutt
formail -cds ~/mailtogit/procmail -
----8<-----
Now that the two scripts are ready, let's create the mutt's macro to use them. It's very simple, just copy the line below to your ~/.muttrc changing the path to the frommutt script:
macro index \Ch '<pipe-entry>/path/to/frommutt^M' "output git patches"


Testing:
Here is one example of grabbing patches from netdev mailing:
[...]
Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 2/8] sfc: Reduce size of efx_rx_buffer further by removin
Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 3/8] sfc: Read MC firmware version when requested through
Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 4/8] sfc: Do not read STAT1.FAULT in efx_mdio_check_mmd()
Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 5/8] sfc: Update copyright dates
Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 6/8] sfc: Expose TX push and TSO counters through ethtool
Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 7/8] sfc: Remove configurable FIFO thresholds for pause f
Mar 01 Ben Hutchings [ ] └─>[PATCH net-next-2.6 8/8] sfc: Bump version to 3.1
[...]

Tagging using 't', notice the '*' mark below:
[...]
* Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 2/8] sfc: Reduce size of efx_rx_buffer further by removin
* Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 3/8] sfc: Read MC firmware version when requested through
* Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 4/8] sfc: Do not read STAT1.FAULT in efx_mdio_check_mmd()
* Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 5/8] sfc: Update copyright dates
* Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 6/8] sfc: Expose TX push and TSO counters through ethtool
* Mar 01 Ben Hutchings [ ] ├─>[PATCH net-next-2.6 7/8] sfc: Remove configurable FIFO thresholds for pause f
* Mar 01 Ben Hutchings [ ] └─>[PATCH net-next-2.6 8/8] sfc: Bump version to 3.1
[...]

then after ctrl+h, this shows up in the ~/incoming directory:
$ ls ~/incoming/
PATCH_net-next-2.6_sfc_Reduce_size_of_efx_rx_buffer_by_unionising_skb_and_page.mbox
PATCH_net-next-2.6_2-8_sfc_Reduce_size_of_efx_rx_buffer_further_by_removing_data_member.mbox
PATCH_net-next-2.6_3-8_sfc_Read_MC_firmware_version_when_requested_through_ethtool.mbox
PATCH_net-next-2.6_4-8_sfc_Do_not_read_STAT1.FAULT_in_efx_mdio_check_mmd_.mbox
PATCH_net-next-2.6_5-8_sfc_Update_copyright_dates.mbox
PATCH_net-next-2.6_6-8_sfc_Expose_TX_push_and_TSO_counters_through_ethtool_statistics.mbox
PATCH_net-next-2.6_7-8_sfc_Remove_configurable_FIFO_thresholds_for_pause_frame_generation.mbox
PATCH_net-next-2.6_8-8_sfc_Bump_version_to_3.1.mbox

Now applying the patches:
$ ssh buildsystem
$ cd /storage/net-next-2.6/
$ git am /storage/incoming/*.mbox
Applying: sfc: Reduce size of efx_rx_buffer further by removing data member
Applying: sfc: Read MC firmware version when requested through ethtool
Applying: sfc: Do not read STAT1.FAULT in efx_mdio_check_mmd()
Applying: sfc: Update copyright dates
Applying: sfc: Expose TX push and TSO counters through ethtool statistics
Applying: sfc: Remove configurable FIFO thresholds for pause frame generation
Applying: sfc: Bump version to 3.1
$

That's it! Notice that usually the patch ordering is fine. But sometimes, you will need to pass the patches in the right order. In my example, the first patch didn't have the 1/8, so I had to apply it first and the rest.

You can also tag all patches and then copy using 'shift+c' to a mailbox and try to apply on git as well. But then you won't be able to change the patch order if you need to.

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐