git-add--interactive: replace hunk recounting with apply --recount
[gitweb.git] / git-add--interactive.perl
index a0a81f134a6288dfc1d87431698f29597ed5e488..e1964a588ed505aca21c7354ba2b0027ce1f8beb 100755 (executable)
@@ -550,6 +550,21 @@ sub parse_diff {
        return @hunk;
 }
 
+sub parse_diff_header {
+       my $src = shift;
+
+       my $head = { TEXT => [], DISPLAY => [] };
+       my $mode = { TEXT => [], DISPLAY => [] };
+
+       for (my $i = 0; $i < @{$src->{TEXT}}; $i++) {
+               my $dest = $src->{TEXT}->[$i] =~ /^(old|new) mode (\d+)$/ ?
+                       $mode : $head;
+               push @{$dest->{TEXT}}, $src->{TEXT}->[$i];
+               push @{$dest->{DISPLAY}}, $src->{DISPLAY}->[$i];
+       }
+       return ($head, $mode);
+}
+
 sub hunk_splittable {
        my ($text) = @_;
 
@@ -795,9 +810,40 @@ sub patch_update_file {
        my ($ix, $num);
        my $path = shift;
        my ($head, @hunk) = parse_diff($path);
+       ($head, my $mode) = parse_diff_header($head);
        for (@{$head->{DISPLAY}}) {
                print;
        }
+
+       if (@{$mode->{TEXT}}) {
+               while (1) {
+                       print @{$mode->{DISPLAY}};
+                       print colored $prompt_color,
+                               "Stage mode change [y/n/a/d/?]? ";
+                       my $line = <STDIN>;
+                       if ($line =~ /^y/i) {
+                               $mode->{USE} = 1;
+                               last;
+                       }
+                       elsif ($line =~ /^n/i) {
+                               $mode->{USE} = 0;
+                               last;
+                       }
+                       elsif ($line =~ /^a/i) {
+                               $_->{USE} = 1 foreach ($mode, @hunk);
+                               last;
+                       }
+                       elsif ($line =~ /^d/i) {
+                               $_->{USE} = 0 foreach ($mode, @hunk);
+                               last;
+                       }
+                       else {
+                               help_patch_cmd('');
+                               next;
+                       }
+               }
+       }
+
        $num = scalar @hunk;
        $ix = 0;
 
@@ -920,40 +966,19 @@ sub patch_update_file {
 
        my $n_lofs = 0;
        my @result = ();
+       if ($mode->{USE}) {
+               push @result, @{$mode->{TEXT}};
+       }
        for (@hunk) {
-               my $text = $_->{TEXT};
-               my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
-                   parse_hunk_header($text->[0]);
-
-               if (!$_->{USE}) {
-                       # We would have added ($n_cnt - $o_cnt) lines
-                       # to the postimage if we were to use this hunk,
-                       # but we didn't.  So the line number that the next
-                       # hunk starts at would be shifted by that much.
-                       $n_lofs -= ($n_cnt - $o_cnt);
-                       next;
-               }
-               else {
-                       if ($n_lofs) {
-                               $n_ofs += $n_lofs;
-                               $text->[0] = ("@@ -$o_ofs" .
-                                             (($o_cnt != 1)
-                                              ? ",$o_cnt" : '') .
-                                             " +$n_ofs" .
-                                             (($n_cnt != 1)
-                                              ? ",$n_cnt" : '') .
-                                             " @@\n");
-                       }
-                       for (@$text) {
-                               push @result, $_;
-                       }
+               if ($_->{USE}) {
+                       push @result, @{$_->{TEXT}};
                }
        }
 
        if (@result) {
                my $fh;
 
-               open $fh, '| git apply --cached';
+               open $fh, '| git apply --cached --recount';
                for (@{$head->{TEXT}}, @result) {
                        print $fh $_;
                }