From: Jeff King <peff@peff.net>
To: Stefan Beller <sbeller@google.com>
Cc: Junio C Hamano <gitster@pobox.com>,
Alexander Kuleshov <kuleshovmail@gmail.com>,
"git@vger.kernel.org" <git@vger.kernel.org>
Subject: my hacky mutt-specific format-patch workflow
Date: Tue, 13 Jan 2015 20:28:19 -0500 [thread overview]
Message-ID: <20150114012819.GA7520@peff.net> (raw)
In-Reply-To: <CAGZ79kZ87ZKT5-OMTEHAMEAmZVOfku_D4vZ9jcWJ4cHrA06cSw@mail.gmail.com>
[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
next prev parent reply other threads:[~2015-01-14 1:28 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-13 17:54 [PATCH] format-patch: print format-patch usage if there are no arguments Alexander Kuleshov
2015-01-13 18:43 ` Junio C Hamano
2015-01-13 18:52 ` Alexander Kuleshov
2015-01-13 19:17 ` Junio C Hamano
2015-01-13 20:00 ` Stefan Beller
2015-01-13 22:28 ` Junio C Hamano
2015-01-13 22:45 ` Jeff King
2015-01-13 22:48 ` Stefan Beller
2015-01-14 1:28 ` Jeff King [this message]
2015-01-13 23:41 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150114012819.GA7520@peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kuleshovmail@gmail.com \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).