name-rev: fix off-by-one error in --stdin.
[gitweb.git] / git-mv.perl
index a21d87eea88d4b1e9a40e4e7f7b836374f566c70..b2eace5b26ce9e01535ee9f430dcd8c9ac78d46f 100755 (executable)
@@ -103,13 +103,22 @@ ()
        $bad = "bad source '$src'";
     }
 
+    $safesrc = quotemeta($src);
+    @srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
+
     $overwritten{$dst} = 0;
     if (($bad eq "") && -e $dst) {
        $bad = "destination '$dst' already exists";
-       if (-f $dst && $opt_f) {
-           print "Warning: $bad; will overwrite!\n";
-           $bad = "";
-           $overwritten{$dst} = 1;
+       if ($opt_f) {
+           # only files can overwrite each other: check both source and destination
+           if (-f $dst && (scalar @srcfiles == 1)) {
+               print "Warning: $bad; will overwrite!\n";
+               $bad = "";
+               $overwritten{$dst} = 1;
+           }
+           else {
+               $bad = "Can not overwrite '$src' with '$dst'";
+           }
        }
     }
     
@@ -118,8 +127,6 @@ ()
     }
 
     if ($bad eq "") {
-       $safesrc = quotemeta($src);
-       @srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
         if (scalar @srcfiles == 0) {
            $bad = "'$src' not under version control";
        }
@@ -166,10 +173,12 @@ ()
 
     push @deletedfiles, @srcfiles;
     if (scalar @srcfiles == 1) {
+       # $dst can be a directory with 1 file inside
        if ($overwritten{$dst} ==1) {
-           push @changedfiles, $dst;
+           push @changedfiles, $dstfiles[0];
+
        } else {
-           push @addedfiles, $dst;
+           push @addedfiles, $dstfiles[0];
        }
     }
     else {
@@ -184,14 +193,27 @@ ()
        exit(1);
 }
        
-my $rc;
-if (scalar @changedfiles >0) {
-       $rc = system("git-update-index","--",@changedfiles);
-       die "git-update-index failed to update changed files with code $?\n" if $rc;
+if (@changedfiles) {
+       open(H, "| git-update-index -z --stdin")
+               or die "git-update-index failed to update changed files with code $!\n";
+       foreach my $fileName (@changedfiles) {
+               print H "$fileName\0";
+       }
+       close(H);
+}
+if (@addedfiles) {
+       open(H, "| git-update-index --add -z --stdin")
+               or die "git-update-index failed to add new names with code $!\n";
+       foreach my $fileName (@addedfiles) {
+               print H "$fileName\0";
+       }
+       close(H);
 }
-if (scalar @addedfiles >0) {
-       $rc = system("git-update-index","--add","--",@addedfiles);
-       die "git-update-index failed to add new names with code $?\n" if $rc;
+if (@deletedfiles) {
+       open(H, "| git-update-index --remove -z --stdin")
+               or die "git-update-index failed to remove old names with code $!\n";
+       foreach my $fileName (@deletedfiles) {
+               print H "$fileName\0";
+       }
+       close(H);
 }
-$rc = system("git-update-index","--remove","--",@deletedfiles);
-die "git-update-index failed to remove old names with code $?\n" if $rc;