From: Rasmus Villemoes <rv@rasmusvillemoes.dk>
To: gitster@pobox.com
Cc: git@vger.kernel.org, Rasmus Villemoes <rv@rasmusvillemoes.dk>
Subject: [RFC] git-send-email: Cache generated message-ids, use them when prompting
Date: Sat, 17 Aug 2013 00:58:46 +0000 [thread overview]
Message-ID: <1376701126-5759-1-git-send-email-rv@rasmusvillemoes.dk> (raw)
This is mostly a proof of concept/RFC patch. The idea is for
git-send-email to store the message-ids it generates, along with the
Subject and Date headers of the message. When prompting for which
Message-ID should be used in In-Reply-To, display a list of recent
emails (identifed using the Date/Subject pairs; the message-ids
themselves are not for human consumption). Choosing from that list
will then use the corresponding message-id; otherwise, the behaviour
is as usual.
When composing v2 or v3 of a patch or patch series, this avoids the
need to get one's MUA to display the Message-ID of the earlier email
(which is cumbersome in some MUAs) and then copy-paste that.
If this idea is accepted, I'm certain I'll get to use the feature
immediately, since the patch is not quite ready for inclusion :-)
Signed-off-by: Rasmus Villemoes <rv@rasmusvillemoes.dk>
---
git-send-email.perl | 101 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 96 insertions(+), 5 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index f608d9b..2e3685c 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -26,6 +26,7 @@ use Data::Dumper;
use Term::ANSIColor;
use File::Temp qw/ tempdir tempfile /;
use File::Spec::Functions qw(catfile);
+use Date::Parse;
use Error qw(:try);
use Git;
@@ -203,6 +204,7 @@ my ($validate, $confirm);
my (@suppress_cc);
my ($auto_8bit_encoding);
my ($compose_encoding);
+my ($msgid_cache_file, $msgid_maxprompt);
my ($debug_net_smtp) = 0; # Net::SMTP, see send_message()
@@ -214,7 +216,7 @@ my %config_bool_settings = (
"signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated
"validate" => [\$validate, 1],
"multiedit" => [\$multiedit, undef],
- "annotate" => [\$annotate, undef]
+ "annotate" => [\$annotate, undef],
);
my %config_settings = (
@@ -237,6 +239,7 @@ my %config_settings = (
"from" => \$sender,
"assume8bitencoding" => \$auto_8bit_encoding,
"composeencoding" => \$compose_encoding,
+ "msgidcachefile" => \$msgid_cache_file,
);
my %config_path_settings = (
@@ -311,6 +314,7 @@ my $rc = GetOptions("h" => \$help,
"8bit-encoding=s" => \$auto_8bit_encoding,
"compose-encoding=s" => \$compose_encoding,
"force" => \$force,
+ "msgid-cache-file=s" => \$msgid_cache_file,
);
usage() if $help;
@@ -784,10 +788,31 @@ sub expand_one_alias {
@bcclist = validate_address_list(sanitize_address_list(@bcclist));
if ($thread && !defined $initial_reply_to) {
- $initial_reply_to = ask(
- "Message-ID to be used as In-Reply-To for the first email (if any)? ",
- default => "",
- valid_re => qr/\@.*\./, confirm_only => 1);
+ my @choices;
+ if ($msgid_cache_file) {
+ @choices = msgid_cache_getmatches();
+ }
+ if (@choices) {
+ my $prompt = '';
+ my $i = 0;
+ $prompt .= sprintf "(%d) [%s] %s\n", $i++, $_->{date}, $_->{subject}
+ for (@choices);
+ $prompt .= sprintf "Answer 0-%d to use the Message-ID of one of the above\n", $#choices;
+ $prompt .= "Message-ID to be used as In-Reply-To for the first email (if any)? ";
+ $initial_reply_to =
+ ask($prompt,
+ default => "",
+ valid_re => qr/\@.*\.|^[0-9]+$/, confirm_only => 1);
+ if ($initial_reply_to =~ /^[0-9]+$/ && $initial_reply_to < @choices) {
+ $initial_reply_to = $choices[$initial_reply_to]{id};
+ }
+ }
+ else {
+ $initial_reply_to =
+ ask("Message-ID to be used as In-Reply-To for the first email (if any)? ",
+ default => "",
+ valid_re => qr/\@.*\./, confirm_only => 1);
+ }
}
if (defined $initial_reply_to) {
$initial_reply_to =~ s/^\s*<?//;
@@ -1282,6 +1307,8 @@ X-Mailer: git-send-email $gitversion
}
}
+ msgid_cache_this($message_id, $subject, $date) if ($msgid_cache_file && !$dry_run);
+
return 1;
}
@@ -1508,6 +1535,8 @@ sub cleanup_compose_files {
$smtp->quit if $smtp;
+msgid_cache_write() if $msgid_cache_file;
+
sub unique_email_list {
my %seen;
my @emails;
@@ -1556,3 +1585,65 @@ sub body_or_subject_has_nonascii {
}
return 0;
}
+
+my @msgid_new_entries;
+
+# For now, use a simple tab-separated format:
+#
+# $id\t$date\t$subject\n
+sub msgid_cache_read {
+ my $fh;
+ my $line;
+ my @entries;
+ if (not open ($fh, '<', $msgid_cache_file)) {
+ # A non-existing cache file is ok, but should we warn if errno != ENOENT?
+ return ();
+ }
+ while ($line = <$fh>) {
+ chomp($line);
+ my ($id, $date, $subject) = split /\t/, $line;
+ my $epoch = str2time($date);
+ push @entries, {id=>$id, date=>$date, epoch=>$epoch, subject=>$subject};
+ }
+ close($fh);
+ return @entries;
+}
+sub msgid_cache_write {
+ my $fh;
+ if (not open($fh, '>>', $msgid_cache_file)) {
+ warn "cannot open $msgid_cache_file for appending: $!";
+ return;
+ }
+ printf $fh "%s\t%s\t%s\n", $_->{id}, $_->{date}, $_->{subject} for (@msgid_new_entries);
+ close($fh);
+}
+# Return an array of cached message-ids, ordered by "relevance". It
+# might make sense to take the Subject of the new mail as an extra
+# argument and do some kind of fuzzy matching against the old
+# subjects, but for now "more relevant" simply means "newer".
+sub msgid_cache_getmatches {
+ my ($maxentries) = @_;
+ $maxentries //= 10;
+ my @list = msgid_cache_read();
+ @list = sort {$b->{epoch} <=> $a->{epoch}} @list;
+ @list = @list[0 .. $maxentries-1] if (@list > $maxentries);
+ return @list;
+}
+
+sub msgid_cache_this {
+ my $msgid = shift;
+ my $subject = shift;
+ my $date = shift;
+ # Make sure there are no tabs which will confuse us, and save
+ # some valuable horizontal real-estate by removing redundant
+ # whitespace.
+ if ($subject) {
+ $subject =~ s/^\s+|\s+$//g;
+ $subject =~ s/\s+/ /g;
+ }
+ # Replace undef or the empty string by an actual string. Nobody uses "0" as the subject...
+ $subject ||= '(none)';
+ $date //= format_2822_time(time());
+ $date =~ s/\s+/ /g;
+ push @msgid_new_entries, {id => $msgid, subject => $subject, date => $date};
+}
--
1.8.4.rc3.2.gb900fc8
next reply other threads:[~2013-08-17 0:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-17 0:58 Rasmus Villemoes [this message]
2013-08-18 21:08 ` [RFC] git-send-email: Cache generated message-ids, use them when prompting Junio C Hamano
2013-08-18 22:24 ` brian m. carlson
2013-08-21 19:04 ` [PATCH v2 0/2] git-send-email: Message-ID caching Rasmus Villemoes
2013-08-21 19:04 ` [PATCH 1/2] git-send-email: add optional 'choices' parameter to the ask sub Rasmus Villemoes
2013-08-21 19:04 ` [PATCH 2/2] git-send-email: Cache generated message-ids, use them when prompting Rasmus Villemoes
2013-08-22 0:20 ` [PATCH v2 0/2] git-send-email: Message-ID caching 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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1376701126-5759-1-git-send-email-rv@rasmusvillemoes.dk \
--to=rv@rasmusvillemoes.dk \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).