[retitling in case there is a wider audience] On Tue, Jan 13, 2015 at 02:48:15PM -0800, Stefan Beller wrote: > Would you mind to share (parts of) the wrapper script? We could see if that > makes sense to incorporate into format-patch as well. Sure, but I'll warn you it's kind of gross and specific to my workflow. :) The script (which I call mpatch) is at the end of this message. The main thing which may be of interest to other people is the cover-letter handling. I write my cover letters in my normal MUA (mutt), and then generate the series as a reply to that. The two ways it supports that are: 1. It generates the list of patches that I include in my cover letter from the mbox. This _should_ be a "git log" one-liner, but our --pretty placeholders do not know how to count. Ideally I could say "[%i/%n]: %s", but neither of those first two exist (and %n would require counting all of the commits first, which might require some surgery to git-log). 2. Given an existing message, it will pick out the to, cc, and message-id headers, and generate corresponding --to, --cc, and --in-reply-to arguments to feed to format-patch. I do it hackily in perl, but probably format-patch could do it internally if it built on git-mailinfo. I typically have my MUA in one terminal and a shell running git in the other. Even though I could run mpatch directly from the MUA, it is often missing the context of which repo I am working in. So instead, I typically use ~/patch as a go-between for the two sessions (both for generating patch series, but also for applying with git-am). So I have this in my muttrc: macro pager,index D '<shell-escape>rm -f $HOME/patch<enter>' macro pager,index A '<copy-message>~/patch<enter><enter>' Applying a patch series from the list is just 'D' to clear the state, then 'A' to collect whatever patches. And then I "git am ~/patch" from the terminal window. Generating a patch series is more like: 1. "mpatch >~/patch" from the git terminal to generate the list of commits. No arguments necessary, because it uses @{upstream} as the base (but occasionally I use "-3" or similar if I am sending out new patches on top of somebody else's work). 2. Reply or start a new thread in mutt, as normal. This becomes the cover letter (the to/cc comes from the reply, or I have mutt aliases for the list and frequent contributors, and/or I may cut and paste from "git log" in some cases). Mutt dumps me in vim to write the actual message, and I ":r ~/patch" to pull it in. 3. Finish and send off the cover letter. This gives it a message-id. 4. Drop the newly-sent message into ~/patch. I usually just open my sent folder and use 'D', 'A' to copy it there. 5. "mpatch" from the git terminal. The headers are picked up from ~/patch. Sometimes I use "-v2", which is passed to format-patch to get "[PATCH v2 i/n]". After that, I'm in mutt with an mbox full of the patches. I have this hotkey in mutt: macro index,pager b ":set edit_headers=yes<enter><resend-message>:set edit_headers=no<enter>" which dumps me vim, with the headers. From there I give a final proofread, write any comments below the "---", and then send it. I imagine for the last bit many people have a similar workflow without mutt that is something like: 1. format-patch into ~/patch/* 2. $EDITOR ~/patch/* 3. git send-email ~/patch/* Those people would potentially benefit from the format-patch in step 1 picking up the headers from an existing message. -Peff -- >8 -- #!/bin/sh upstream_branch() { current=`git symbolic-ref HEAD` upstream=`git for-each-ref --format='%(upstream)' "$current"` if test -n "$upstream"; then echo $upstream else echo origin fi } get_reply_headers() { perl -ne ' if (defined $opt && /^\s+(.*)/) { $val .= " $1"; next; } if (defined $opt) { print "--$opt=", quotemeta($val), " "; $opt = $val = undef; } if (/^(cc|to):\s*(.*)/i) { $opt = lc($1); $val = $2; } elsif (/^message-id:\s*(.*)/i) { $opt = "in-reply-to"; $val = $1; } ' } has_nonoption= for i in "$@"; do case "$i" in -[0-9]) has_nonoption=yes ;; -*) ;; *) has_nonoption=yes esac done : ${REPLY:=$HOME/patch} test -n "$REPLY" && eval "set -- `get_reply_headers <\"$REPLY\"` \"\$@\"" test "$has_nonoption" = "yes" || set -- "$@" `upstream_branch` git format-patch -s --stdout --from "$@" >.mbox if test -t 1; then mutt -f .mbox else perl -lne ' if (/^Subject: (.*)/) { $subject = $1; } elsif ($subject && /^\s+(.*)/) { $subject .= " $1"; } elsif ($subject) { print $subject; $subject = undef; } ' .mbox | sed -e 's/\[PATCH /[/' \ -e 's/]/]:/' \ -e 's/^/ /' fi rm -f .mbox -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html