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>maint
							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
	
	 Pierre Habouzit
						Pierre Habouzit