From 492e60c82456b228a24ff0021e6accee946b7a1c Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 19 Feb 2018 11:29:02 +0000 Subject: [PATCH 1/9] add -i: add function to format hunk header This code is duplicated in a couple of places so make it into a function as we're going to add some more callers shortly. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- git-add--interactive.perl | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 28b325d754..64f869c3b7 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -751,6 +751,15 @@ sub parse_hunk_header { return ($o_ofs, $o_cnt, $n_ofs, $n_cnt); } +sub format_hunk_header { + my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = @_; + return ("@@ -$o_ofs" . + (($o_cnt != 1) ? ",$o_cnt" : '') . + " +$n_ofs" . + (($n_cnt != 1) ? ",$n_cnt" : '') . + " @@\n"); +} + sub split_hunk { my ($text, $display) = @_; my @split = (); @@ -838,11 +847,7 @@ sub split_hunk { my $o_cnt = $hunk->{OCNT}; my $n_cnt = $hunk->{NCNT}; - my $head = ("@@ -$o_ofs" . - (($o_cnt != 1) ? ",$o_cnt" : '') . - " +$n_ofs" . - (($n_cnt != 1) ? ",$n_cnt" : '') . - " @@\n"); + my $head = format_hunk_header($o_ofs, $o_cnt, $n_ofs, $n_cnt); my $display_head = $head; unshift @{$hunk->{TEXT}}, $head; if ($diff_use_color) { @@ -912,11 +917,7 @@ sub merge_hunk { } push @line, $line; } - my $head = ("@@ -$o0_ofs" . - (($o_cnt != 1) ? ",$o_cnt" : '') . - " +$n0_ofs" . - (($n_cnt != 1) ? ",$n_cnt" : '') . - " @@\n"); + my $head = format_hunk_header($o0_ofs, $o_cnt, $n0_ofs, $n_cnt); @{$prev->{TEXT}} = ($head, @line); } From e4d671c6a686ba48f9f987fdabad0eeb49759199 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 19 Feb 2018 11:29:03 +0000 Subject: [PATCH 2/9] t3701: indent here documents Indent here documents in line with the current style for tests. While at it, quote the end marker of here-docs that do not use variable interpolation. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/t3701-add-interactive.sh | 174 ++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index a49c12c79b..39c7423069 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -22,14 +22,14 @@ test_expect_success 'status works (initial)' ' ' test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + new file mode 100644 + index 0000000..d95f3ad + --- /dev/null + +++ b/file + @@ -0,0 +1 @@ + +content + EOF ' test_expect_success 'diff works (initial)' ' @@ -59,14 +59,14 @@ test_expect_success 'status works (commit)' ' ' test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + index 180b47c..b6f2c08 100644 + --- a/file + +++ b/file + @@ -1 +1,2 @@ + baseline + +content + EOF ' test_expect_success 'diff works (commit)' ' @@ -83,8 +83,8 @@ test_expect_success 'revert works (commit)' ' test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + EOF ' test_expect_success 'setup fake editor' ' @@ -100,21 +100,21 @@ test_expect_success 'dummy edit works' ' ' test_expect_success 'setup patch' ' -cat >patch <patch <<-\EOF + @@ -1,1 +1,4 @@ + this + +patch + -does not + apply + EOF ' test_expect_success 'setup fake editor' ' echo "#!$SHELL_PATH" >fake_editor.sh && - cat >>fake_editor.sh <<\EOF && -mv -f "$1" oldpatch && -mv -f patch "$1" -EOF + cat >>fake_editor.sh <<-\EOF && + mv -f "$1" oldpatch && + mv -f patch "$1" + EOF chmod a+x fake_editor.sh && test_set_editor "$(pwd)/fake_editor.sh" ' @@ -126,10 +126,10 @@ test_expect_success 'bad edit rejected' ' ' test_expect_success 'setup patch' ' -cat >patch <patch <<-\EOF + this patch + is garbage + EOF ' test_expect_success 'garbage edit rejected' ' @@ -139,28 +139,28 @@ test_expect_success 'garbage edit rejected' ' ' test_expect_success 'setup patch' ' -cat >patch <patch <<-\EOF + @@ -1,0 +1,0 @@ + baseline + +content + +newcontent + +lines + EOF ' test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + diff --git a/file b/file + index b5dd6c9..f910ae9 100644 + --- a/file + +++ b/file + @@ -1,4 +1,4 @@ + baseline + content + -newcontent + +more + lines + EOF ' test_expect_success 'real edit works' ' @@ -222,31 +222,31 @@ test_expect_success 'setup again' ' # Write the patch file with a new line at the top and bottom test_expect_success 'setup patch' ' -cat >patch <patch <<-\EOF + index 180b47c..b6f2c08 100644 + --- a/file + +++ b/file + @@ -1,2 +1,4 @@ + +firstline + baseline + content + +lastline + EOF ' # Expected output, similar to the patch but w/ diff at the top test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + diff --git a/file b/file + index b6f2c08..61b9053 100755 + --- a/file + +++ b/file + @@ -1,2 +1,4 @@ + +firstline + baseline + content + +lastline + EOF ' # Test splitting the first patch, then adding both @@ -259,15 +259,15 @@ test_expect_success 'add first line works' ' ' test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + diff --git a/non-empty b/non-empty + deleted file mode 100644 + index d95f3ad..0000000 + --- a/non-empty + +++ /dev/null + @@ -1 +0,0 @@ + -content + EOF ' test_expect_success 'deleting a non-empty file' ' @@ -282,11 +282,11 @@ test_expect_success 'deleting a non-empty file' ' ' test_expect_success 'setup expected' ' -cat >expected <expected <<-\EOF + diff --git a/empty b/empty + deleted file mode 100644 + index e69de29..0000000 + EOF ' test_expect_success 'deleting an empty file' ' From 11489a6539b8840ae18b9a5c7e6dd602e8f28209 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 19 Feb 2018 11:29:04 +0000 Subject: [PATCH 3/9] t3701: use test_write_lines and write_script Simplify things slightly by using the above helpers. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/t3701-add-interactive.sh | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 39c7423069..4a369fcb51 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -87,13 +87,8 @@ test_expect_success 'setup expected' ' EOF ' -test_expect_success 'setup fake editor' ' - >fake_editor.sh && - chmod a+x fake_editor.sh && - test_set_editor "$(pwd)/fake_editor.sh" -' - test_expect_success 'dummy edit works' ' + test_set_editor : && (echo e; echo a) | git add -p && git diff > diff && test_cmp expected diff @@ -110,12 +105,10 @@ test_expect_success 'setup patch' ' ' test_expect_success 'setup fake editor' ' - echo "#!$SHELL_PATH" >fake_editor.sh && - cat >>fake_editor.sh <<-\EOF && + write_script "fake_editor.sh" <<-\EOF && mv -f "$1" oldpatch && mv -f patch "$1" EOF - chmod a+x fake_editor.sh && test_set_editor "$(pwd)/fake_editor.sh" ' @@ -302,18 +295,12 @@ test_expect_success 'deleting an empty file' ' test_expect_success 'split hunk setup' ' git reset --hard && - for i in 10 20 30 40 50 60 - do - echo $i - done >test && + test_write_lines 10 20 30 40 50 60 >test && git add test && test_tick && git commit -m test && - for i in 10 15 20 21 22 23 24 30 40 50 60 - do - echo $i - done >test + test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test ' test_expect_success 'split hunk "add -p (edit)"' ' @@ -334,17 +321,7 @@ test_expect_success 'split hunk "add -p (edit)"' ' ' test_expect_failure 'split hunk "add -p (no, yes, edit)"' ' - cat >test <<-\EOF && - 5 - 10 - 20 - 21 - 30 - 31 - 40 - 50 - 60 - EOF + test_write_lines 5 10 20 21 30 31 40 50 60 >test && git reset && # test sequence is s(plit), n(o), y(es), e(dit) # q n q q is there to make sure we exit at the end. From 902f414a72b29ca9c6c575faf29cc2b0b8b4fe1c Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 1 Mar 2018 10:50:58 +0000 Subject: [PATCH 4/9] t3701: don't hard code sha1 hash values Use a filter when comparing diffs to fix the value of non-zero hashes in diff index lines so we're not hard coding sha1 hash values in the expected output. This makes it easier to change the expected output if a test is edited as we don't need to worry about the exact hash value and means the tests will work when the hash algorithm is transitioned away from sha1. Thanks-to: Junio C Hamano Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/t3701-add-interactive.sh | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 4a369fcb51..f818c532da 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -10,6 +10,19 @@ then test_done fi +diff_cmp () { + for x + do + sed -e '/^index/s/[0-9a-f]*[1-9a-f][0-9a-f]*\.\./1234567../' \ + -e '/^index/s/\.\.[0-9a-f]*[1-9a-f][0-9a-f]*/..9abcdef/' \ + -e '/^index/s/ 00*\.\./ 0000000../' \ + -e '/^index/s/\.\.00*$/..0000000/' \ + -e '/^index/s/\.\.00* /..0000000 /' \ + "$x" >"$x.filtered" + done + test_cmp "$1.filtered" "$2.filtered" +} + test_expect_success 'setup (initial)' ' echo content >file && git add file && @@ -35,7 +48,7 @@ test_expect_success 'setup expected' ' test_expect_success 'diff works (initial)' ' (echo d; echo 1) | git add -i >output && sed -ne "/new file/,/content/p" diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success 'revert works (initial)' ' git add file && @@ -72,7 +85,7 @@ test_expect_success 'setup expected' ' test_expect_success 'diff works (commit)' ' (echo d; echo 1) | git add -i >output && sed -ne "/^index/,/content/p" diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success 'revert works (commit)' ' git add file && @@ -91,7 +104,7 @@ test_expect_success 'dummy edit works' ' test_set_editor : && (echo e; echo a) | git add -p && git diff > diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success 'setup patch' ' @@ -159,7 +172,7 @@ test_expect_success 'setup expected' ' test_expect_success 'real edit works' ' (echo e; echo n; echo d) | git add -p && git diff >output && - test_cmp expected output + diff_cmp expected output ' test_expect_success 'skip files similarly as commit -a' ' @@ -171,7 +184,7 @@ test_expect_success 'skip files similarly as commit -a' ' git reset && git commit -am commit && git diff >expected && - test_cmp expected output && + diff_cmp expected output && git reset --hard HEAD^ ' rm -f .gitignore @@ -248,7 +261,7 @@ test_expect_success 'add first line works' ' git apply patch && (echo s; echo y; echo y) | git add -p file && git diff --cached > diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success 'setup expected' ' @@ -271,7 +284,7 @@ test_expect_success 'deleting a non-empty file' ' rm non-empty && echo y | git add -p non-empty && git diff --cached >diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success 'setup expected' ' @@ -290,7 +303,7 @@ test_expect_success 'deleting an empty file' ' rm empty && echo y | git add -p empty && git diff --cached >diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success 'split hunk setup' ' @@ -355,7 +368,7 @@ test_expect_success 'patch mode ignores unmerged entries' ' +changed EOF git diff --cached >diff && - test_cmp expected diff + diff_cmp expected diff ' test_expect_success TTY 'diffs can be colorized' ' @@ -384,7 +397,7 @@ test_expect_success 'patch-mode via -i prompts for files' ' echo test >expect && git diff --cached --name-only >actual && - test_cmp expect actual + diff_cmp expect actual ' test_expect_success 'add -p handles globs' ' From 23fea4c240218d519da01e6d2d64264084a7334c Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 1 Mar 2018 10:50:59 +0000 Subject: [PATCH 5/9] t3701: add failing test for pathological context lines When a hunk is skipped by add -i the offsets of subsequent hunks are not adjusted to account for any missing insertions due to the skipped hunk. Most of the time this does not matter as apply uses the context lines to apply the subsequent hunks in the correct place, however in pathological cases the context lines will match at the now incorrect offset and the hunk will be applied in the wrong place. The offsets of hunks following an edited hunk that has had the number of insertions or deletions changed also need to be updated in the same way. Add failing tests to demonstrate this. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/t3701-add-interactive.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index f818c532da..fe7c1bef61 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -483,4 +483,34 @@ test_expect_success 'add -p works even with color.ui=always' ' test_cmp expect actual ' +test_expect_success 'set up pathological context' ' + git reset --hard && + test_write_lines a a a a a a a a a a a >a && + git add a && + git commit -m a && + test_write_lines c b a a a a a a a b a a a a >a && + test_write_lines a a a a a a a b a a a a >expected-1 && + test_write_lines b a a a a a a a b a a a a >expected-2 && + # check editing can cope with missing header and deleted context lines + # as well as changes to other lines + test_write_lines +b " a" >patch +' + +test_expect_failure 'add -p works with pathological context lines' ' + git reset && + printf "%s\n" n y | + git add -p && + git cat-file blob :a >actual && + test_cmp expected-1 actual +' + +test_expect_failure '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 | + git add -p && + git cat-file blob :a >actual && + test_cmp expected-2 actual +' + test_done From fecc6f3a6862c55dee0e9a2390acaf4b23991fef Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 1 Mar 2018 10:51:00 +0000 Subject: [PATCH 6/9] 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 Signed-off-by: Junio C Hamano --- git-add--interactive.perl | 15 +++++++++++++-- t/t3701-add-interactive.sh | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 64f869c3b7..6f6a21dc11 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -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} && diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index fe7c1bef61..6f18a92486 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -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 && From 2b8ea7f3c7d8dfd4f1eddaef6688b51f8106767e Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 5 Mar 2018 10:56:28 +0000 Subject: [PATCH 7/9] add -p: calculate offset delta for edited patches 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 Signed-off-by: Junio C Hamano --- git-add--interactive.perl | 59 ++++++++++++++++++++++++++++++++------ t/t3701-add-interactive.sh | 2 +- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 6f6a21dc11..b5f01160c5 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -938,6 +938,11 @@ 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. + if ($_->{OFS_DELTA}) { + $ofs_delta -= $_->{OFS_DELTA}; + } next; } if ($ofs_delta) { @@ -945,6 +950,11 @@ sub coalesce_overlapping_hunks { $_->{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. + if ($_->{OFS_DELTA}) { + $ofs_delta += $_->{OFS_DELTA}; + } if (defined $last_o_ctx && $o_ofs <= $last_o_ctx && !$_->{DIRTY} && @@ -1016,6 +1026,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 +1148,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 6f18a92486..24ed3f4a22 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -504,7 +504,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 | From b3e0fcfe429204ccdf1f6977c55127171d65a8e5 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 5 Mar 2018 10:56:29 +0000 Subject: [PATCH 8/9] add -p: fix counting when splitting and coalescing When a file has no trailing new line at the end diff records this by appending "\ No newline at end of file" below the last line of the file. This line should not be counted in the hunk header. Fix the splitting and coalescing code to count files without a trailing new line properly and change one of the tests to test splitting without a trailing new line. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- git-add--interactive.perl | 11 +++++++++++ t/t3701-add-interactive.sh | 31 +++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index b5f01160c5..4a1e71d2e4 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -793,6 +793,11 @@ sub split_hunk { while (++$i < @$text) { my $line = $text->[$i]; my $display = $display->[$i]; + if ($line =~ /^\\/) { + push @{$this->{TEXT}}, $line; + push @{$this->{DISPLAY}}, $display; + next; + } if ($line =~ /^ /) { if ($this->{ADDDEL} && !defined $next_hunk_start) { @@ -891,6 +896,9 @@ sub merge_hunk { $n_cnt++; push @line, $line; next; + } elsif ($line =~ /^\\/) { + push @line, $line; + next; } last if ($o1_ofs <= $ofs); @@ -909,6 +917,9 @@ sub merge_hunk { $n_cnt++; push @line, $line; next; + } elsif ($line =~ /^\\/) { + push @line, $line; + next; } $ofs++; $o_cnt++; diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 24ed3f4a22..e5c66f7500 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -237,14 +237,15 @@ test_expect_success 'setup patch' ' baseline content +lastline + \ No newline at end of file EOF ' -# Expected output, similar to the patch but w/ diff at the top +# Expected output, diff is similar to the patch but w/ diff at the top test_expect_success 'setup expected' ' - cat >expected <<-\EOF - diff --git a/file b/file - index b6f2c08..61b9053 100755 + echo diff --git a/file b/file >expected && + cat patch |sed "/^index/s/ 100644/ 100755/" >>expected && + cat >expected-output <<-\EOF --- a/file +++ b/file @@ -1,2 +1,4 @@ @@ -252,16 +253,30 @@ test_expect_success 'setup expected' ' baseline content +lastline + \ No newline at end of file + @@ -1,2 +1,3 @@ + +firstline + baseline + content + @@ -1,2 +2,3 @@ + baseline + content + +lastline + \ No newline at end of file EOF ' # Test splitting the first patch, then adding both -test_expect_success 'add first line works' ' +test_expect_success C_LOCALE_OUTPUT 'add first line works' ' git commit -am "clear local changes" && git apply patch && - (echo s; echo y; echo y) | git add -p file && - git diff --cached > diff && - diff_cmp expected diff + printf "%s\n" s y y | git add -p file 2>error | + sed -n -e "s/^Stage this hunk[^@]*\(@@ .*\)/\1/" \ + -e "/^[-+@ \\\\]"/p >output && + test_must_be_empty error && + git diff --cached >diff && + diff_cmp expected diff && + test_cmp expected-output output ' test_expect_success 'setup expected' ' From 3a8522f41ff45b16e06888d2b164252c9aeeaa03 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Mon, 5 Mar 2018 10:56:30 +0000 Subject: [PATCH 9/9] add -p: don't rely on apply's '--recount' option Now that add -p counts patches properly it should be possible to turn off the '--recount' option when invoking 'git apply' Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- git-add--interactive.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 4a1e71d2e4..ab022ec073 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -677,7 +677,7 @@ sub add_untracked_cmd { sub run_git_apply { my $cmd = shift; my $fh; - open $fh, '| git ' . $cmd . " --recount --allow-overlap"; + open $fh, '| git ' . $cmd . " --allow-overlap"; print $fh @_; return close $fh; }