[PATCH] git-send-email: parse all messages in mbox

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently git-send-email sends all mbox in one email. This seems to be wrong,
because mbox can contain several messages. For example,
`git format-patch --stdout' forms mbox file with all patches in it.

This patch allows git send-email to send several messages from one mbox
separately.

Signed-off-by: Vitaly Mayatskikh <v.mayatskih@xxxxxxxxx>
---
 git-send-email.perl |  278 ++++++++++++++++++++++++++-------------------------
 1 files changed, 141 insertions(+), 137 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index cccbf45..614fcbd 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -984,168 +984,172 @@ $message_num = 0;
 foreach my $t (@files) {
 	open(F,"<",$t) or die "can't open file $t";
 
-	my $author = undef;
-	my $author_encoding;
-	my $has_content_type;
-	my $body_encoding;
-	@cc = ();
-	@xh = ();
-	my $input_format = undef;
-	my @header = ();
-	$message = "";
-	$message_num++;
-	# First unfold multiline header fields
-	while(<F>) {
-		last if /^\s*$/;
-		if (/^\s+\S/ and @header) {
-			chomp($header[$#header]);
-			s/^\s+/ /;
-			$header[$#header] .= $_;
-	    } else {
-			push(@header, $_);
-		}
-	}
-	# Now parse the header
-	foreach(@header) {
-		if (/^From /) {
-			$input_format = 'mbox';
-			next;
-		}
-		chomp;
-		if (!defined $input_format && /^[-A-Za-z]+:\s/) {
-			$input_format = 'mbox';
+	while (1) {
+		my $author = undef;
+		my $author_encoding;
+		my $has_content_type;
+		my $body_encoding;
+		@cc = ();
+		@xh = ();
+		my $input_format = undef;
+		my @header = ();
+		$message = "";
+		$message_num++;
+		# First unfold multiline header fields
+		while(<F>) {
+			last if /^\s*$/;
+			if (/^\s+\S/ and @header) {
+				chomp($header[$#header]);
+				s/^\s+/ /;
+				$header[$#header] .= $_;
+			} else {
+				push(@header, $_);
+			}
 		}
-
-		if (defined $input_format && $input_format eq 'mbox') {
-			if (/^Subject:\s+(.*)$/) {
-				$subject = $1;
+		# Now parse the header
+		foreach(@header) {
+			if (/^From /) {
+				$input_format = 'mbox';
+				next;
 			}
-			elsif (/^From:\s+(.*)$/) {
-				($author, $author_encoding) = unquote_rfc2047($1);
-				next if $suppress_cc{'author'};
-				next if $suppress_cc{'self'} and $author eq $sender;
-				printf("(mbox) Adding cc: %s from line '%s'\n",
-					$1, $_) unless $quiet;
-				push @cc, $1;
+			chomp;
+			if (!defined $input_format && /^[-A-Za-z]+:\s/) {
+				$input_format = 'mbox';
 			}
-			elsif (/^Cc:\s+(.*)$/) {
-				foreach my $addr (parse_address_line($1)) {
-					if (unquote_rfc2047($addr) eq $sender) {
-						next if ($suppress_cc{'self'});
-					} else {
-						next if ($suppress_cc{'cc'});
-					}
+
+			if (defined $input_format && $input_format eq 'mbox') {
+				if (/^Subject:\s+(.*)$/) {
+					$subject = $1;
+				}
+				elsif (/^From:\s+(.*)$/) {
+					($author, $author_encoding) = unquote_rfc2047($1);
+					next if $suppress_cc{'author'};
+					next if $suppress_cc{'self'} and $author eq $sender;
 					printf("(mbox) Adding cc: %s from line '%s'\n",
-						$addr, $_) unless $quiet;
-					push @cc, $addr;
+					       $1, $_) unless $quiet;
+					push @cc, $1;
 				}
-			}
-			elsif (/^Content-type:/i) {
-				$has_content_type = 1;
-				if (/charset="?([^ "]+)/) {
-					$body_encoding = $1;
+				elsif (/^Cc:\s+(.*)$/) {
+					foreach my $addr (parse_address_line($1)) {
+						if (unquote_rfc2047($addr) eq $sender) {
+							next if ($suppress_cc{'self'});
+						} else {
+							next if ($suppress_cc{'cc'});
+						}
+						printf("(mbox) Adding cc: %s from line '%s'\n",
+						       $addr, $_) unless $quiet;
+						push @cc, $addr;
+					}
+				}
+				elsif (/^Content-type:/i) {
+					$has_content_type = 1;
+					if (/charset="?([^ "]+)/) {
+						$body_encoding = $1;
+					}
+					push @xh, $_;
+				}
+				elsif (/^Message-Id: (.*)/i) {
+					$message_id = $1;
+				}
+				elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) {
+					push @xh, $_;
 				}
-				push @xh, $_;
-			}
-			elsif (/^Message-Id: (.*)/i) {
-				$message_id = $1;
-			}
-			elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) {
-				push @xh, $_;
-			}
 
-		} else {
-			# In the traditional
-			# "send lots of email" format,
-			# line 1 = cc
-			# line 2 = subject
-			# So let's support that, too.
-			$input_format = 'lots';
-			if (@cc == 0 && !$suppress_cc{'cc'}) {
-				printf("(non-mbox) Adding cc: %s from line '%s'\n",
-					$_, $_) unless $quiet;
-				push @cc, $_;
-			} elsif (!defined $subject) {
-				$subject = $_;
+			} else {
+				# In the traditional
+				# "send lots of email" format,
+				# line 1 = cc
+				# line 2 = subject
+				# So let's support that, too.
+				$input_format = 'lots';
+				if (@cc == 0 && !$suppress_cc{'cc'}) {
+					printf("(non-mbox) Adding cc: %s from line '%s'\n",
+					       $_, $_) unless $quiet;
+					push @cc, $_;
+				} elsif (!defined $subject) {
+					$subject = $_;
+				}
 			}
 		}
-	}
-	# Now parse the message body
-	while(<F>) {
-		$message .=  $_;
-		if (/^(Signed-off-by|Cc): (.*)$/i) {
-			chomp;
-			my ($what, $c) = ($1, $2);
-			chomp $c;
-			if ($c eq $sender) {
-				next if ($suppress_cc{'self'});
-			} else {
-				next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i;
-				next if $suppress_cc{'bodycc'} and $what =~ /Cc/i;
+		# Now parse the message body
+		while(<F>) {
+			last if /^From /; # Next message in file
+			$message .=  $_;
+			if (/^(Signed-off-by|Cc): (.*)$/i) {
+				chomp;
+				my ($what, $c) = ($1, $2);
+				chomp $c;
+				if ($c eq $sender) {
+					next if ($suppress_cc{'self'});
+				} else {
+					next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i;
+					next if $suppress_cc{'bodycc'} and $what =~ /Cc/i;
+				}
+				push @cc, $c;
+				printf("(body) Adding cc: %s from line '%s'\n",
+				       $c, $_) unless $quiet;
 			}
-			push @cc, $c;
-			printf("(body) Adding cc: %s from line '%s'\n",
-				$c, $_) unless $quiet;
 		}
-	}
-	close F;
 
-	if (defined $cc_cmd && !$suppress_cc{'cccmd'}) {
-		open(F, "$cc_cmd $t |")
-			or die "(cc-cmd) Could not execute '$cc_cmd'";
-		while(<F>) {
-			my $c = $_;
-			$c =~ s/^\s*//g;
-			$c =~ s/\n$//g;
-			next if ($c eq $sender and $suppress_from);
-			push @cc, $c;
-			printf("(cc-cmd) Adding cc: %s from: '%s'\n",
-				$c, $cc_cmd) unless $quiet;
+		if (defined $cc_cmd && !$suppress_cc{'cccmd'}) {
+			open(CC_CMD, "$cc_cmd $t |")
+			    or die "(cc-cmd) Could not execute '$cc_cmd'";
+			while(<CC_CMD>) {
+				my $c = $_;
+				$c =~ s/^\s*//g;
+				$c =~ s/\n$//g;
+				next if ($c eq $sender and $suppress_from);
+				push @cc, $c;
+				printf("(cc-cmd) Adding cc: %s from: '%s'\n",
+				       $c, $cc_cmd) unless $quiet;
+			}
+			close CC_CMD
+			    or die "(cc-cmd) failed to close pipe to '$cc_cmd'";
 		}
-		close F
-			or die "(cc-cmd) failed to close pipe to '$cc_cmd'";
-	}
 
-	if (defined $author and $author ne $sender) {
-		$message = "From: $author\n\n$message";
-		if (defined $author_encoding) {
-			if ($has_content_type) {
-				if ($body_encoding eq $author_encoding) {
-					# ok, we already have the right encoding
+		if (defined $author and $author ne $sender) {
+			$message = "From: $author\n\n$message";
+			if (defined $author_encoding) {
+				if ($has_content_type) {
+					if ($body_encoding eq $author_encoding) {
+						# ok, we already have the right encoding
+					}
+					else {
+						# uh oh, we should re-encode
+					}
 				}
 				else {
-					# uh oh, we should re-encode
+					push @xh,
+					'MIME-Version: 1.0',
+					"Content-Type: text/plain; charset=$author_encoding",
+					'Content-Transfer-Encoding: 8bit';
 				}
 			}
-			else {
-				push @xh,
-				  'MIME-Version: 1.0',
-				  "Content-Type: text/plain; charset=$author_encoding",
-				  'Content-Transfer-Encoding: 8bit';
-			}
 		}
-	}
 
-	$needs_confirm = (
-		$confirm eq "always" or
-		($confirm =~ /^(?:auto|cc)$/ && @cc) or
-		($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));
-	$needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc);
+		$needs_confirm = (
+			$confirm eq "always" or
+			($confirm =~ /^(?:auto|cc)$/ && @cc) or
+			($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));
+		$needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc);
 
-	@cc = (@initial_cc, @cc);
+		@cc = (@initial_cc, @cc);
 
-	send_message();
+		send_message();
 
-	# set up for the next message
-	if ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) {
-		$reply_to = $message_id;
-		if (length $references > 0) {
-			$references .= "\n $message_id";
-		} else {
-			$references = "$message_id";
+		# set up for the next message
+		if ($chain_reply_to || !defined $reply_to || length($reply_to) == 0) {
+			$reply_to = $message_id;
+			if (length $references > 0) {
+				$references .= "\n $message_id";
+			} else {
+				$references = "$message_id";
+			}
 		}
+		$message_id = undef;
+		last unless (<F>);
 	}
-	$message_id = undef;
+	close F;
 }
 
 cleanup_compose_files();

-- 
wbr, Vitaly
--
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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]