git send-email: interpret unknown files as revision lists
Filter out all the arguments git-send-email doesn't like to a git format-patch command, that dumps its content to a safe directory. Barf when a file/revision conflict occurs, allow it to be overriden --[no-]format-patch. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
caf0c3d692
commit
5df9fcf695
@ -8,7 +8,7 @@ git-send-email - Send a collection of patches as emails
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git send-email' [options] <file|directory> [... file|directory]
|
||||
'git send-email' [options] <file|directory|rev-list options>...
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
@ -183,6 +183,12 @@ Administering
|
||||
--[no-]validate::
|
||||
Perform sanity checks on patches.
|
||||
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
|
||||
|
@ -22,8 +22,12 @@ use Term::ReadLine;
|
||||
use Getopt::Long;
|
||||
use Data::Dumper;
|
||||
use Term::ANSIColor;
|
||||
use File::Temp qw/ tempdir /;
|
||||
use Error qw(:try);
|
||||
use Git;
|
||||
|
||||
Getopt::Long::Configure qw/ pass_through /;
|
||||
|
||||
package FakeTerm;
|
||||
sub new {
|
||||
my ($class, $reason) = @_;
|
||||
@ -38,7 +42,7 @@ package main;
|
||||
|
||||
sub usage {
|
||||
print <<EOT;
|
||||
git send-email [options] <file | directory>...
|
||||
git send-email [options] <file | directory | rev-list options >
|
||||
|
||||
Composing:
|
||||
--from <str> * Email From:
|
||||
@ -73,6 +77,8 @@ git send-email [options] <file | directory>...
|
||||
--quiet * Output one line of info per email.
|
||||
--dry-run * Don't actually send the emails.
|
||||
--[no-]validate * Perform patch sanity checks. Default on.
|
||||
--[no-]format-patch * understand any non optional arguments as
|
||||
`git format-patch` ones.
|
||||
|
||||
EOT
|
||||
exit(1);
|
||||
@ -146,6 +152,7 @@ if ($@) {
|
||||
|
||||
# Behavior modification variables
|
||||
my ($quiet, $dry_run) = (0, 0);
|
||||
my $format_patch;
|
||||
my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$";
|
||||
|
||||
# Variables with corresponding config settings
|
||||
@ -229,6 +236,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
|
||||
"envelope-sender=s" => \$envelope_sender,
|
||||
"thread!" => \$thread,
|
||||
"validate!" => \$validate,
|
||||
"format-patch!" => \$format_patch,
|
||||
);
|
||||
|
||||
unless ($rc) {
|
||||
@ -363,23 +371,52 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
|
||||
|
||||
($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
|
||||
# arguments and collect up the files that need to be processed.
|
||||
for my $f (@ARGV) {
|
||||
if (-d $f) {
|
||||
my @rev_list_opts;
|
||||
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)
|
||||
or die "Failed to opendir $f: $!";
|
||||
|
||||
push @files, grep { -f $_ } map { +$f . "/" . $_ }
|
||||
sort readdir(DH);
|
||||
closedir(DH);
|
||||
} elsif (-f $f or -p $f) {
|
||||
} elsif ((-f $f or -p $f) and !check_file_rev_conflict($f)) {
|
||||
push @files, $f;
|
||||
} 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) {
|
||||
foreach my $f (@files) {
|
||||
unless (-p $f) {
|
||||
|
@ -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
|
||||
'
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user