Subject: [PATCH 2/5] git send-email: interpret unknown files as revision lists

From: Pierre Habouzit <[email-masked]>
Date: Tue, 4 Nov 2008 17:24:15 +0100

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.

Signed-off-by: Pierre Habouzit <[email-masked]>
---
 Documentation/git-send-email.txt |    2 +-
 git-send-email.perl              |   28 ++++++++++++++++++++++++----
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 82f5056..4654d4f 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -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
diff --git a/git-send-email.perl b/git-send-email.perl
index aaace02..c29868a 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -22,8 +22,11 @@ use Term::ReadLine;
 use Getopt::Long;
 use Data::Dumper;
 use Term::ANSIColor;
+use File::Temp qw/ tempdir /;
 use Git;
 
+Getopt::Long::Configure qw/ pass_through /;
+
 package FakeTerm;
 sub new {
 	my ($class, $reason) = @_;
@@ -38,7 +41,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:
@@ -363,10 +366,22 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
 
 ($sender) = expand_aliases($sender) if defined $sender;
 
+sub check_file_rev_conflict($) {
+	my $f = shift;
+	if ($repo->command('rev-parse', '--verify', '--quiet', $f)) {
+		die("revision/filename conflict on `$f'");
+	}
+}
+
 # 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) {
+		check_file_rev_conflict($f);
 		opendir(DH,$f)
 			or die "Failed to opendir $f: $!";
 
@@ -374,12 +389,17 @@ for my $f (@ARGV) {
 				sort readdir(DH);
 		closedir(DH);
 	} elsif (-f $f or -p $f) {
+		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) {
-- 
1.5.6.5