add -p: adjust offsets of subsequent hunks when one is skipped

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>

Phillip Wood committed Mar 1, 2018 at 10:51 UTC fecc6f3a6862c55dee0e9a2390acaf4b23991fef
2 files changed +14 -3
git-add--interactive.perl
+13 -2
@@ -926,14 +926,25 @@ sub coalesce_overlapping_hunks {
926 my @out = ();
927
928 my ($last_o_ctx, $last_was_dirty);
929 + my $ofs_delta = 0;
930
930 - for (grep { $_->{USE} } @in) {
931 + for (@in) {
932 if ($_->{TYPE} ne 'hunk') {
933 push @out, $_;
934 next;
935 }
936 my $text = $_->{TEXT};
936 - my ($o_ofs) = parse_hunk_header($text->[0]);
937 + my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
938 + parse_hunk_header($text->[0]);
939 + unless ($_->{USE}) {
940 + $ofs_delta += $o_cnt - $n_cnt;
941 + next;
942 + }
943 + if ($ofs_delta) {
944 + $n_ofs += $ofs_delta;
945 + $_->{TEXT}->[0] = format_hunk_header($o_ofs, $o_cnt,
946 + $n_ofs, $n_cnt);
947 + }
948 if (defined $last_o_ctx &&
949 $o_ofs <= $last_o_ctx &&
950 !$_->{DIRTY} &&
t/t3701-add-interactive.sh
+1 -1
@@ -496,7 +496,7 @@ test_expect_success 'set up pathological context' '
496 test_write_lines +b " a" >patch
497 '
498
499 -test_expect_failure 'add -p works with pathological context lines' '
499 +test_expect_success 'add -p works with pathological context lines' '
500 git reset &&
501 printf "%s\n" n y |
502 git add -p &&