{"thread":{"id":"1376","subject":"[PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","startedAt":"2005-07-31T08:17:25Z","lastAt":"2005-08-03T07:32:15Z","messageCount":16,"participants":["Ryan Anderson","Matthias Urlichs","Junio C Hamano","Johannes Schindelin","Sergey Vlasov","Noel Maddy"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"6659","messageId":"11227978451100@foobar.com","threadId":"1376","inReplyTo":null,"subject":"[PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-07-31T08:17:25Z","receivedAt":"2005-07-31T08:17:25Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"This is based off of GregKH's script, send-lots-of-email.pl, and strives to do\nall the nice things a good subsystem maintainer does when forwarding a patch or\n50 upstream:\n\n\tAll the prior handlers of the patch, as determined by the\n\tSigned-off-by: lines, and/or the author of the commit, are cc:ed on the\n\temail.\n\n\tAll emails are sent as a reply to the previous email, making it easy to\n\tskip a collection of emails that are uninteresting.\n\nSigned-off-by: Ryan Anderson <ryan@michonline.com>\n---\n\n Makefile              |    2 \n git-send-email-script |  265 +++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 266 insertions(+), 1 deletions(-)\n create mode 100755 git-send-email-script\n\n55d4b5b7a11448d60eb00b5a7081954663842b06\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -62,7 +62,7 @@ SCRIPTS=git git-apply-patch-script git-m\n \tgit-format-patch-script git-sh-setup-script git-push-script \\\n \tgit-branch-script git-parse-remote git-verify-tag-script \\\n \tgit-ls-remote-script git-clone-dumb-http git-rename-script \\\n-\tgit-request-pull-script\n+\tgit-request-pull-script git-send-email-script\n \n PROG=   git-update-cache git-diff-files git-init-db git-write-tree \\\n \tgit-read-tree git-commit-tree git-cat-file git-fsck-cache \\\ndiff --git a/git-send-email-script b/git-send-email-script\nnew file mode 100755\n--- /dev/null\n+++ b/git-send-email-script\n@@ -0,0 +1,265 @@\n+#!/usr/bin/perl -w\n+# horrible hack of a script to send off a large number of email messages, one after\n+# each other, all chained together.  This is useful for large numbers of patches.\n+#\n+# Use at your own risk!!!!\n+#\n+# greg kroah-hartman Jan 8, 2002\n+# <greg@kroah.com>\n+#\n+# GPL v2 (See COPYING)\n+# \n+# Ported to support git \"mbox\" format files by Ryan Anderson <ryan@michonline.com>\n+#\n+# Sends emails to the email listed on the command line.\n+# \n+# updated to give a valid subject and CC the owner of the patch - Jan 2005\n+# first line of the message is who to CC, \n+# and second line is the subject of the message.\n+# \n+\n+use strict;\n+use warnings;\n+use Term::ReadLine;\n+use Mail::Sendmail;\n+use Getopt::Long;\n+use Data::Dumper;\n+use Email::Valid;\n+\n+# Variables we fill in automatically, or via prompting:\n+my (@to,@cc,$initial_reply_to,$initial_subject,@files,$from);\n+\n+# Example of them\n+# modify these options each time you run the script\n+#$to = 'torvalds@osdl.org,git@vger.kernel.org';\n+#$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';\n+#$initial_subject = \"[PATCH] Deb package build fixes\";\n+#@files = (qw(\n+#0001-Make-debian-rules-executable-and-correct-the-spelling-of-rsync-in.txt\n+#0002-Debian-packages-should-include-the-binaries.txt\n+#0003-The-deb-package-building-needs-these-two-new-files-to-work-correctly.txt\n+#));\n+\n+# change this to your email address.\n+#$from = \"Ryan Anderson <ryan\\@michonline.com>\";\n+\n+my $term = new Term::ReadLine 'git-send-email';\n+\n+# Begin by accumulating all the variables (defined above), that we will end up\n+# needing, first, from the command line:\n+\n+my $rc = GetOptions(\"from=s\" => \\$from,\n+                    \"in-reply-to=s\" => \\$initial_reply_to,\n+\t\t    \"subject=s\" => \\$initial_subject,\n+\t\t    \"to=s\" => \\@to,\n+\t );\n+\n+# Now, let's fill any that aren't set in with defaults:\n+\n+open(GITVAR,\"-|\",\"git-var\",\"-l\")\n+\tor die \"Failed to open pipe from git-var: $!\";\n+\n+my ($author,$committer);\n+while(<GITVAR>) {\n+\tchomp;\n+\tmy ($var,$data) = split /=/,$_,2;\n+\tmy @fields = split /\\s+/, $data;\n+\n+\tmy $ident = join(\" \", @fields[0...(@fields-3)]);\n+\n+\tif ($var eq 'GIT_AUTHOR_IDENT') {\n+\t\t$author = $ident;\n+\t} elsif ($var eq 'GIT_COMMITTER_IDENT') {\n+\t\t$committer = $ident;\n+\t}\n+}\n+close(GITVAR);\n+\n+\n+if (!defined $from) {\n+\t$from = $author || $committer;\n+\t1 while (!defined ($_ = $term->readline(\"Who should the emails appear to be from? \", \n+\t\t\t\t$from)));\n+\t$from = $_;\n+\tprint \"Emails will be sent from: \", $from, \"\\n\";\n+}\n+\n+if (!@to) {\n+\t1 while (!defined ($_ = $term->readline(\"Who should the emails be sent to? \", \n+\t\t\t\t\"\")));\n+\tmy $to = $_;\n+\tpush @to, split /,/, $to;\n+}\n+\n+if (!defined $initial_subject) {\n+\t1 while (!defined ($_ = \n+\t\t$term->readline(\"What subject should the emails start with? \", \n+\t\t\t$initial_subject)));\n+\t$initial_subject = $_;\n+}\n+\n+if (!defined $initial_reply_to) {\n+\t1 while (!defined ($_ = \n+\t\t$term->readline(\"Message-ID to be used as In-Reply-To? \", \n+\t\t\t$initial_reply_to)));\n+\t$initial_reply_to = $_;\n+}\n+\n+# Now that all the defaults are set, process the rest of the command line\n+# arguments and collect up the files that need to be processed.\n+for my $f (@ARGV) {\n+\tif (-d $f) {\n+\t\topendir(DH,$f)\n+\t\t\tor die \"Failed to opendir $f: $!\";\n+\n+\t\tpush @files, map { +$f . \"/\" . $_ } grep !/^\\.{1,2}$/,\n+\t\t\tsort readdir(DH);\n+\t} elsif (-f $f) {\n+\t\tpush @files, $f;\n+\n+\t} else {\n+\t\tprint STDERR \"Skipping $f - not found.\\n\";\n+\t}\n+}\n+\n+if (@files) {\n+\tprint $_,\"\\n\" for @files;\n+} else {\n+\tprint <<EOT;\n+git-send-email-script [options] <file | directory> [... file | directory ]\n+Options:\n+   --from         Specify the \"From:\" line of the email to be sent.\n+   --to\t          Specify the primary \"To:\" line of the email.\n+   --subject      Specify the initial \"Subject:\" line.\n+   --in-reply-to  Specify the first \"In-Reply-To:\" header line.\n+\n+Error: Please specify a file or a directory on the command line.\n+EOT\n+\texit(1);\n+}\n+\n+# Variables we set as part of the loop over files\n+our ($message_id, $cc, %mail, $subject, $reply_to, $message);\n+\n+\n+# Usually don't need to change anything below here.\n+\n+# we make a \"fake\" message id by taking the current number\n+# of seconds since the beginning of Unix time and tacking on\n+# a random number to the end, in case we are called quicker than\n+# 1 second since the last time we were called.\n+sub make_message_id\n+{\n+\tmy $date = `date \"+\\%s\"`;\n+\tchomp($date);\n+\tmy $pseudo_rand = int (rand(4200));\n+\t$message_id = \"<$date$pseudo_rand\\@foobar.com>\";\n+\tprint \"new message id = $message_id\\n\";\n+}\n+\n+\n+\n+$cc = \"\";\n+\n+sub send_message\n+{\n+\tmy %to;\n+\t$to{lc(Email::Valid->address($_))}++ for (@to);\n+\n+\tmy $to = join(\",\", keys %to);\n+\n+\t%mail = (\tTo\t=>\t$to,\n+\t\t\tFrom\t=>\t$from,\n+\t\t\tCC\t=>\t$cc,\n+\t\t\tSubject\t=>\t$subject,\n+\t\t\tMessage\t=>\t$message,\n+\t\t\t'Reply-to'\t=>\t$from,\n+\t\t\t'In-Reply-To'\t=>\t$reply_to,\n+\t\t\t'Message-ID'\t=>\t$message_id,\n+\t\t\t'X-Mailer'\t=>\t\"git-send-email-script\",\n+\t\t);\n+\n+\t$mail{smtp} = 'localhost';\n+\n+\t#print Data::Dumper->Dump([\\%mail],[qw(*mail)]);\n+\n+\tsendmail(%mail) or die $Mail::Sendmail::error;\n+\n+\tprint \"OK. Log says:\\n\", $Mail::Sendmail::log;\n+\tprint \"\\n\\n\"\n+}\n+\n+\n+$reply_to = $initial_reply_to;\n+make_message_id();\n+$subject = $initial_subject;\n+\n+foreach my $t (@files) {\n+\tmy $F = $t;\n+\topen(F,\"<\",$t) or die \"can't open file $t\";\n+\n+\t@cc = ();\n+\tmy $found_mbox = 0;\n+\tmy $header_done = 0;\n+\t$message = \"\";\n+\twhile(<F>) {\n+\t\tif (!$header_done) {\n+\t\t\t$found_mbox = 1, next if (/^From /);\n+\t\t\tchomp;\n+\n+\t\t\tif ($found_mbox) {\n+\t\t\t\tif (/^Subject:\\s+(.*)$/) {\n+\t\t\t\t\t$subject = $1;\n+\n+\t\t\t\t} elsif (/^(Cc|From):\\s+(.*)$/) {\n+\t\t\t\t\tprintf(\"(mbox) Adding cc: %s from line '%s'\\n\",\n+\t\t\t\t\t\t$2, $_);\n+\t\t\t\t\tpush @cc, $2;\n+\t\t\t\t}\n+\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\tif (@cc == 0) {\n+\t\t\t\t\tprintf(\"(non-mbox) Adding cc: %s from line '%s'\\n\",\n+\t\t\t\t\t\t$_, $_);\n+\n+\t\t\t\t\tpush @cc, $_;\n+\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\t\n+\t\t\t# A whitespace line will terminate the headers\n+\t\t\tif (m/^\\s*$/) {\n+\t\t\t\t$header_done = 1;\n+\t\t\t}\n+\t\t} else {\n+\t\t\t$message .=  $_;\n+\t\t\tif (/^Signed-off-by: (.*)$/i) {\n+\t\t\t\tmy $c = $1;\n+\t\t\t\tchomp $c;\n+\t\t\t\tpush @cc, $c;\n+\t\t\t\tprintf(\"(sob) Adding cc: %s from line '%s'\\n\",\n+\t\t\t\t\t$c, $_);\n+\t\t\t}\n+\t\t}\n+\t}\n+\tclose F;\n+\n+\tmy %clean_ccs;\n+\t$clean_ccs{lc(Email::Valid->address($_))}++ for @cc;\n+\n+\t$cc = join(\",\", keys %clean_ccs);\n+\n+\tsend_message();\n+\n+\t# set up for the next message\n+\t$reply_to = $message_id;\n+\tmake_message_id();\n+#\t$subject = \"Re: \".$initial_subject;\n+}\n"},{"id":"6661","messageId":"20050731082430.GG32263@mythryan2.michonline.com","threadId":"1376","inReplyTo":"11227978451100@foobar.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-07-31T08:24:30Z","receivedAt":"2005-07-31T08:24:30Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Sun, Jul 31, 2005 at 04:17:25AM -0400, Ryan Anderson wrote:\n> This is based off of GregKH's script, send-lots-of-email.pl, and strives to do\n> all the nice things a good subsystem maintainer does when forwarding a patch or\n> 50 upstream:\n> \n> \tAll the prior handlers of the patch, as determined by the\n> \tSigned-off-by: lines, and/or the author of the commit, are cc:ed on the\n> \temail.\n> \n> \tAll emails are sent as a reply to the previous email, making it easy to\n> \tskip a collection of emails that are uninteresting.\n> \n> Signed-off-by: Ryan Anderson <ryan@michonline.com>\n\nAnd yes, I did generate this thread with this script - so I have proof\nthat it works nicely.\n\nActually, with this:\n\tgit format-patch -n --mbox -o ../pending/ origin\n\tgit send-email ../pending/\n\t<answer some questions>\n\nIn 2-3 minutes I should have my git tree at\nrsync://h4x0r5.com/git-ryan.git/ updated with these changes, and my\nSYNOPSIS draft.  (I haven't added the short tutorial that Sam suggested\nyet, that's a task for another 4am hackfest.)\n\n-- \nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"6662","messageId":"pan.2005.07.31.09.36.07.97284@smurf.noris.de","threadId":"1376","inReplyTo":"20050731082430.GG32263@mythryan2.michonline.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-07-31T09:36:10Z","receivedAt":"2005-07-31T09:36:10Z","isPatch":true,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Ryan Anderson wrote:\n\n> And yes, I did generate this thread with this script - so I have proof\n> that it works nicely.\n\nIt might make sense to create a \"Patch 0/N\" with a short explanation, and\nhave the actual patches be replies to that -- or to patch 1/N if that's\nnot necessary.\n\nAs it is, patch N hangs off patch N-1 in my email threading view, which\ngets slightly cumbersome if N>10.\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\nNothing makes a person more productive than the last minute.\n"},{"id":"6663","messageId":"7vbr4jmhqe.fsf@assigned-by-dhcp.cox.net","threadId":"1376","inReplyTo":"11227978451100@foobar.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-31T09:45:29Z","receivedAt":"2005-07-31T09:45:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ryan Anderson <ryan@michonline.com> writes:\n\n> \tAll emails are sent as a reply to the previous email, making it easy to\n> \tskip a collection of emails that are uninteresting.\n\nI understand why _some_ people consider this preferable, but\nwonder if this should have a knob to be tweaked.\n\nFor example, I myself often find it very hard to read when\na cascading thread goes very deep like this:\n\n     [PATCH 0/9] cover\n       [PATCH 1/9] first one\n         [PATCH 2/9] second one\n          [PATCH 3/9] third one in the series\n            ...\n\nand prefer to see this instead (this assumes your MUA is\nhalf-way decent and lets you sort by subject):\n\n     [PATCH 0/9] cover\n       [PATCH 1/9] first one\n       [PATCH 2/9] second one\n       [PATCH 3/9] third one in the series\n       ...\n\n> +# horrible hack of a script to send off a large number of email messages, one after\n> +# each other, all chained together.  This is useful for large numbers of patches.\n> +#\n> +# Use at your own risk!!!!\n\nWell, if it is \"Use at your own risk\" maybe it should stay\noutside the official distribution for a while until it gets\nsafer ;-).\n\n> +\tmy @fields = split /\\s+/, $data;\n> +\tmy $ident = join(\" \", @fields[0...(@fields-3)]);\n\nWouldn't \"s/>.*/>/\" be easier than splitting and joining?\n\n> +if (!defined $from) {\n> +\t$from = $author || $committer;\n> +\t1 while (!defined ($_ = $term->readline(\"Who should the emails appear to be from? \", \n> +\t\t\t\t$from)));\n\nJudging from your past patches, you seem to really like\nstatement modifiers[*].  While they _are_ valid Perl constructs,\nit is extremely hard to read when used outside very simple\nidiomatic use.  Please consider rewriting the above and the like\nusing compound statements[*] (I am using these terms according\nto the definition in perlsyn.pod).  Remember, there are people\nPerl is not their native language, but are intelligent enough to\nbe of great help fixing problems in programs you write in Perl.\nTo most of them, compound statements are more familiar, so try\nto be gentle to them.\n\n> +\t\topendir(DH,$f)\n> +\t\t\tor die \"Failed to opendir $f: $!\";\n> +\t\tpush @files, map { +$f . \"/\" . $_ } grep !/^\\.{1,2}$/,\n> +\t\t\tsort readdir(DH);\n\nMaybe skip potential subdirs while you are at it, something like this?\n\n    push @files, sort grep { -f $_ } map { \"$f/$_\" } readdir(DH)\n\n> +\tmy $pseudo_rand = int (rand(4200));\n> +\t$message_id = \"<$date$pseudo_rand\\@foobar.com>\";\n> +\tprint \"new message id = $message_id\\n\";\n\nI doubt this hardcoded foobar.com is a good idea.  Did you mean\nto print it, by the way?\n\n> +\t$to{lc(Email::Valid->address($_))}++ for (@to);\n> +\tmy $to = join(\",\", keys %to);\n\nIs this the culprit that produced this mechanical-looking line?\n\n    To: junkio@cox.net,git@vger.kernel.org\n\nInterestingly enough, you do not seem to do it for the From:\nline.\n\n    From: Ryan Anderson <ryan@michonline.com>\n\nAlso you seem to be losing the ordering in @to and @cc by the\nuse of uniquefying \"keys %to\" and \"keys %cc\".  I can not offhand\ntell if it matters, but you probably would care, at least for\nthe primary recipients listed in @to array.\n\n> +\t$mail{smtp} = 'localhost';\n\nI suspect this probably need to be configurable.  I may be a\nminority, but my outgoing messages are directly handed to my\nlocal ISP smtp server from my MUA, and the smtp server running\non the locahost does not talk to the outside world.\n\n> +\t# set up for the next message\n> +\t$reply_to = $message_id;\n\nMaking chaining policy configurable would be just one liner\nchange here, I suppose.\n\nSince there are always 47 different ways to do the same thing in\nPerl, Perl style varies a lot more than Shell style which in\nturn varies a lot more than C.  You should be prepared to be\nnitpicked a lot when you post Perl ;-).  And I was in nitpicking\nmood tonight.\n\nThanks for the patch.  Overall, very good intent.  Slightly\ntroublesome details.\n\n-jc\n"},{"id":"6664","messageId":"Pine.LNX.4.58.0507311223240.16181@wgmdd8.biozentrum.uni-wuerzburg.de","threadId":"1376","inReplyTo":"11227978451100@foobar.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-07-31T10:25:13Z","receivedAt":"2005-07-31T10:25:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nwouldn't it be a good idea to make $from and $to required parameters? At\nleast you could infer a sensible default of $from from GIT_* environment\nvariables, no? I am not quite comfortable with a hard coded sender in a\nscript possibly deployed into a multi-user environment.\n\nCiao,\nDscho\n"},{"id":"6665","messageId":"20050731145055.2b5e6161.vsu@altlinux.ru","threadId":"1376","inReplyTo":"11227978451100@foobar.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Sergey Vlasov","fromEmail":"vsu@altlinux.ru","sentAt":"2005-07-31T10:50:55Z","receivedAt":"2005-07-31T10:50:55Z","isPatch":true,"sender":{"key":"vsu@altlinux.ru","avatar":"https://avatars.githubusercontent.com/u/616082?v=4"},"body":"On Sun, 31 Jul 2005 04:17:25 -0400 Ryan Anderson wrote:\n\n> This is based off of GregKH's script, send-lots-of-email.pl, and\n> strives to do all the nice things a good subsystem maintainer does\n> when forwarding a patch or 50 upstream:\n> \n> \tAll the prior handlers of the patch, as determined by the\n> \tSigned-off-by: lines, and/or the author of the commit, are cc:ed\n> \ton the email.\n\n> \tAll emails are sent as a reply to the previous email, making it\n> \teasy to skip a collection of emails that are uninteresting.\n\nActually, this is the part of GregKH's script which I hate ;)\n\n50 patches sent this way produce an enormous email thread; if someone\nthen tries to comment on a 40th patch, this part of the thread ends up\nfar behind the right edge of the message list window in almost any mail\nclient (and if someone comments on the first patch, the comments are far\nfrom that patch).\n\nSending a [PATCH 0/N] message with the overall description of the\npatchset and then all patches as replies to that message looks much\nbetter in that respect.  However, missing messages in this form are less\nobvious.\n"},{"id":"6670","messageId":"7vll3mhjq0.fsf@assigned-by-dhcp.cox.net","threadId":"1376","inReplyTo":"7vbr4jmhqe.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-31T19:13:43Z","receivedAt":"2005-07-31T19:13:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Oh, another thing.  Could you refrain from doing\nquoted-printable when possible?  Thanks.\n"},{"id":"6686","messageId":"20050731235242.GH32263@mythryan2.michonline.com","threadId":"1376","inReplyTo":"7vbr4jmhqe.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-07-31T23:52:42Z","receivedAt":"2005-07-31T23:52:42Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Sun, Jul 31, 2005 at 02:45:29AM -0700, Junio C Hamano wrote:\n> Ryan Anderson <ryan@michonline.com> writes:\n> \n> > \tAll emails are sent as a reply to the previous email, making it easy to\n> > \tskip a collection of emails that are uninteresting.\n> \n> I understand why _some_ people consider this preferable, but\n> wonder if this should have a knob to be tweaked.\n\nHmm, fair enough.\n\nI'll send a few more patches in a minute that deal with the things in\nthis email but for now:\n\n\t--chain-reply-to (or --no-chain-reply-to)\n\n\tWill toggle between these two behaviors.  (This will not be\n\tprompted for by the ReadLine interface, btw.)\n\n> > +# horrible hack of a script to send off a large number of email messages, one after\n> > +# each other, all chained together.  This is useful for large numbers of patches.\n> > +#\n> > +# Use at your own risk!!!!\n> \n> Well, if it is \"Use at your own risk\" maybe it should stay\n> outside the official distribution for a while until it gets\n> safer ;-).\n\nHeh.  I missed some comments that I meant to clean up that were in\nGreg's original script.  One of the patches will clean up the comments.\n\n> > +\tmy @fields = split /\\s+/, $data;\n> > +\tmy $ident = join(\" \", @fields[0...(@fields-3)]);\n> \n> Wouldn't \"s/>.*/>/\" be easier than splitting and joining?\n\nMost of GIT_COMMITTER_IDENT (and GIT_AUTHOR_IDENT) is use controllable,\nexcept for the \"date\" section of it.  I know we delimit that with\nspaces, so the above is guaranteed to work unless we change the format\nthat git-var returns.\n\nIf I hope that nobody has done something like:\n\tGIT_AUTHOR=\"Ryan <> Anderson\"\n\tGIT_AUTHOR_EMAIL=\"ryan@michonline.com\"\n\nI get more confusing results.  (I suddenly have to think about what that\nregular expression does in this case - and I'm pretty sure that the one\nyou gave would do bad things.)\n\nProbably the best fix for this would be to take libgit.a, make a shared\nlibrary out of it, and then interface the Perl scripts directly with it\nvia a .xs module.  I was thinking that I'd rather have direct access to\nthe git_ident* functions than calling out to git-var, anyway.  Consider\nthat a plan for a revamp after the core seems to have settled down a bit\nmore.\n\n> > +if (!defined $from) {\n> > +\t$from = $author || $committer;\n> > +\t1 while (!defined ($_ = $term->readline(\"Who should the emails appear to be from? \", \n> > +\t\t\t\t$from)));\n> \n> Judging from your past patches, you seem to really like\n> statement modifiers[*].  While they _are_ valid Perl constructs,\n> it is extremely hard to read when used outside very simple\n> idiomatic use.  Please consider rewriting the above and the like\n> using compound statements[*] (I am using these terms according\n> to the definition in perlsyn.pod).  Remember, there are people\n> Perl is not their native language, but are intelligent enough to\n> be of great help fixing problems in programs you write in Perl.\n> To most of them, compound statements are more familiar, so try\n> to be gentle to them.\n\nI copied this from another program of mine, and I'm *sure* I copied the\nstyle directly from a ReadLine example.  But, I can't find a current\nexample that says this is good, so, I'll fix this, too.  It is rather\nugly.  (The other uses of this style are... less bad, IMO, than this\nabuse here.)\n\n\n> \n> > +\t\topendir(DH,$f)\n> > +\t\t\tor die \"Failed to opendir $f: $!\";\n> > +\t\tpush @files, map { +$f . \"/\" . $_ } grep !/^\\.{1,2}$/,\n> > +\t\t\tsort readdir(DH);\n> \n> Maybe skip potential subdirs while you are at it, something like this?\n> \n>     push @files, sort grep { -f $_ } map { \"$f/$_\" } readdir(DH)\n\nGood point.  One one hand I'd say, \"Let it break for people who do\nstrange things like that\", but I'll make it safer anyway.\n\n(Someone is going to reply and ask for it to recurse into subdirectories\nnow.  Maybe Andrew Morton would find that useful with his rather massive\ncollection of patches in -mm kernels.  But that's a feature for next\nweek.)\n\n> > +\tmy $pseudo_rand = int (rand(4200));\n> > +\t$message_id = \"<$date$pseudo_rand\\@foobar.com>\";\n> > +\tprint \"new message id = $message_id\\n\";\n> \n> I doubt this hardcoded foobar.com is a good idea.  Did you mean\n> to print it, by the way?\n\nI'll convert this to something that is based off the $from address\ninstead.  It's probably better that way, anyway.\n\n> > +\t$to{lc(Email::Valid->address($_))}++ for (@to);\n> > +\tmy $to = join(\",\", keys %to);\n> \n> Is this the culprit that produced this mechanical-looking line?\n> \n>     To: junkio@cox.net,git@vger.kernel.org\n\nNo, that line was exactly what I put into the readline entry.\n\n> Interestingly enough, you do not seem to do it for the From:\n> line.\n> \n>     From: Ryan Anderson <ryan@michonline.com>\n> \n> Also you seem to be losing the ordering in @to and @cc by the\n> use of uniquefying \"keys %to\" and \"keys %cc\".  I can not offhand\n> tell if it matters, but you probably would care, at least for\n> the primary recipients listed in @to array.\n\nWell, it was kind of annoying to see the same email address appear 2-3\ntimes in the email, because of the way I pull in all the relevant emails\nfrom various places.  So I really needed a way to cull the duplicates.\nI don't believe ordering is really significant in To: or Cc: lines, for\nreally anyone.  I could do soemthing like this, instead, I suppose:\n\n\tmy @clean_to = ();\n\tmy %dupe_check_to = ();\n\tforeach my $to_entry (@to) {\n\t\tif (!$dupe_check_to{Email::Valid->address($to_entry)}++) {\n\t\t\tpush @clean_to, $to_entry;\n\t\t}\n\t}\n\n\tmy $to = join(\", \", @clean_to);\n\nI just like the first one a little better (though, I can't really pin\ndown why).\n\n> > +\t$mail{smtp} = 'localhost';\n> \n> I suspect this probably need to be configurable.  I may be a\n> minority, but my outgoing messages are directly handed to my\n> local ISP smtp server from my MUA, and the smtp server running\n> on the locahost does not talk to the outside world.\n\nOddly, I think this is even the wrong setting after having read over the\nMail::Sendmail docs to figure out how to change the MIME settings.\n\n> Since there are always 47 different ways to do the same thing in\n> Perl, Perl style varies a lot more than Shell style which in\n> turn varies a lot more than C.  You should be prepared to be\n> nitpicked a lot when you post Perl ;-).  And I was in nitpicking\n> mood tonight.\n\nIt's Perl.  There does seem to be a lot of nitpicking when people write\nPerl.\n\n(If you write it in idiomatic Perl, the non-Perl users hate you.  If you\nwrite it like C, the Perl users complain that you write it like C.\n*sigh*)\n\n> Thanks for the patch.  Overall, very good intent.  Slightly\n> troublesome details.\n\nThanks.\n\nI'll have a series of patches out in a few minutes that will update what\nI originally sent to fix your issues here.\n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"6687","messageId":"20050731235439.GI32263@mythryan2.michonline.com","threadId":"1376","inReplyTo":"Pine.LNX.4.58.0507311223240.16181@wgmdd8.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-07-31T23:54:39Z","receivedAt":"2005-07-31T23:54:39Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Sun, Jul 31, 2005 at 12:25:13PM +0200, Johannes Schindelin wrote:\n> Hi,\n> \n> wouldn't it be a good idea to make $from and $to required parameters? At\n> least you could infer a sensible default of $from from GIT_* environment\n> variables, no? I am not quite comfortable with a hard coded sender in a\n> script possibly deployed into a multi-user environment.\n\nThe sender isn't hardcoded.\n\nIf it isn't sent on the command line, the return value from git-var -l\nis used to set a default, which is then confirmed by the ReadLine\ninterface.\n\nSome of the comments were leftover from Greg's original, before I\nremembered to remove them - it should be better now if you take another\nlook.  (See my, soon to be sent, set of additional changes.)\n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"6690","messageId":"7vk6j6a3rh.fsf@assigned-by-dhcp.cox.net","threadId":"1376","inReplyTo":"20050731235242.GH32263@mythryan2.michonline.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-01T00:40:18Z","receivedAt":"2005-08-01T00:40:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ryan Anderson <ryan@michonline.com> writes:\n\n> If I hope that nobody has done something like:\n> \tGIT_AUTHOR=\"Ryan <> Anderson\"\n> \tGIT_AUTHOR_EMAIL=\"ryan@michonline.com\"\n>\n> I get more confusing results.\n\nThe function git_author_info() would remove <> from the above\nGIT_AUTHOR_* environment values by calling ident.c:copy(), so I\nthink you would get more-or-less what you _should_ expect without\ngetting confused.\n\n    $ GIT_AUTHOR_NAME=\"Ryan <> Anderson\" \\\n      GIT_AUTHOR_EMAIL=\"ryan@michonline.com\" git-var -l\n    GIT_COMMITTER_IDENT=Junio C Hamano <junkio@cox.net> 1122855849 -0700\n    GIT_AUTHOR_IDENT=Ryan  Anderson <ryan@michonline.com> 1122855849 -0700\n\n>> Is this the culprit that produced this mechanical-looking line?\n>> \n>>     To: junkio@cox.net,git@vger.kernel.org\n>\n> No, that line was exactly what I put into the readline entry.\n\nI was mostly talking about Email::Valid seeming to be stripping\nout the display-name[*] part and keeping only addr-spec[*] part,\nlike this:\n\n    $ cat j.perl\n    #!/usr/bin/perl\n    use Email::Valid;\n    for ('Junio C Hamano <junkio@cox.net>',\n         'Ryan Anderson <ryan@michonline.com>') {\n        print $_, \" => \", lc(Email::Valid->address($_)), \"\\n\";\n    }\n    $ perl j.perl\n    Junio C Hamano <junkio@cox.net> => junkio@cox.net\n    Ryan Anderson <ryan@michonline.com> => ryan@michonline.com\n\nAlso, I wonder if running lc() to downcase the local-part[*] is\nsafe/allowed/correct; domain[*] part is case insensitive and\nshould be OK to downcase, though.\n\n> ..., because of the way I pull in all the relevant emails\n> from various places.  So I really needed a way to cull the duplicates.\n> ...  I could do soemthing like this, instead, I suppose:\n\nI understand your needs, and you can make it a \"sub\nfilter_dups\", which I think would make things a lot more\npleasant to read.\n\n\n[Footnote]\n\nTerms marked [*] are from RFC2822, section 3.4.\n"},{"id":"6699","messageId":"pan.2005.08.01.07.59.50.252244@smurf.noris.de","threadId":"1376","inReplyTo":"7vk6j6a3rh.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-08-01T07:59:52Z","receivedAt":"2005-08-01T07:59:52Z","isPatch":true,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Junio C Hamano wrote:\n\n> Also, I wonder if running lc() to downcase the local-part[*] is\n> safe/allowed/correct\n\nmostly/no/no.\n\nIt's unlikely to be a real-life problem, but we still shouldn't do it.\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\nAmusements to virtue are like breezes of air to the flame -- gentle ones will\nfan it, but strong ones will put it out.\n\t\t\t\t\t-- David Thomas\n"},{"id":"6716","messageId":"20050802124824.GA13096@uglybox.localnet","threadId":"1376","inReplyTo":"7vk6j52qhn.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [OT] Perl-ish perl vs. C-ish perl.","fromName":"Noel Maddy","fromEmail":"noel@zhtwn.com","sentAt":"2005-08-02T12:48:24Z","receivedAt":"2005-08-02T12:48:24Z","isPatch":false,"sender":{"key":"noel@zhtwn.com","avatar":null},"body":"On Mon, Aug 01, 2005 at 04:21:08PM -0700, Junio C Hamano wrote:\n> Noel Maddy <noel@zhtwn.com> writes:\n\n(silly perl stuff)\n\n> Please refrain from making this thread \"I know more Perl than\n> you do\"; thank you.\n\nSorry. Just trying to help, but suitably chastened.\n\nThanks\n\n-- \nTime is an illusion.  Lunchtime doubly so.\n\t\t\t\t\t\t\t-- Ford Prefect\n+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\nNoel Maddy <noel@zhtwn.com>\n"},{"id":"6717","messageId":"7v3bpscn1r.fsf@assigned-by-dhcp.cox.net","threadId":"1376","inReplyTo":"20050802124824.GA13096@uglybox.localnet","subject":"Re: [OT] Perl-ish perl vs. C-ish perl.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-02T16:37:36Z","receivedAt":"2005-08-02T16:37:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Noel Maddy <noel@zhtwn.com> writes:\n\n>> Please refrain from making this thread \"I know more Perl than\n>> you do\"; thank you.\n>\n> Sorry. Just trying to help, but suitably chastened.\n\nI realize that what you sent was not _too_ Perlish and being\nhelpful.  If you feel I overreacted, I am sorry; I _do_ think I\ndid overreact, attempting to be preemptive.\n"},{"id":"6718","messageId":"20050802172040.GA20527@uglybox.localnet","threadId":"1376","inReplyTo":"7v3bpscn1r.fsf@assigned-by-dhcp.cox.net","subject":"Re: [OT] Perl-ish perl vs. C-ish perl.","fromName":"Noel Maddy","fromEmail":"noel@zhtwn.com","sentAt":"2005-08-02T17:20:40Z","receivedAt":"2005-08-02T17:20:40Z","isPatch":false,"sender":{"key":"noel@zhtwn.com","avatar":null},"body":"On Tue, Aug 02, 2005 at 09:37:36AM -0700, Junio C Hamano wrote:\n> Noel Maddy <noel@zhtwn.com> writes:\n> \n> >> Please refrain from making this thread \"I know more Perl than\n> >> you do\"; thank you.\n> >\n> > Sorry. Just trying to help, but suitably chastened.\n> \n> I realize that what you sent was not _too_ Perlish and being\n> helpful.  If you feel I overreacted, I am sorry; I _do_ think I\n> did overreact, attempting to be preemptive.\n\nNo, I don't think you overreacted. Well, maybe a _little_ bit. ;)\n\nI think you're focused on making git good (as in reliable and\nmaintainable), and that strong focus is admirable.\n\nYour clarification on the expected developer profile, and how to target\nthe code to those developers helps, too.\n\nFor those of us who've spent years living in Perl, the idioms come much\neasier than those who are coming from other languages like C. But if\nthe expected maintainers are not perl weenies (like me, I guess), then\nyou're right, it's better to stay away from the more perl-y stuffy.\n\nAgain, thanks.\n\n> \n\n-- \nIf we can't define the user experience of Windows so that all Windows\nmachines operate the same way, then the Windows brand is meaningless.\n\t\t\t\t\t\t\t  -- Bill Gates\n+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\nNoel Maddy <noel@zhtwn.com>\n"},{"id":"6736","messageId":"20050803013042.GF5762@mythryan2.michonline.com","threadId":"1376","inReplyTo":"7vbr4jmhqe.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-08-03T01:30:42Z","receivedAt":"2005-08-03T01:30:42Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Sun, Jul 31, 2005 at 02:45:29AM -0700, Junio C Hamano wrote:\n> Ryan Anderson <ryan@michonline.com> writes:\n> \n> > \tAll emails are sent as a reply to the previous email, making it easy to\n> > \tskip a collection of emails that are uninteresting.\n> \n> I understand why _some_ people consider this preferable, but\n> wonder if this should have a knob to be tweaked.\n> \n> For example, I myself often find it very hard to read when\n> a cascading thread goes very deep like this:\n> \n>      [PATCH 0/9] cover\n>        [PATCH 1/9] first one\n>          [PATCH 2/9] second one\n>           [PATCH 3/9] third one in the series\n>             ...\n> \n> and prefer to see this instead (this assumes your MUA is\n> half-way decent and lets you sort by subject):\n> \n>      [PATCH 0/9] cover\n>        [PATCH 1/9] first one\n>        [PATCH 2/9] second one\n>        [PATCH 3/9] third one in the series\n>        ...\n\nIn testing this, I think I figured out *why* the former is preferred -\nit guarantees the sorting when in the standard mode of \"order by date\".\n\nSince these emails are sent *very* fast, delivery order tends to be the\ndominating factor in how they sort in your inbox, as they will all have\nthe same time.  So that's a trifle annoying.\n\nYes, sorting by subject will fix it, but \"threaded + subject\" is\nactually something I'm not sure much of anything supports.  (It's not\ninstantly obvious how to do it in mutt, for example - though,\nadmittedly, Mutt may very well have a way to do it.)\n\nI noticed this while testing my 2 new fixes - those will sent in a few\nseconds.\n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"6746","messageId":"pan.2005.08.03.07.32.15.169731@smurf.noris.de","threadId":"1376","inReplyTo":"20050803013042.GF5762@mythryan2.michonline.com","subject":"Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-08-03T07:32:15Z","receivedAt":"2005-08-03T07:32:15Z","isPatch":true,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Ryan Anderson wrote:\n\n> Since these emails are sent *very* fast, delivery order tends to be the\n> dominating factor in how they sort in your inbox, as they will all have\n> the same time.  So that's a trifle annoying.\n\nThat's trivially fixable: just generate your own Date: header and\nadd a second for each email.\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\nBe careful whilst playing under the anvil tree.\n"}]}