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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.