Merge branch 'ph/send-email'
* ph/send-email: git send-email: ask less questions when --compose is used. git send-email: add --annotate option git send-email: interpret unknown files as revision lists git send-email: make the message file name more specific.maint
commit
496db64202
|
@ -8,7 +8,7 @@ git-send-email - Send a collection of patches as emails
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git send-email' [options] <file|directory> [... file|directory]
|
'git send-email' [options] <file|directory|rev-list options>...
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
@ -37,9 +37,23 @@ The --bcc option must be repeated for each user you want on the bcc list.
|
||||||
+
|
+
|
||||||
The --cc option must be repeated for each user you want on the cc list.
|
The --cc option must be repeated for each user you want on the cc list.
|
||||||
|
|
||||||
|
--annotate::
|
||||||
|
Review each patch you're about to send in an editor. The setting
|
||||||
|
'sendemail.multiedit' defines if this will spawn one editor per patch
|
||||||
|
or one for all of them at once.
|
||||||
|
|
||||||
--compose::
|
--compose::
|
||||||
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
|
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
|
||||||
introductory message for the patch series.
|
introductory message for the patch series.
|
||||||
|
+
|
||||||
|
When compose is in used, git send-email gets less interactive will use the
|
||||||
|
values of the headers you set there. If the body of the email (what you type
|
||||||
|
after the headers and a blank line) only contains blank (or GIT: prefixed)
|
||||||
|
lines, the summary won't be sent, but git-send-email will still use the
|
||||||
|
Headers values if you don't removed them.
|
||||||
|
+
|
||||||
|
If it wasn't able to see a header in the summary it will ask you about it
|
||||||
|
interactively after quitting your editor.
|
||||||
|
|
||||||
--from::
|
--from::
|
||||||
Specify the sender of the emails. This will default to
|
Specify the sender of the emails. This will default to
|
||||||
|
@ -183,6 +197,12 @@ Administering
|
||||||
--[no-]validate::
|
--[no-]validate::
|
||||||
Perform sanity checks on patches.
|
Perform sanity checks on patches.
|
||||||
Currently, validation means the following:
|
Currently, validation means the following:
|
||||||
|
|
||||||
|
--[no-]format-patch::
|
||||||
|
When an argument may be understood either as a reference or as a file name,
|
||||||
|
choose to understand it as a format-patch argument ('--format-patch')
|
||||||
|
or as a file name ('--no-format-patch'). By default, when such a conflict
|
||||||
|
occurs, git send-email will fail.
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
* Warn of patches that contain lines longer than 998 characters; this
|
* Warn of patches that contain lines longer than 998 characters; this
|
||||||
|
@ -204,6 +224,12 @@ sendemail.aliasfiletype::
|
||||||
Format of the file(s) specified in sendemail.aliasesfile. Must be
|
Format of the file(s) specified in sendemail.aliasesfile. Must be
|
||||||
one of 'mutt', 'mailrc', 'pine', or 'gnus'.
|
one of 'mutt', 'mailrc', 'pine', or 'gnus'.
|
||||||
|
|
||||||
|
sendemail.multiedit::
|
||||||
|
If true (default), a single editor instance will be spawned to edit
|
||||||
|
files you have to edit (patches when '--annotate' is used, and the
|
||||||
|
summary when '--compose' is used). If false, files will be edited one
|
||||||
|
after the other, spawning a new editor each time.
|
||||||
|
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
|
|
|
@ -22,8 +22,12 @@ use Term::ReadLine;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
use Term::ANSIColor;
|
use Term::ANSIColor;
|
||||||
|
use File::Temp qw/ tempdir /;
|
||||||
|
use Error qw(:try);
|
||||||
use Git;
|
use Git;
|
||||||
|
|
||||||
|
Getopt::Long::Configure qw/ pass_through /;
|
||||||
|
|
||||||
package FakeTerm;
|
package FakeTerm;
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, $reason) = @_;
|
my ($class, $reason) = @_;
|
||||||
|
@ -38,7 +42,7 @@ package main;
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
print <<EOT;
|
print <<EOT;
|
||||||
git send-email [options] <file | directory>...
|
git send-email [options] <file | directory | rev-list options >
|
||||||
|
|
||||||
Composing:
|
Composing:
|
||||||
--from <str> * Email From:
|
--from <str> * Email From:
|
||||||
|
@ -47,6 +51,7 @@ git send-email [options] <file | directory>...
|
||||||
--bcc <str> * Email Bcc:
|
--bcc <str> * Email Bcc:
|
||||||
--subject <str> * Email "Subject:"
|
--subject <str> * Email "Subject:"
|
||||||
--in-reply-to <str> * Email "In-Reply-To:"
|
--in-reply-to <str> * Email "In-Reply-To:"
|
||||||
|
--annotate * Review each patch that will be sent in an editor.
|
||||||
--compose * Open an editor for introduction.
|
--compose * Open an editor for introduction.
|
||||||
|
|
||||||
Sending:
|
Sending:
|
||||||
|
@ -73,6 +78,8 @@ git send-email [options] <file | directory>...
|
||||||
--quiet * Output one line of info per email.
|
--quiet * Output one line of info per email.
|
||||||
--dry-run * Don't actually send the emails.
|
--dry-run * Don't actually send the emails.
|
||||||
--[no-]validate * Perform patch sanity checks. Default on.
|
--[no-]validate * Perform patch sanity checks. Default on.
|
||||||
|
--[no-]format-patch * understand any non optional arguments as
|
||||||
|
`git format-patch` ones.
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -124,12 +131,10 @@ my $auth;
|
||||||
sub unique_email_list(@);
|
sub unique_email_list(@);
|
||||||
sub cleanup_compose_files();
|
sub cleanup_compose_files();
|
||||||
|
|
||||||
# Constants (essentially)
|
|
||||||
my $compose_filename = ".msg.$$";
|
|
||||||
|
|
||||||
# Variables we fill in automatically, or via prompting:
|
# Variables we fill in automatically, or via prompting:
|
||||||
my (@to,@cc,@initial_cc,@bcclist,@xh,
|
my (@to,@cc,@initial_cc,@bcclist,@xh,
|
||||||
$initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time);
|
$initial_reply_to,$initial_subject,@files,
|
||||||
|
$author,$sender,$smtp_authpass,$annotate,$compose,$time);
|
||||||
|
|
||||||
my $envelope_sender;
|
my $envelope_sender;
|
||||||
|
|
||||||
|
@ -149,6 +154,27 @@ if ($@) {
|
||||||
|
|
||||||
# Behavior modification variables
|
# Behavior modification variables
|
||||||
my ($quiet, $dry_run) = (0, 0);
|
my ($quiet, $dry_run) = (0, 0);
|
||||||
|
my $format_patch;
|
||||||
|
my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$";
|
||||||
|
|
||||||
|
# Handle interactive edition of files.
|
||||||
|
my $multiedit;
|
||||||
|
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
|
||||||
|
sub do_edit {
|
||||||
|
if (defined($multiedit) && !$multiedit) {
|
||||||
|
map {
|
||||||
|
system('sh', '-c', $editor.' "$@"', $editor, $_);
|
||||||
|
if (($? & 127) || ($? >> 8)) {
|
||||||
|
die("the editor exited uncleanly, aborting everything");
|
||||||
|
}
|
||||||
|
} @_;
|
||||||
|
} else {
|
||||||
|
system('sh', '-c', $editor.' "$@"', $editor, @_);
|
||||||
|
if (($? & 127) || ($? >> 8)) {
|
||||||
|
die("the editor exited uncleanly, aborting everything");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Variables with corresponding config settings
|
# Variables with corresponding config settings
|
||||||
my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd);
|
my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd);
|
||||||
|
@ -179,6 +205,7 @@ my %config_settings = (
|
||||||
"aliasesfile" => \@alias_files,
|
"aliasesfile" => \@alias_files,
|
||||||
"suppresscc" => \@suppress_cc,
|
"suppresscc" => \@suppress_cc,
|
||||||
"envelopesender" => \$envelope_sender,
|
"envelopesender" => \$envelope_sender,
|
||||||
|
"multiedit" => \$multiedit,
|
||||||
);
|
);
|
||||||
|
|
||||||
# Handle Uncouth Termination
|
# Handle Uncouth Termination
|
||||||
|
@ -221,6 +248,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
|
||||||
"smtp-ssl" => sub { $smtp_encryption = 'ssl' },
|
"smtp-ssl" => sub { $smtp_encryption = 'ssl' },
|
||||||
"smtp-encryption=s" => \$smtp_encryption,
|
"smtp-encryption=s" => \$smtp_encryption,
|
||||||
"identity=s" => \$identity,
|
"identity=s" => \$identity,
|
||||||
|
"annotate" => \$annotate,
|
||||||
"compose" => \$compose,
|
"compose" => \$compose,
|
||||||
"quiet" => \$quiet,
|
"quiet" => \$quiet,
|
||||||
"cc-cmd=s" => \$cc_cmd,
|
"cc-cmd=s" => \$cc_cmd,
|
||||||
|
@ -231,6 +259,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
|
||||||
"envelope-sender=s" => \$envelope_sender,
|
"envelope-sender=s" => \$envelope_sender,
|
||||||
"thread!" => \$thread,
|
"thread!" => \$thread,
|
||||||
"validate!" => \$validate,
|
"validate!" => \$validate,
|
||||||
|
"format-patch!" => \$format_patch,
|
||||||
);
|
);
|
||||||
|
|
||||||
unless ($rc) {
|
unless ($rc) {
|
||||||
|
@ -368,23 +397,52 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
|
||||||
|
|
||||||
($sender) = expand_aliases($sender) if defined $sender;
|
($sender) = expand_aliases($sender) if defined $sender;
|
||||||
|
|
||||||
|
# returns 1 if the conflict must be solved using it as a format-patch argument
|
||||||
|
sub check_file_rev_conflict($) {
|
||||||
|
my $f = shift;
|
||||||
|
try {
|
||||||
|
$repo->command('rev-parse', '--verify', '--quiet', $f);
|
||||||
|
if (defined($format_patch)) {
|
||||||
|
print "foo\n";
|
||||||
|
return $format_patch;
|
||||||
|
}
|
||||||
|
die(<<EOF);
|
||||||
|
File '$f' exists but it could also be the range of commits
|
||||||
|
to produce patches for. Please disambiguate by...
|
||||||
|
|
||||||
|
* Saying "./$f" if you mean a file; or
|
||||||
|
* Giving --format-patch option if you mean a range.
|
||||||
|
EOF
|
||||||
|
} catch Git::Error::Command with {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Now that all the defaults are set, process the rest of the command line
|
# Now that all the defaults are set, process the rest of the command line
|
||||||
# arguments and collect up the files that need to be processed.
|
# arguments and collect up the files that need to be processed.
|
||||||
for my $f (@ARGV) {
|
my @rev_list_opts;
|
||||||
if (-d $f) {
|
while (my $f = pop @ARGV) {
|
||||||
|
if ($f eq "--") {
|
||||||
|
push @rev_list_opts, "--", @ARGV;
|
||||||
|
@ARGV = ();
|
||||||
|
} elsif (-d $f and !check_file_rev_conflict($f)) {
|
||||||
opendir(DH,$f)
|
opendir(DH,$f)
|
||||||
or die "Failed to opendir $f: $!";
|
or die "Failed to opendir $f: $!";
|
||||||
|
|
||||||
push @files, grep { -f $_ } map { +$f . "/" . $_ }
|
push @files, grep { -f $_ } map { +$f . "/" . $_ }
|
||||||
sort readdir(DH);
|
sort readdir(DH);
|
||||||
closedir(DH);
|
closedir(DH);
|
||||||
} elsif (-f $f or -p $f) {
|
} elsif ((-f $f or -p $f) and !check_file_rev_conflict($f)) {
|
||||||
push @files, $f;
|
push @files, $f;
|
||||||
} else {
|
} else {
|
||||||
print STDERR "Skipping $f - not found.\n";
|
push @rev_list_opts, $f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (@rev_list_opts) {
|
||||||
|
push @files, $repo->command('format-patch', '-o', tempdir(CLEANUP => 1), @rev_list_opts);
|
||||||
|
}
|
||||||
|
|
||||||
if ($validate) {
|
if ($validate) {
|
||||||
foreach my $f (@files) {
|
foreach my $f (@files) {
|
||||||
unless (-p $f) {
|
unless (-p $f) {
|
||||||
|
@ -403,6 +461,108 @@ if (@files) {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_patch_subject($) {
|
||||||
|
my $fn = shift;
|
||||||
|
open (my $fh, '<', $fn);
|
||||||
|
while (my $line = <$fh>) {
|
||||||
|
next unless ($line =~ /^Subject: (.*)$/);
|
||||||
|
close $fh;
|
||||||
|
return "GIT: $1\n";
|
||||||
|
}
|
||||||
|
close $fh;
|
||||||
|
die "No subject line in $fn ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($compose) {
|
||||||
|
# Note that this does not need to be secure, but we will make a small
|
||||||
|
# effort to have it be unique
|
||||||
|
open(C,">",$compose_filename)
|
||||||
|
or die "Failed to open for writing $compose_filename: $!";
|
||||||
|
|
||||||
|
|
||||||
|
my $tpl_sender = $sender || $repoauthor || $repocommitter || '';
|
||||||
|
my $tpl_subject = $initial_subject || '';
|
||||||
|
my $tpl_reply_to = $initial_reply_to || '';
|
||||||
|
|
||||||
|
print C <<EOT;
|
||||||
|
From $tpl_sender # This line is ignored.
|
||||||
|
GIT: Lines beginning in "GIT: " will be removed.
|
||||||
|
GIT: Consider including an overall diffstat or table of contents
|
||||||
|
GIT: for the patch you are writing.
|
||||||
|
GIT:
|
||||||
|
GIT: Clear the body content if you don't wish to send a summary.
|
||||||
|
From: $tpl_sender
|
||||||
|
Subject: $tpl_subject
|
||||||
|
In-Reply-To: $tpl_reply_to
|
||||||
|
|
||||||
|
EOT
|
||||||
|
for my $f (@files) {
|
||||||
|
print C get_patch_subject($f);
|
||||||
|
}
|
||||||
|
close(C);
|
||||||
|
|
||||||
|
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
|
||||||
|
|
||||||
|
if ($annotate) {
|
||||||
|
do_edit($compose_filename, @files);
|
||||||
|
} else {
|
||||||
|
do_edit($compose_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
open(C2,">",$compose_filename . ".final")
|
||||||
|
or die "Failed to open $compose_filename.final : " . $!;
|
||||||
|
|
||||||
|
open(C,"<",$compose_filename)
|
||||||
|
or die "Failed to open $compose_filename : " . $!;
|
||||||
|
|
||||||
|
my $need_8bit_cte = file_has_nonascii($compose_filename);
|
||||||
|
my $in_body = 0;
|
||||||
|
my $summary_empty = 1;
|
||||||
|
while(<C>) {
|
||||||
|
next if m/^GIT: /;
|
||||||
|
if ($in_body) {
|
||||||
|
$summary_empty = 0 unless (/^\n$/);
|
||||||
|
} elsif (/^\n$/) {
|
||||||
|
$in_body = 1;
|
||||||
|
if ($need_8bit_cte) {
|
||||||
|
print C2 "MIME-Version: 1.0\n",
|
||||||
|
"Content-Type: text/plain; ",
|
||||||
|
"charset=utf-8\n",
|
||||||
|
"Content-Transfer-Encoding: 8bit\n";
|
||||||
|
}
|
||||||
|
} elsif (/^MIME-Version:/i) {
|
||||||
|
$need_8bit_cte = 0;
|
||||||
|
} elsif (/^Subject:\s*(.+)\s*$/i) {
|
||||||
|
$initial_subject = $1;
|
||||||
|
my $subject = $initial_subject;
|
||||||
|
$_ = "Subject: " .
|
||||||
|
($subject =~ /[^[:ascii:]]/ ?
|
||||||
|
quote_rfc2047($subject) :
|
||||||
|
$subject) .
|
||||||
|
"\n";
|
||||||
|
} elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
|
||||||
|
$initial_reply_to = $1;
|
||||||
|
next;
|
||||||
|
} elsif (/^From:\s*(.+)\s*$/i) {
|
||||||
|
$sender = $1;
|
||||||
|
next;
|
||||||
|
} elsif (/^(?:To|Cc|Bcc):/i) {
|
||||||
|
print "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
print C2 $_;
|
||||||
|
}
|
||||||
|
close(C);
|
||||||
|
close(C2);
|
||||||
|
|
||||||
|
if ($summary_empty) {
|
||||||
|
print "Summary email is empty, skipping it\n";
|
||||||
|
$compose = -1;
|
||||||
|
}
|
||||||
|
} elsif ($annotate) {
|
||||||
|
do_edit(@files);
|
||||||
|
}
|
||||||
|
|
||||||
my $prompting = 0;
|
my $prompting = 0;
|
||||||
if (!defined $sender) {
|
if (!defined $sender) {
|
||||||
$sender = $repoauthor || $repocommitter || '';
|
$sender = $repoauthor || $repocommitter || '';
|
||||||
|
@ -447,17 +607,6 @@ sub expand_aliases {
|
||||||
@initial_cc = expand_aliases(@initial_cc);
|
@initial_cc = expand_aliases(@initial_cc);
|
||||||
@bcclist = expand_aliases(@bcclist);
|
@bcclist = expand_aliases(@bcclist);
|
||||||
|
|
||||||
if (!defined $initial_subject && $compose) {
|
|
||||||
while (1) {
|
|
||||||
$_ = $term->readline("What subject should the initial email start with? ", $initial_subject);
|
|
||||||
last if defined $_;
|
|
||||||
print "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$initial_subject = $_;
|
|
||||||
$prompting++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($thread && !defined $initial_reply_to && $prompting) {
|
if ($thread && !defined $initial_reply_to && $prompting) {
|
||||||
while (1) {
|
while (1) {
|
||||||
$_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to);
|
$_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to);
|
||||||
|
@ -484,59 +633,6 @@ if (!defined $smtp_server) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($compose) {
|
if ($compose) {
|
||||||
# Note that this does not need to be secure, but we will make a small
|
|
||||||
# effort to have it be unique
|
|
||||||
open(C,">",$compose_filename)
|
|
||||||
or die "Failed to open for writing $compose_filename: $!";
|
|
||||||
print C "From $sender # This line is ignored.\n";
|
|
||||||
printf C "Subject: %s\n\n", $initial_subject;
|
|
||||||
printf C <<EOT;
|
|
||||||
GIT: Please enter your email below.
|
|
||||||
GIT: Lines beginning in "GIT: " will be removed.
|
|
||||||
GIT: Consider including an overall diffstat or table of contents
|
|
||||||
GIT: for the patch you are writing.
|
|
||||||
|
|
||||||
EOT
|
|
||||||
close(C);
|
|
||||||
|
|
||||||
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
|
|
||||||
system('sh', '-c', $editor.' "$@"', $editor, $compose_filename);
|
|
||||||
|
|
||||||
open(C2,">",$compose_filename . ".final")
|
|
||||||
or die "Failed to open $compose_filename.final : " . $!;
|
|
||||||
|
|
||||||
open(C,"<",$compose_filename)
|
|
||||||
or die "Failed to open $compose_filename : " . $!;
|
|
||||||
|
|
||||||
my $need_8bit_cte = file_has_nonascii($compose_filename);
|
|
||||||
my $in_body = 0;
|
|
||||||
while(<C>) {
|
|
||||||
next if m/^GIT: /;
|
|
||||||
if (!$in_body && /^\n$/) {
|
|
||||||
$in_body = 1;
|
|
||||||
if ($need_8bit_cte) {
|
|
||||||
print C2 "MIME-Version: 1.0\n",
|
|
||||||
"Content-Type: text/plain; ",
|
|
||||||
"charset=utf-8\n",
|
|
||||||
"Content-Transfer-Encoding: 8bit\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$in_body && /^MIME-Version:/i) {
|
|
||||||
$need_8bit_cte = 0;
|
|
||||||
}
|
|
||||||
if (!$in_body && /^Subject: ?(.*)/i) {
|
|
||||||
my $subject = $1;
|
|
||||||
$_ = "Subject: " .
|
|
||||||
($subject =~ /[^[:ascii:]]/ ?
|
|
||||||
quote_rfc2047($subject) :
|
|
||||||
$subject) .
|
|
||||||
"\n";
|
|
||||||
}
|
|
||||||
print C2 $_;
|
|
||||||
}
|
|
||||||
close(C);
|
|
||||||
close(C2);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
$_ = $term->readline("Send this email? (y|n) ");
|
$_ = $term->readline("Send this email? (y|n) ");
|
||||||
last if defined $_;
|
last if defined $_;
|
||||||
|
@ -548,8 +644,10 @@ EOT
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($compose > 0) {
|
||||||
@files = ($compose_filename . ".final", @files);
|
@files = ($compose_filename . ".final", @files);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Variables we set as part of the loop over files
|
# Variables we set as part of the loop over files
|
||||||
our ($message_id, %mail, $subject, $reply_to, $references, $message);
|
our ($message_id, %mail, $subject, $reply_to, $references, $message);
|
||||||
|
|
|
@ -292,4 +292,12 @@ test_expect_success '--compose adds MIME for utf8 subject' '
|
||||||
grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
|
grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'detects ambiguous reference/file conflict' '
|
||||||
|
echo master > master &&
|
||||||
|
git add master &&
|
||||||
|
git commit -m"add master" &&
|
||||||
|
test_must_fail git send-email --dry-run master 2>errors &&
|
||||||
|
grep disambiguate errors
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in New Issue