git-add--interactive: Improve behavior on bogus input
[gitweb.git] / git-add--interactive.perl
index dc3038091dd7db7dd4bb96cf8832df789b4d127f..be6881496c88fcffc52031e482bfdd8d03faa66c 100755 (executable)
@@ -3,9 +3,16 @@
 use strict;
 
 sub run_cmd_pipe {
-       my $fh = undef;
-       open($fh, '-|', @_) or die;
-       return <$fh>;
+       if ($^O eq 'MSWin32') {
+               my @invalid = grep {m/[":*]/} @_;
+               die "$^O does not support: @invalid\n" if @invalid;
+               my @args = map { m/ /o ? "\"$_\"": $_ } @_;
+               return qx{@args};
+       } else {
+               my $fh = undef;
+               open($fh, '-|', @_) or die;
+               return <$fh>;
+       }
 }
 
 my ($GIT_DIR) = run_cmd_pipe(qw(git rev-parse --git-dir));
@@ -17,7 +24,7 @@ sub run_cmd_pipe {
 
 sub refresh {
        my $fh;
-       open $fh, '-|', qw(git update-index --refresh)
+       open $fh, 'git update-index --refresh |'
            or die;
        while (<$fh>) {
                ;# ignore 'needs update'
@@ -206,9 +213,13 @@ sub list_and_choose {
                        print ">> ";
                }
                my $line = <STDIN>;
-               last if (!$line);
+               if (!$line) {
+                       print "\n";
+                       $opts->{ON_EOF}->() if $opts->{ON_EOF};
+                       last;
+               }
                chomp $line;
-               my $donesomething = 0;
+               last if $line eq '';
                for my $choice (split(/[\s,]+/, $line)) {
                        my $choose = 1;
                        my ($bottom, $top);
@@ -240,12 +251,11 @@ sub list_and_choose {
                                next TOPLOOP;
                        }
                        for ($i = $bottom-1; $i <= $top-1; $i++) {
-                               next if (@stuff <= $i);
+                               next if (@stuff <= $i || $i < 0);
                                $chosen[$i] = $choose;
-                               $donesomething++;
                        }
                }
-               last if (!$donesomething || $opts->{IMMEDIATE});
+               last if ($opts->{IMMEDIATE});
        }
        for ($i = 0; $i < @stuff; $i++) {
                if ($chosen[$i]) {
@@ -296,7 +306,7 @@ sub revert_cmd {
                my @lines = run_cmd_pipe(qw(git ls-tree HEAD --),
                                         map { $_->{VALUE} } @update);
                my $fh;
-               open $fh, '|-', qw(git update-index --index-info)
+               open $fh, '| git update-index --index-info'
                    or die;
                for (@lines) {
                        print $fh $_;
@@ -725,7 +735,7 @@ sub patch_update_cmd {
        if (@result) {
                my $fh;
 
-               open $fh, '|-', qw(git apply --cached);
+               open $fh, '| git apply --cached';
                for (@{$head->{TEXT}}, @result) {
                        print $fh $_;
                }
@@ -784,6 +794,7 @@ sub main_loop {
                                             SINGLETON => 1,
                                             LIST_FLAT => 4,
                                             HEADER => '*** Commands ***',
+                                            ON_EOF => \&quit_cmd,
                                             IMMEDIATE => 1 }, @cmd);
                if ($it) {
                        eval {