{"thread":{"id":"19287","subject":"[PATCH] git-send-email: parse all messages in mbox","startedAt":"2009-05-11T13:46:51Z","lastAt":"2009-05-14T18:41:21Z","messageCount":5,"participants":["Vitaly Mayatskikh","Junio C Hamano","Jay Soffian"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"113538","messageId":"873abbeoqc.wl%vmayatsk@redhat.com","threadId":"19287","inReplyTo":null,"subject":"[PATCH] git-send-email: parse all messages in mbox","fromName":"Vitaly Mayatskikh","fromEmail":"v.mayatskih@gmail.com","sentAt":"2009-05-11T13:46:51Z","receivedAt":"2009-05-11T13:46:51Z","isPatch":true,"sender":{"key":"v.mayatskih@gmail.com","avatar":"https://gravatar.com/avatar/10e7872617c00157baad2014b42b6dedd1dc5bb97d2d050fa0ca97d63c592241?d=mp&s=160"},"body":"Currently git-send-email sends all mbox in one email. This seems to be wrong,\nbecause mbox can contain several messages. For example,\n`git format-patch --stdout' forms mbox file with all patches in it.\n\nThis patch allows git send-email to send several messages from one mbox\nseparately.\n\nSigned-off-by: Vitaly Mayatskikh <v.mayatskih@gmail.com>\n---\n git-send-email.perl |  278 ++++++++++++++++++++++++++-------------------------\n 1 files changed, 141 insertions(+), 137 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex cccbf45..614fcbd 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -984,168 +984,172 @@ $message_num = 0;\n foreach my $t (@files) {\n \topen(F,\"<\",$t) or die \"can't open file $t\";\n \n-\tmy $author = undef;\n-\tmy $author_encoding;\n-\tmy $has_content_type;\n-\tmy $body_encoding;\n-\t@cc = ();\n-\t@xh = ();\n-\tmy $input_format = undef;\n-\tmy @header = ();\n-\t$message = \"\";\n-\t$message_num++;\n-\t# First unfold multiline header fields\n-\twhile(<F>) {\n-\t\tlast if /^\\s*$/;\n-\t\tif (/^\\s+\\S/ and @header) {\n-\t\t\tchomp($header[$#header]);\n-\t\t\ts/^\\s+/ /;\n-\t\t\t$header[$#header] .= $_;\n-\t    } else {\n-\t\t\tpush(@header, $_);\n-\t\t}\n-\t}\n-\t# Now parse the header\n-\tforeach(@header) {\n-\t\tif (/^From /) {\n-\t\t\t$input_format = 'mbox';\n-\t\t\tnext;\n-\t\t}\n-\t\tchomp;\n-\t\tif (!defined $input_format && /^[-A-Za-z]+:\\s/) {\n-\t\t\t$input_format = 'mbox';\n+\twhile (1) {\n+\t\tmy $author = undef;\n+\t\tmy $author_encoding;\n+\t\tmy $has_content_type;\n+\t\tmy $body_encoding;\n+\t\t@cc = ();\n+\t\t@xh = ();\n+\t\tmy $input_format = undef;\n+\t\tmy @header = ();\n+\t\t$message = \"\";\n+\t\t$message_num++;\n+\t\t# First unfold multiline header fields\n+\t\twhile(<F>) {\n+\t\t\tlast if /^\\s*$/;\n+\t\t\tif (/^\\s+\\S/ and @header) {\n+\t\t\t\tchomp($header[$#header]);\n+\t\t\t\ts/^\\s+/ /;\n+\t\t\t\t$header[$#header] .= $_;\n+\t\t\t} else {\n+\t\t\t\tpush(@header, $_);\n+\t\t\t}\n \t\t}\n-\n-\t\tif (defined $input_format && $input_format eq 'mbox') {\n-\t\t\tif (/^Subject:\\s+(.*)$/) {\n-\t\t\t\t$subject = $1;\n+\t\t# Now parse the header\n+\t\tforeach(@header) {\n+\t\t\tif (/^From /) {\n+\t\t\t\t$input_format = 'mbox';\n+\t\t\t\tnext;\n \t\t\t}\n-\t\t\telsif (/^From:\\s+(.*)$/) {\n-\t\t\t\t($author, $author_encoding) = unquote_rfc2047($1);\n-\t\t\t\tnext if $suppress_cc{'author'};\n-\t\t\t\tnext if $suppress_cc{'self'} and $author eq $sender;\n-\t\t\t\tprintf(\"(mbox) Adding cc: %s from line '%s'\\n\",\n-\t\t\t\t\t$1, $_) unless $quiet;\n-\t\t\t\tpush @cc, $1;\n+\t\t\tchomp;\n+\t\t\tif (!defined $input_format && /^[-A-Za-z]+:\\s/) {\n+\t\t\t\t$input_format = 'mbox';\n \t\t\t}\n-\t\t\telsif (/^Cc:\\s+(.*)$/) {\n-\t\t\t\tforeach my $addr (parse_address_line($1)) {\n-\t\t\t\t\tif (unquote_rfc2047($addr) eq $sender) {\n-\t\t\t\t\t\tnext if ($suppress_cc{'self'});\n-\t\t\t\t\t} else {\n-\t\t\t\t\t\tnext if ($suppress_cc{'cc'});\n-\t\t\t\t\t}\n+\n+\t\t\tif (defined $input_format && $input_format eq 'mbox') {\n+\t\t\t\tif (/^Subject:\\s+(.*)$/) {\n+\t\t\t\t\t$subject = $1;\n+\t\t\t\t}\n+\t\t\t\telsif (/^From:\\s+(.*)$/) {\n+\t\t\t\t\t($author, $author_encoding) = unquote_rfc2047($1);\n+\t\t\t\t\tnext if $suppress_cc{'author'};\n+\t\t\t\t\tnext if $suppress_cc{'self'} and $author eq $sender;\n \t\t\t\t\tprintf(\"(mbox) Adding cc: %s from line '%s'\\n\",\n-\t\t\t\t\t\t$addr, $_) unless $quiet;\n-\t\t\t\t\tpush @cc, $addr;\n+\t\t\t\t\t       $1, $_) unless $quiet;\n+\t\t\t\t\tpush @cc, $1;\n \t\t\t\t}\n-\t\t\t}\n-\t\t\telsif (/^Content-type:/i) {\n-\t\t\t\t$has_content_type = 1;\n-\t\t\t\tif (/charset=\"?([^ \"]+)/) {\n-\t\t\t\t\t$body_encoding = $1;\n+\t\t\t\telsif (/^Cc:\\s+(.*)$/) {\n+\t\t\t\t\tforeach my $addr (parse_address_line($1)) {\n+\t\t\t\t\t\tif (unquote_rfc2047($addr) eq $sender) {\n+\t\t\t\t\t\t\tnext if ($suppress_cc{'self'});\n+\t\t\t\t\t\t} else {\n+\t\t\t\t\t\t\tnext if ($suppress_cc{'cc'});\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\tprintf(\"(mbox) Adding cc: %s from line '%s'\\n\",\n+\t\t\t\t\t\t       $addr, $_) unless $quiet;\n+\t\t\t\t\t\tpush @cc, $addr;\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\telsif (/^Content-type:/i) {\n+\t\t\t\t\t$has_content_type = 1;\n+\t\t\t\t\tif (/charset=\"?([^ \"]+)/) {\n+\t\t\t\t\t\t$body_encoding = $1;\n+\t\t\t\t\t}\n+\t\t\t\t\tpush @xh, $_;\n+\t\t\t\t}\n+\t\t\t\telsif (/^Message-Id: (.*)/i) {\n+\t\t\t\t\t$message_id = $1;\n+\t\t\t\t}\n+\t\t\t\telsif (!/^Date:\\s/ && /^[-A-Za-z]+:\\s+\\S/) {\n+\t\t\t\t\tpush @xh, $_;\n \t\t\t\t}\n-\t\t\t\tpush @xh, $_;\n-\t\t\t}\n-\t\t\telsif (/^Message-Id: (.*)/i) {\n-\t\t\t\t$message_id = $1;\n-\t\t\t}\n-\t\t\telsif (!/^Date:\\s/ && /^[-A-Za-z]+:\\s+\\S/) {\n-\t\t\t\tpush @xh, $_;\n-\t\t\t}\n \n-\t\t} else {\n-\t\t\t# In the traditional\n-\t\t\t# \"send lots of email\" format,\n-\t\t\t# line 1 = cc\n-\t\t\t# line 2 = subject\n-\t\t\t# So let's support that, too.\n-\t\t\t$input_format = 'lots';\n-\t\t\tif (@cc == 0 && !$suppress_cc{'cc'}) {\n-\t\t\t\tprintf(\"(non-mbox) Adding cc: %s from line '%s'\\n\",\n-\t\t\t\t\t$_, $_) unless $quiet;\n-\t\t\t\tpush @cc, $_;\n-\t\t\t} elsif (!defined $subject) {\n-\t\t\t\t$subject = $_;\n+\t\t\t} else {\n+\t\t\t\t# In the traditional\n+\t\t\t\t# \"send lots of email\" format,\n+\t\t\t\t# line 1 = cc\n+\t\t\t\t# line 2 = subject\n+\t\t\t\t# So let's support that, too.\n+\t\t\t\t$input_format = 'lots';\n+\t\t\t\tif (@cc == 0 && !$suppress_cc{'cc'}) {\n+\t\t\t\t\tprintf(\"(non-mbox) Adding cc: %s from line '%s'\\n\",\n+\t\t\t\t\t       $_, $_) unless $quiet;\n+\t\t\t\t\tpush @cc, $_;\n+\t\t\t\t} elsif (!defined $subject) {\n+\t\t\t\t\t$subject = $_;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n-\t}\n-\t# Now parse the message body\n-\twhile(<F>) {\n-\t\t$message .=  $_;\n-\t\tif (/^(Signed-off-by|Cc): (.*)$/i) {\n-\t\t\tchomp;\n-\t\t\tmy ($what, $c) = ($1, $2);\n-\t\t\tchomp $c;\n-\t\t\tif ($c eq $sender) {\n-\t\t\t\tnext if ($suppress_cc{'self'});\n-\t\t\t} else {\n-\t\t\t\tnext if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i;\n-\t\t\t\tnext if $suppress_cc{'bodycc'} and $what =~ /Cc/i;\n+\t\t# Now parse the message body\n+\t\twhile(<F>) {\n+\t\t\tlast if /^From /; # Next message in file\n+\t\t\t$message .=  $_;\n+\t\t\tif (/^(Signed-off-by|Cc): (.*)$/i) {\n+\t\t\t\tchomp;\n+\t\t\t\tmy ($what, $c) = ($1, $2);\n+\t\t\t\tchomp $c;\n+\t\t\t\tif ($c eq $sender) {\n+\t\t\t\t\tnext if ($suppress_cc{'self'});\n+\t\t\t\t} else {\n+\t\t\t\t\tnext if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i;\n+\t\t\t\t\tnext if $suppress_cc{'bodycc'} and $what =~ /Cc/i;\n+\t\t\t\t}\n+\t\t\t\tpush @cc, $c;\n+\t\t\t\tprintf(\"(body) Adding cc: %s from line '%s'\\n\",\n+\t\t\t\t       $c, $_) unless $quiet;\n \t\t\t}\n-\t\t\tpush @cc, $c;\n-\t\t\tprintf(\"(body) Adding cc: %s from line '%s'\\n\",\n-\t\t\t\t$c, $_) unless $quiet;\n \t\t}\n-\t}\n-\tclose F;\n \n-\tif (defined $cc_cmd && !$suppress_cc{'cccmd'}) {\n-\t\topen(F, \"$cc_cmd $t |\")\n-\t\t\tor die \"(cc-cmd) Could not execute '$cc_cmd'\";\n-\t\twhile(<F>) {\n-\t\t\tmy $c = $_;\n-\t\t\t$c =~ s/^\\s*//g;\n-\t\t\t$c =~ s/\\n$//g;\n-\t\t\tnext if ($c eq $sender and $suppress_from);\n-\t\t\tpush @cc, $c;\n-\t\t\tprintf(\"(cc-cmd) Adding cc: %s from: '%s'\\n\",\n-\t\t\t\t$c, $cc_cmd) unless $quiet;\n+\t\tif (defined $cc_cmd && !$suppress_cc{'cccmd'}) {\n+\t\t\topen(CC_CMD, \"$cc_cmd $t |\")\n+\t\t\t    or die \"(cc-cmd) Could not execute '$cc_cmd'\";\n+\t\t\twhile(<CC_CMD>) {\n+\t\t\t\tmy $c = $_;\n+\t\t\t\t$c =~ s/^\\s*//g;\n+\t\t\t\t$c =~ s/\\n$//g;\n+\t\t\t\tnext if ($c eq $sender and $suppress_from);\n+\t\t\t\tpush @cc, $c;\n+\t\t\t\tprintf(\"(cc-cmd) Adding cc: %s from: '%s'\\n\",\n+\t\t\t\t       $c, $cc_cmd) unless $quiet;\n+\t\t\t}\n+\t\t\tclose CC_CMD\n+\t\t\t    or die \"(cc-cmd) failed to close pipe to '$cc_cmd'\";\n \t\t}\n-\t\tclose F\n-\t\t\tor die \"(cc-cmd) failed to close pipe to '$cc_cmd'\";\n-\t}\n \n-\tif (defined $author and $author ne $sender) {\n-\t\t$message = \"From: $author\\n\\n$message\";\n-\t\tif (defined $author_encoding) {\n-\t\t\tif ($has_content_type) {\n-\t\t\t\tif ($body_encoding eq $author_encoding) {\n-\t\t\t\t\t# ok, we already have the right encoding\n+\t\tif (defined $author and $author ne $sender) {\n+\t\t\t$message = \"From: $author\\n\\n$message\";\n+\t\t\tif (defined $author_encoding) {\n+\t\t\t\tif ($has_content_type) {\n+\t\t\t\t\tif ($body_encoding eq $author_encoding) {\n+\t\t\t\t\t\t# ok, we already have the right encoding\n+\t\t\t\t\t}\n+\t\t\t\t\telse {\n+\t\t\t\t\t\t# uh oh, we should re-encode\n+\t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\telse {\n-\t\t\t\t\t# uh oh, we should re-encode\n+\t\t\t\t\tpush @xh,\n+\t\t\t\t\t'MIME-Version: 1.0',\n+\t\t\t\t\t\"Content-Type: text/plain; charset=$author_encoding\",\n+\t\t\t\t\t'Content-Transfer-Encoding: 8bit';\n \t\t\t\t}\n \t\t\t}\n-\t\t\telse {\n-\t\t\t\tpush @xh,\n-\t\t\t\t  'MIME-Version: 1.0',\n-\t\t\t\t  \"Content-Type: text/plain; charset=$author_encoding\",\n-\t\t\t\t  'Content-Transfer-Encoding: 8bit';\n-\t\t\t}\n \t\t}\n-\t}\n \n-\t$needs_confirm = (\n-\t\t$confirm eq \"always\" or\n-\t\t($confirm =~ /^(?:auto|cc)$/ && @cc) or\n-\t\t($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));\n-\t$needs_confirm = \"inform\" if ($needs_confirm && $confirm_unconfigured && @cc);\n+\t\t$needs_confirm = (\n+\t\t\t$confirm eq \"always\" or\n+\t\t\t($confirm =~ /^(?:auto|cc)$/ && @cc) or\n+\t\t\t($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));\n+\t\t$needs_confirm = \"inform\" if ($needs_confirm && $confirm_unconfigured && @cc);\n \n-\t@cc = (@initial_cc, @cc);\n+\t\t@cc = (@initial_cc, @cc);\n \n-\tsend_message();\n+\t\tsend_message();\n \n-\t# set up for the next message\n-\tif ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) {\n-\t\t$reply_to = $message_id;\n-\t\tif (length $references > 0) {\n-\t\t\t$references .= \"\\n $message_id\";\n-\t\t} else {\n-\t\t\t$references = \"$message_id\";\n+\t\t# set up for the next message\n+\t\tif ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) {\n+\t\t\t$reply_to = $message_id;\n+\t\t\tif (length $references > 0) {\n+\t\t\t\t$references .= \"\\n $message_id\";\n+\t\t\t} else {\n+\t\t\t\t$references = \"$message_id\";\n+\t\t\t}\n \t\t}\n+\t\t$message_id = undef;\n+\t\tlast unless (<F>);\n \t}\n-\t$message_id = undef;\n+\tclose F;\n }\n \n cleanup_compose_files();\n\n-- \nwbr, Vitaly\n"},{"id":"113710","messageId":"7vpred7vhi.fsf@alter.siamese.dyndns.org","threadId":"19287","inReplyTo":"873abbeoqc.wl%vmayatsk@redhat.com","subject":"Re: [PATCH] git-send-email: parse all messages in mbox","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-12T23:27:21Z","receivedAt":"2009-05-12T23:27:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Vitaly Mayatskikh <v.mayatskih@gmail.com> writes:\n\n> Currently git-send-email sends all mbox in one email. This seems to be wrong,\n> because mbox can contain several messages. For example,\n> `git format-patch --stdout' forms mbox file with all patches in it.\n>\n> This patch allows git send-email to send several messages from one mbox\n> separately.\n\nI suspect nobody would comment on it because with reindentation this was\nextremely painful to review.\n\nI _think_ the gist of your change is that (1) here you stop slurping the\nbody when you see a line that begins with \"From \"...\n\n> +\t\t# Now parse the message body\n> +\t\twhile(<F>) {\n> +\t\t\tlast if /^From /; # Next message in file\n\n... and (2) the \"last unless (<F>)\" at the end of the loop where you\nattempt to see if there is any more lines to be read from the stream (and\nif so go back and continue from the header parsing).\n\n> -\t# set up for the next message\n> -\tif ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) {\n> -\t\t$reply_to = $message_id;\n> -\t\tif (length $references > 0) {\n> -\t\t\t$references .= \"\\n $message_id\";\n> -\t\t} else {\n> -\t\t\t$references = \"$message_id\";\n> +\t\t# set up for the next message\n> +\t\tif ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) {\n> +\t\t\t$reply_to = $message_id;\n> +\t\t\tif (length $references > 0) {\n> +\t\t\t\t$references .= \"\\n $message_id\";\n> +\t\t\t} else {\n> +\t\t\t\t$references = \"$message_id\";\n> +\t\t\t}\n>  \t\t}\n> +\t\t$message_id = undef;\n> +\t\tlast unless (<F>);\n>  \t}\n> -\t$message_id = undef;\n> +\tclose F;\n\nBut I think the code structure is wrong.  When you said \"last if /^From /\"\nearlier, you have already read that line (and you do not unread it), and\nhere with \"unless (<F>)\" you are reading yet another line (one line after\nthe UNIX-From line) and discarding it.  The next round loses the real\nRFC2822 header line you discarded with this unless (<F>), and begins from\nthe next line, and would break \"First unfold multiline header fields\"\nlogic among other things.\n\nBut this is only from reviewing a patch with reindentation noise so I\nmight have missed some subtle issues.\n\nCan you make this into two patches for easier review?  One to split out\nthe existing loop for a single input stream into a helper function without\nchanging any behaviour (i.e. the loop reads everything to the end), and\nthen as a follow-up patch introduce \"when we see a UNIX-From line we are\nat the beginning of the next message so return early\" logic to the helper?\n\nIOW, after the two-patch series, the current main-loop may look\nsomething like:\n\n\tmy $unread_line = undef;\n\twhile (1) {\n\t\t$unread_line = handle_one_stream(\\*F, $unread_line);\n                last if (!defined $unread_line);\n\t}\n        close(\\*F);\n\nand your new handle_one_stream() sub will look something like:\n\n\tsub handle_one_stream {\n\t\tmy ($fh, $last_line) = @_;\n\t\tlocal ($_);\n\n\t\tmy $author = undef;\n                my $author_encoding;\n                my $has_content_type;\n                my $body_encoding;\n                @cc = ();\n                @xh = ();\n                my $input_format = undef;\n                my @header = ();\n                $message = \"\";\n                $message_num++;\n\n                # First unfold multiline header fields\n                while (1) {\n\t\t\tif (defined $last_line) {\n\t\t\t\t$_ = $last_line;\n                                $last_line = undef;\n\t\t\t} else {\n                        \t$_ = <F>;\n\t\t\t}\n                        ...\n\t\t}\n                # Now parse the header\n                ...\n                # Now parse the message body\n                $last_line = undef;\n                while (1) {\n                \t$_ = <F>;\n\t\t\tif (/^From /) {\n\t\t\t\t# This is the beginning of the\n                                # next message; unread it.\n\t\t\t\t$last_line = $_;\n                                last;\n                        }\n                        $message .= $_;\n\t\t\t...\n\t\t}\n\t\treturn $last_line;\n\t}\n"},{"id":"113915","messageId":"87y6t0ow1o.wl%vmayatsk@redhat.com","threadId":"19287","inReplyTo":"7vpred7vhi.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-send-email: parse all messages in mbox","fromName":"Vitaly Mayatskikh","fromEmail":"v.mayatskih@gmail.com","sentAt":"2009-05-14T09:47:47Z","receivedAt":"2009-05-14T09:47:47Z","isPatch":true,"sender":{"key":"v.mayatskih@gmail.com","avatar":"https://gravatar.com/avatar/10e7872617c00157baad2014b42b6dedd1dc5bb97d2d050fa0ca97d63c592241?d=mp&s=160"},"body":"At Tue, 12 May 2009 16:27:21 -0700, Junio C Hamano wrote:\n\nThanks for your review Junio! Once I'll found a free minute, I'll\nrefresh my almost forgotten Perl knowledge and try to deuglify the\npatch.\n\n-- \nwbr, Vitaly\n"},{"id":"113936","messageId":"76718490905140748n390d0e85t8349b69fc6debc2a@mail.gmail.com","threadId":"19287","inReplyTo":"873abbeoqc.wl%vmayatsk@redhat.com","subject":"Re: [PATCH] git-send-email: parse all messages in mbox","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-05-14T14:48:33Z","receivedAt":"2009-05-14T14:48:33Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Mon, May 11, 2009 at 9:46 AM, Vitaly Mayatskikh\n<v.mayatskih@gmail.com> wrote:\n> Currently git-send-email sends all mbox in one email. This seems to be wrong,\n> because mbox can contain several messages. For example,\n> `git format-patch --stdout' forms mbox file with all patches in it.\n\nJust out of curiosity, what is the motivation for this patch?\n\nBy default, format-patch generates a file per commit, which is what\nsend-email currently expects. You can also specify one or more commits\nto send-email directly, in which case it runs format-patch on your\nbehalf. And, send-email cannot handle messages on stdin, so \"git\nformat-patch | git send-email\" is not a valid workflow, even after\nthis patch.\n\nSo the only way I can see this being useful is if you're doing something like:\n\n$ git format-patch --stdout > mbox\n$ git send-email mbox\n\nOr you can combine those in bash with:\n\n$ git send-email <(git format-patch --stdout)\n\nBut, why? The only way this patch would make any sense to me is if it\n_also_ extended send-email to read its messages from stdin.\n\nj.\n"},{"id":"113950","messageId":"87fxf7zfvy.wl%vmayatsk@redhat.com","threadId":"19287","inReplyTo":"76718490905140748n390d0e85t8349b69fc6debc2a@mail.gmail.com","subject":"Re: [PATCH] git-send-email: parse all messages in mbox","fromName":"Vitaly Mayatskikh","fromEmail":"v.mayatskih@gmail.com","sentAt":"2009-05-14T18:41:21Z","receivedAt":"2009-05-14T18:41:21Z","isPatch":true,"sender":{"key":"v.mayatskih@gmail.com","avatar":"https://gravatar.com/avatar/10e7872617c00157baad2014b42b6dedd1dc5bb97d2d050fa0ca97d63c592241?d=mp&s=160"},"body":"At Thu, 14 May 2009 10:48:33 -0400, Jay Soffian wrote:\n\n> On Mon, May 11, 2009 at 9:46 AM, Vitaly Mayatskikh\n> <v.mayatskih@gmail.com> wrote:\n> > Currently git-send-email sends all mbox in one email. This seems to be wrong,\n> > because mbox can contain several messages. For example,\n> > `git format-patch --stdout' forms mbox file with all patches in it.\n> \n> Just out of curiosity, what is the motivation for this patch?\n> \n> By default, format-patch generates a file per commit, which is what\n> send-email currently expects. You can also specify one or more commits\n> to send-email directly, in which case it runs format-patch on your\n> behalf. And, send-email cannot handle messages on stdin, so \"git\n> format-patch | git send-email\" is not a valid workflow, even after\n> this patch.\n> \n> So the only way I can see this being useful is if you're doing something like:\n> \n> $ git format-patch --stdout > mbox\n> $ git send-email mbox\n> \n> Or you can combine those in bash with:\n> \n> $ git send-email <(git format-patch --stdout)\n> \n> But, why? The only way this patch would make any sense to me is if it\n> _also_ extended send-email to read its messages from stdin.\n\nBecause I want to edit cover letter, make --dry-run, etc. And it's\nmore handy to me to have one entity (file) then a dozen of separate\npatches.\n\n-- \nwbr, Vitaly\n"}]}