Merge branch 'pw/add-p-hunk-split-fix'

"git add -p" rewritten in C regressed hunk splitting in some cases,
which has been corrected.

* pw/add-p-hunk-split-fix:
  builtin add -p: fix hunk splitting
  t3701: clean up hunk splitting tests
This commit is contained in:
Junio C Hamano 2022-02-09 14:20:59 -08:00
commit ec4f70e647
2 changed files with 56 additions and 12 deletions

View File

@ -383,6 +383,17 @@ static int is_octal(const char *p, size_t len)
return 1;
}
static void complete_file(char marker, struct hunk *hunk)
{
if (marker == '-' || marker == '+')
/*
* Last hunk ended in non-context line (i.e. it
* appended lines to the file, so there are no
* trailing context lines).
*/
hunk->splittable_into++;
}
static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
{
struct strvec args = STRVEC_INIT;
@ -472,6 +483,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
eol = pend;
if (starts_with(p, "diff ")) {
complete_file(marker, hunk);
ALLOC_GROW_BY(s->file_diff, s->file_diff_nr, 1,
file_diff_alloc);
file_diff = s->file_diff + s->file_diff_nr - 1;
@ -598,13 +610,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
file_diff->hunk->colored_end = hunk->colored_end;
}
}
if (marker == '-' || marker == '+')
/*
* Last hunk ended in non-context line (i.e. it appended lines
* to the file, so there are no trailing context lines).
*/
hunk->splittable_into++;
complete_file(marker, hunk);
/* non-colored shorter than colored? */
if (colored_p != colored_pend) {

View File

@ -326,7 +326,9 @@ test_expect_success 'correct message when there is nothing to do' '
test_expect_success 'setup again' '
git reset --hard &&
test_chmod +x file &&
echo content >>file
echo content >>file &&
test_write_lines A B C D>file2 &&
git add file2
'
# Write the patch file with a new line at the top and bottom
@ -341,13 +343,27 @@ test_expect_success 'setup patch' '
content
+lastline
\ No newline at end of file
diff --git a/file2 b/file2
index 8422d40..35b930a 100644
--- a/file2
+++ b/file2
@@ -1,4 +1,5 @@
-A
+Z
B
+Y
C
-D
+X
EOF
'
# Expected output, diff is similar to the patch but w/ diff at the top
test_expect_success 'setup expected' '
echo diff --git a/file b/file >expected &&
cat patch |sed "/^index/s/ 100644/ 100755/" >>expected &&
sed -e "/^index 180b47c/s/ 100644/ 100755/" \
-e /1,5/s//1,4/ \
-e /Y/d patch >>expected &&
cat >expected-output <<-\EOF
--- a/file
+++ b/file
@ -366,6 +382,28 @@ test_expect_success 'setup expected' '
content
+lastline
\ No newline at end of file
--- a/file2
+++ b/file2
@@ -1,4 +1,5 @@
-A
+Z
B
+Y
C
-D
+X
@@ -1,2 +1,2 @@
-A
+Z
B
@@ -2,2 +2,3 @@
B
+Y
C
@@ -3,2 +4,2 @@
C
-D
+X
EOF
'
@ -373,9 +411,9 @@ test_expect_success 'setup expected' '
test_expect_success 'add first line works' '
git commit -am "clear local changes" &&
git apply patch &&
printf "%s\n" s y y | git add -p file 2>error |
sed -n -e "s/^([1-2]\/[1-2]) Stage this hunk[^@]*\(@@ .*\)/\1/" \
-e "/^[-+@ \\\\]"/p >output &&
test_write_lines s y y s y n y | git add -p 2>error >raw-output &&
sed -n -e "s/^([1-9]\/[1-9]) Stage this hunk[^@]*\(@@ .*\)/\1/" \
-e "/^[-+@ \\\\]"/p raw-output >output &&
test_must_be_empty error &&
git diff --cached >diff &&
diff_cmp expected diff &&