add -p: adjust offsets of subsequent hunks when one is skipped
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Thu, 1 Mar 2018 10:51:00 +0000 (10:51 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 1 Mar 2018 19:39:15 +0000 (11:39 -0800)
Since commit 8cbd431082 ("git-add--interactive: replace hunk
recounting with apply --recount", 2008-7-2) if a hunk is skipped then
we rely on the context lines to apply subsequent hunks in the right
place. While this works most of the time it is possible for hunks to
end up being applied in the wrong place. To fix this adjust the offset
of subsequent hunks to correct for any change in the number of
insertions or deletions due to the skipped hunk. The change in offset
due to edited hunks that have the number of insertions or deletions
changed is ignored here, it will be fixed in the next commit.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-add--interactive.perl
t/t3701-add-interactive.sh
index 64f869c3b7fe89ea698b78645554b94c665dcd6f..6f6a21dc11e23be13a14beb24ed670c232925f4a 100755 (executable)
@@ -926,14 +926,25 @@ sub coalesce_overlapping_hunks {
        my @out = ();
 
        my ($last_o_ctx, $last_was_dirty);
+       my $ofs_delta = 0;
 
-       for (grep { $_->{USE} } @in) {
+       for (@in) {
                if ($_->{TYPE} ne 'hunk') {
                        push @out, $_;
                        next;
                }
                my $text = $_->{TEXT};
-               my ($o_ofs) = parse_hunk_header($text->[0]);
+               my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
+                                               parse_hunk_header($text->[0]);
+               unless ($_->{USE}) {
+                       $ofs_delta += $o_cnt - $n_cnt;
+                       next;
+               }
+               if ($ofs_delta) {
+                       $n_ofs += $ofs_delta;
+                       $_->{TEXT}->[0] = format_hunk_header($o_ofs, $o_cnt,
+                                                            $n_ofs, $n_cnt);
+               }
                if (defined $last_o_ctx &&
                    $o_ofs <= $last_o_ctx &&
                    !$_->{DIRTY} &&
index fe7c1bef610d3b68042bef0a0bc2a5b7f39df095..6f18a924869bd7116d34cf74f36f1ffdb3ea7677 100755 (executable)
@@ -496,7 +496,7 @@ test_expect_success 'set up pathological context' '
        test_write_lines +b " a" >patch
 '
 
-test_expect_failure 'add -p works with pathological context lines' '
+test_expect_success 'add -p works with pathological context lines' '
        git reset &&
        printf "%s\n" n y |
        git add -p &&