From: Phillip Wood <phillip.wood@talktalk.net> To: Git Mailing List <git@vger.kernel.org> Cc: Junio C Hamano <gitster@pobox.com>, "Brian M. Carlson" <sandals@crustytoothpaste.net>, Eric Sunshine <sunshine@sunshineco.com>, Phillip Wood <phillip.wood@dunelm.org.uk> Subject: [PATCH v4 7/9] add -p: calculate offset delta for edited patches Date: Thu, 1 Mar 2018 10:51:01 +0000 Message-ID: <20180301105103.24268-8-phillip.wood@talktalk.net> (raw) In-Reply-To: <20180301105103.24268-1-phillip.wood@talktalk.net> From: Phillip Wood <phillip.wood@dunelm.org.uk> Recount the number of preimage and postimage lines in a hunk after it has been edited so any change in the number of insertions or deletions can be used to adjust the offsets of subsequent hunks. If an edited hunk is subsequently split then the offset correction will be lost. It would be possible to fix this if it is a problem, however the code here is still an improvement on the status quo for the common case where an edited hunk is applied without being split. This is also a necessary step to removing '--recount' and '--allow-overlap' from the invocation of 'git apply'. Before '--recount' can be removed the splitting and coalescing counting needs to be fixed to handle a missing newline at the end of a file. In order to remove '--allow-overlap' there needs to be i) some way of verifying the offset data in the edited hunk (probably by correlating the preimage (or postimage if the patch is going to be applied in reverse) lines of the edited and unedited versions to see if they are offset or if any leading/trailing context lines have been removed) and ii) a way of dealing with edited hunks that change context lines that are shared with neighbouring hunks. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> --- Notes: changes since v1 - edited hunks are now recounted before seeing if they apply in preparation for removing '--recount' when invoking 'git apply' - added sentence to commit message about the offset data being lost if an edited hunk is split git-add--interactive.perl | 55 ++++++++++++++++++++++++++++++++++++++-------- t/t3701-add-interactive.sh | 2 +- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 7a0a5896bb..0df0c2aa06 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -938,13 +938,19 @@ sub coalesce_overlapping_hunks { parse_hunk_header($text->[0]); unless ($_->{USE}) { $ofs_delta += $o_cnt - $n_cnt; + # If this hunk has been edited then subtract + # the delta that is due to the edit. + $_->{OFS_DELTA} and $ofs_delta -= $_->{OFS_DELTA}; next; } if ($ofs_delta) { $n_ofs += $ofs_delta; $_->{TEXT}->[0] = format_hunk_header($o_ofs, $o_cnt, $n_ofs, $n_cnt); } + # If this hunk was edited then adjust the offset delta + # to reflect the edit. + $_->{OFS_DELTA} and $ofs_delta += $_->{OFS_DELTA}; if (defined $last_o_ctx && $o_ofs <= $last_o_ctx && !$_->{DIRTY} && @@ -1016,6 +1022,30 @@ marked for discarding."), marked for applying."), ); +sub recount_edited_hunk { + local $_; + my ($oldtext, $newtext) = @_; + my ($o_cnt, $n_cnt) = (0, 0); + for (@{$newtext}[1..$#{$newtext}]) { + my $mode = substr($_, 0, 1); + if ($mode eq '-') { + $o_cnt++; + } elsif ($mode eq '+') { + $n_cnt++; + } elsif ($mode eq ' ') { + $o_cnt++; + $n_cnt++; + } + } + my ($o_ofs, undef, $n_ofs, undef) = + parse_hunk_header($newtext->[0]); + $newtext->[0] = format_hunk_header($o_ofs, $o_cnt, $n_ofs, $n_cnt); + my (undef, $orig_o_cnt, undef, $orig_n_cnt) = + parse_hunk_header($oldtext->[0]); + # Return the change in the number of lines inserted by this hunk + return $orig_o_cnt - $orig_n_cnt - $o_cnt + $n_cnt; +} + sub edit_hunk_manually { my ($oldtext) = @_; @@ -1114,25 +1144,32 @@ sub prompt_yesno { } sub edit_hunk_loop { - my ($head, $hunk, $ix) = @_; - my $text = $hunk->[$ix]->{TEXT}; + my ($head, $hunks, $ix) = @_; + my $hunk = $hunks->[$ix]; + my $text = $hunk->{TEXT}; while (1) { - $text = edit_hunk_manually($text); - if (!defined $text) { + my $newtext = edit_hunk_manually($text); + if (!defined $newtext) { return undef; } my $newhunk = { - TEXT => $text, - TYPE => $hunk->[$ix]->{TYPE}, + TEXT => $newtext, + TYPE => $hunk->{TYPE}, USE => 1, DIRTY => 1, }; + $newhunk->{OFS_DELTA} = recount_edited_hunk($text, $newtext); + # If this hunk has already been edited then add the + # offset delta of the previous edit to get the real + # delta from the original unedited hunk. + $hunk->{OFS_DELTA} and + $newhunk->{OFS_DELTA} += $hunk->{OFS_DELTA}; if (diff_applies($head, - @{$hunk}[0..$ix-1], + @{$hunks}[0..$ix-1], $newhunk, - @{$hunk}[$ix+1..$#{$hunk}])) { - $newhunk->{DISPLAY} = [color_diff(@{$text})]; + @{$hunks}[$ix+1..$#{$hunks}])) { + $newhunk->{DISPLAY} = [color_diff(@{$newtext})]; return $newhunk; } else { diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index e3150a4e07..4cc9517eda 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -552,7 +552,7 @@ test_expect_success 'add -p works with pathological context lines' ' test_cmp expected-1 actual ' -test_expect_failure 'add -p patch editing works with pathological context lines' ' +test_expect_success 'add -p patch editing works with pathological context lines' ' git reset && # n q q below is in case edit fails printf "%s\n" e y n q q | -- 2.16.1
next prev parent reply index Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-02-13 10:44 [PATCH 0/4] Correct offsets of hunks when one is skipped Phillip Wood 2018-02-13 10:44 ` [PATCH 1/4] add -i: add function to format hunk header Phillip Wood 2018-02-13 10:44 ` [PATCH 2/4] t3701: add failing test for pathological context lines Phillip Wood 2018-02-13 20:35 ` Junio C Hamano 2018-02-13 10:44 ` [PATCH 3/4] add -p: Adjust offsets of subsequent hunks when one is skipped Phillip Wood 2018-02-13 10:44 ` [PATCH 4/4] add -p: calculate offset delta for edited patches Phillip Wood 2018-02-13 23:56 ` [PATCH 0/4] Correct offsets of hunks when one is skipped brian m. carlson 2018-02-19 13:01 ` Phillip Wood 2018-02-19 11:29 ` [PATCH v2 0/9] " Phillip Wood 2018-02-19 11:29 ` [PATCH v2 1/9] add -i: add function to format hunk header Phillip Wood 2018-02-20 18:21 ` Junio C Hamano 2018-02-19 11:29 ` [PATCH v2 2/9] t3701: indent here documents Phillip Wood 2018-02-19 18:36 ` Eric Sunshine 2018-02-19 11:29 ` [PATCH v2 3/9] t3701: use test_write_lines and write_script Phillip Wood 2018-02-19 18:47 ` Eric Sunshine 2018-02-20 17:19 ` Junio C Hamano 2018-02-21 11:26 ` Phillip Wood 2018-02-19 11:29 ` [PATCH v2 4/9] t3701: don't hard code sha1 hash values Phillip Wood 2018-02-19 18:52 ` Eric Sunshine 2018-02-20 17:39 ` Junio C Hamano 2018-02-21 11:42 ` Phillip Wood 2018-02-21 16:58 ` Junio C Hamano 2018-02-19 11:29 ` [PATCH v2 5/9] t3701: add failing test for pathological context lines Phillip Wood 2018-02-21 11:28 ` Phillip Wood 2018-02-19 11:29 ` [PATCH v2 6/9] add -p: Adjust offsets of subsequent hunks when one is skipped Phillip Wood 2018-02-19 11:29 ` [PATCH v2 7/9] add -p: calculate offset delta for edited patches Phillip Wood 2018-02-19 11:29 ` [PATCH v2 8/9] add -p: fix counting when splitting and coalescing Phillip Wood 2018-02-19 11:29 ` [PATCH v2 9/9] add -p: don't rely on apply's '--recount' option Phillip Wood 2018-02-20 18:50 ` Junio C Hamano 2018-02-27 11:03 ` [PATCH v3 0/9] Correct offsets of hunks when one is skipped Phillip Wood 2018-02-27 11:03 ` [PATCH v3 1/9] add -i: add function to format hunk header Phillip Wood 2018-02-27 11:03 ` [PATCH v3 2/9] t3701: indent here documents Phillip Wood 2018-02-27 22:35 ` Junio C Hamano 2018-02-28 11:00 ` Phillip Wood 2018-02-28 15:37 ` Junio C Hamano 2018-03-01 10:57 ` Phillip Wood 2018-03-01 15:58 ` Junio C Hamano 2018-02-27 11:03 ` [PATCH v3 3/9] t3701: use test_write_lines and write_script Phillip Wood 2018-02-27 11:03 ` [PATCH v3 4/9] t3701: don't hard code sha1 hash values Phillip Wood 2018-02-27 22:42 ` Junio C Hamano 2018-02-28 11:03 ` Phillip Wood 2018-02-28 11:10 ` Phillip Wood 2018-02-27 11:04 ` [PATCH v3 5/9] t3701: add failing test for pathological context lines Phillip Wood 2018-02-27 11:04 ` [PATCH v3 6/9] add -p: Adjust offsets of subsequent hunks when one is skipped Phillip Wood 2018-02-27 11:04 ` [PATCH v3 7/9] add -p: calculate offset delta for edited patches Phillip Wood 2018-02-27 11:04 ` [PATCH v3 8/9] add -p: fix counting when splitting and coalescing Phillip Wood 2018-02-27 11:04 ` [PATCH v3 9/9] add -p: don't rely on apply's '--recount' option Phillip Wood 2018-03-01 10:50 ` [PATCH v4 0/9] Correct offsets of hunks when one is skipped Phillip Wood 2018-03-01 10:50 ` [PATCH v4 1/9] add -i: add function to format hunk header Phillip Wood 2018-03-01 10:50 ` [PATCH v4 2/9] t3701: indent here documents Phillip Wood 2018-03-01 10:50 ` [PATCH v4 3/9] t3701: use test_write_lines and write_script Phillip Wood 2018-03-01 10:50 ` [PATCH v4 4/9] t3701: don't hard code sha1 hash values Phillip Wood 2018-03-02 15:55 ` SZEDER Gábor 2018-03-02 16:09 ` Junio C Hamano 2018-03-05 10:59 ` Phillip Wood 2018-03-05 12:32 ` SZEDER Gábor 2018-03-01 10:50 ` [PATCH v4 5/9] t3701: add failing test for pathological context lines Phillip Wood 2018-03-01 10:51 ` [PATCH v4 6/9] add -p: adjust offsets of subsequent hunks when one is skipped Phillip Wood 2018-03-01 10:51 ` Phillip Wood [this message] 2018-03-01 20:14 ` [PATCH v4 7/9] add -p: calculate offset delta for edited patches Junio C Hamano 2018-03-02 10:36 ` Phillip Wood 2018-03-01 10:51 ` [PATCH v4 8/9] add -p: fix counting when splitting and coalescing Phillip Wood 2018-03-01 20:29 ` Junio C Hamano 2018-03-02 10:48 ` Phillip Wood 2018-03-01 10:51 ` [PATCH v4 9/9] add -p: don't rely on apply's '--recount' option Phillip Wood 2018-03-01 20:30 ` Junio C Hamano 2018-03-02 10:49 ` Phillip Wood 2018-03-05 10:56 ` [PATCH v5 0/9] Correct offsets of hunks when one is skipped Phillip Wood 2018-03-05 10:56 ` [PATCH v5 1/9] add -i: add function to format hunk header Phillip Wood 2018-03-05 10:56 ` [PATCH v5 2/9] t3701: indent here documents Phillip Wood 2018-03-05 10:56 ` [PATCH v5 3/9] t3701: use test_write_lines and write_script Phillip Wood 2018-03-05 10:56 ` [PATCH v5 4/9] t3701: don't hard code sha1 hash values Phillip Wood 2018-03-05 10:56 ` [PATCH v5 5/9] t3701: add failing test for pathological context lines Phillip Wood 2018-03-05 10:56 ` [PATCH v5 6/9] add -p: adjust offsets of subsequent hunks when one is skipped Phillip Wood 2018-03-05 10:56 ` [PATCH v5 7/9] add -p: calculate offset delta for edited patches Phillip Wood 2018-03-05 10:56 ` [PATCH v5 8/9] add -p: fix counting when splitting and coalescing Phillip Wood 2018-03-05 10:56 ` [PATCH v5 9/9] add -p: don't rely on apply's '--recount' option Phillip Wood 2018-03-05 18:50 ` [PATCH v5 0/9] Correct offsets of hunks when one is skipped Junio C Hamano 2018-03-06 10:25 ` Phillip Wood
Reply instructions: You may reply publically to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style List information: http://vger.kernel.org/majordomo-info.html * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180301105103.24268-8-phillip.wood@talktalk.net \ --to=phillip.wood@talktalk.net \ --cc=git@vger.kernel.org \ --cc=gitster@pobox.com \ --cc=phillip.wood@dunelm.org.uk \ --cc=sandals@crustytoothpaste.net \ --cc=sunshine@sunshineco.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
git@vger.kernel.org list mirror (unofficial, one of many) Archives are clonable: git clone --mirror https://public-inbox.org/git git clone --mirror http://ou63pmih66umazou.onion/git git clone --mirror http://czquwvybam4bgbro.onion/git git clone --mirror http://hjrcffqmbrq6wope.onion/git Example config snippet for mirrors Newsgroups are available over NNTP: nntp://news.public-inbox.org/inbox.comp.version-control.git nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git nntp://news.gmane.org/gmane.comp.version-control.git note: .onion URLs require Tor: https://www.torproject.org/ AGPL code for this site: git clone https://public-inbox.org/public-inbox.git