{"thread":{"id":"52027","subject":"[PATCH] contrib: git-cpcover: copy cover letter","startedAt":"2019-10-13T11:50:43Z","lastAt":"2019-10-13T11:50:43Z","messageCount":1,"participants":["Michael S. Tsirkin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"383991","messageId":"20191013115006.4650-1-mst@redhat.com","threadId":"52027","inReplyTo":null,"subject":"[PATCH] contrib: git-cpcover: copy cover letter","fromName":"Michael S. Tsirkin","fromEmail":"mst@redhat.com","sentAt":"2019-10-13T11:50:32Z","receivedAt":"2019-10-13T11:50:43Z","isPatch":true,"sender":{"key":"mst@kernel.org","avatar":null},"body":"My flow looks like this:\n1. git format-patch -v<n> --cover-letter <params> -o <dir>\n2. vi <dir>/v<n-1>-0000-cover-letter.patch <dir>/v<n>-0000-cover-letter.patch\n\ncopy subject and blurb, avoiding patchset stats\n\n3. add changelog update blurb as appropriate\n\n4. git send-email <dir>/v<n>-*\n\nThe following perl script automates step 2 above.  Hacked together\nrather quickly, so I'm only proposing it for contrib for now.  If others\nsee the need, we can add docs, tests and move it to git proper.\n\nSigned-off-by: Michael S. Tsirkin <mst@redhat.com>\n---\n contrib/git-cpcover | 80 +++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 80 insertions(+)\n create mode 100755 contrib/git-cpcover\n\ndiff --git a/contrib/git-cpcover b/contrib/git-cpcover\nnew file mode 100755\nindex 0000000000..d80bd141ba\n--- /dev/null\n+++ b/contrib/git-cpcover\n@@ -0,0 +1,80 @@\n+#!/usr/bin/perl -i\n+\n+use strict;\n+\n+die \"Usage: ${0} <from> [<to>]\" unless $#ARGV == 0 or $#ARGV == 1;\n+\n+my $ffrom = shift @ARGV;\n+my @extraheaders = ();\n+\n+open(FROM, \"<\", $ffrom) || die \"Can not open $ffrom\";\n+\n+my @from = ();\n+while (<FROM>) {\n+\tpush @from, $_;\n+}\n+\n+close(FROM) || die \"error closing $ffrom\";\n+\n+#get subject\n+my $subj;\n+my $bodyi;\n+for (my $i = 0; $i <= $#from; $i++) {\n+\t$_ = $from[$i];\n+\t#print STDERR \"<$line>\\n\";\n+\tif (not defined ($subj) and s/^Subject: \\[[^]]+\\] //) {\n+\t\t$subj = $_;\n+\t\tchomp $subj;\n+\t}\n+\tif (m/^(To|Cc):/) {\n+\t\tpush @extraheaders, $from[$i];\n+\t}\n+\tif (defined ($subj) and m/^$/) {\n+\t\t$bodyi = $i + 1;\n+\t\tlast;\n+\t}\n+}\n+\n+die \"No subject found in $ffrom\" unless defined($subj);\n+\n+die \"No body found in $ffrom\" unless defined($bodyi);\n+\n+my $bodyl;\n+my $statb;\n+my $state;\n+for (my $i = $#from; $i >= $bodyi; $i--) {\n+\t$_ = $from[$i];\n+\t$statb = $i if m/ [0-9]+ files changed, [0-9]+ insertions\\(\\+\\), [0-9]+ deletions\\(-\\)/;\n+\tnext unless defined($statb);\n+\t$state = $i if m/^$/;\n+\tnext unless defined($state);\n+\tnext if m/^$/;\n+\tnext if m/^  [^ ]/;\n+\tnext if m/\\([0-9]+\\):$/;\n+\t$bodyl = $i;\n+\tlast;\n+}\n+\n+die \"No body found in $ffrom\" unless defined($bodyl);\n+\n+#print STDERR $bodyi, \"-\", $bodyl, \"\\n\";\n+my $blurb = join(\"\", @from[$bodyi..$bodyl]);\n+\n+my $gotsubj = 0;\n+my $gotblurb = 0;\n+my $gotendofheaders = 0;\n+while (<>) {\n+\tif (not $gotsubj and\n+\t    s/\\*\\*\\* SUBJECT HERE \\*\\*\\*/$subj/) {\n+\t\t$gotsubj = 1;\n+\t}\n+\tif (not $gotblurb and\n+\t    s/\\*\\*\\* BLURB HERE \\*\\*\\*/$blurb/) {\n+\t\t$gotblurb = 1;\n+\t}\n+\tif (not $gotendofheaders and m/^$/) {\n+\t\tprint join(\"\", @extraheaders);\n+\t\t$gotendofheaders = 1;\n+\t}\n+\tprint $_;\n+}\n-- \nMST\n\n"}]}