Skip to content

Commit 72a50fa

Browse files
committed
Merge branch 'pw/add-patch-with-suppress-blank-empty' into maint-2.46
"git add -p" by users with diff.suppressBlankEmpty set to true failed to parse the patch that represents an unmodified empty line with an empty line (not a line with a single space on it), which has been corrected. * pw/add-patch-with-suppress-blank-empty: add-patch: use normalize_marker() when recounting edited hunk add-patch: handle splitting hunks with diff.suppressBlankEmpty
2 parents fca5ece + 60cf761 commit 72a50fa

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

add-patch.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,12 @@ static void complete_file(char marker, struct hunk *hunk)
402402
hunk->splittable_into++;
403403
}
404404

405+
/* Empty context lines may omit the leading ' ' */
406+
static int normalize_marker(const char *p)
407+
{
408+
return p[0] == '\n' || (p[0] == '\r' && p[1] == '\n') ? ' ' : p[0];
409+
}
410+
405411
static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
406412
{
407413
struct strvec args = STRVEC_INIT;
@@ -487,6 +493,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
487493
while (p != pend) {
488494
char *eol = memchr(p, '\n', pend - p);
489495
const char *deleted = NULL, *mode_change = NULL;
496+
char ch = normalize_marker(p);
490497

491498
if (!eol)
492499
eol = pend;
@@ -534,7 +541,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
534541
* Start counting into how many hunks this one can be
535542
* split
536543
*/
537-
marker = *p;
544+
marker = ch;
538545
} else if (hunk == &file_diff->head &&
539546
starts_with(p, "new file")) {
540547
file_diff->added = 1;
@@ -588,10 +595,10 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
588595
(int)(eol - (plain->buf + file_diff->head.start)),
589596
plain->buf + file_diff->head.start);
590597

591-
if ((marker == '-' || marker == '+') && *p == ' ')
598+
if ((marker == '-' || marker == '+') && ch == ' ')
592599
hunk->splittable_into++;
593-
if (marker && *p != '\\')
594-
marker = *p;
600+
if (marker && ch != '\\')
601+
marker = ch;
595602

596603
p = eol == pend ? pend : eol + 1;
597604
hunk->end = p - plain->buf;
@@ -815,7 +822,7 @@ static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
815822
(int)(hunk->end - hunk->start),
816823
plain + hunk->start);
817824

818-
if (plain[overlap_end] != ' ')
825+
if (normalize_marker(&plain[overlap_end]) != ' ')
819826
return error(_("expected context line "
820827
"#%d in\n%.*s"),
821828
(int)(j + 1),
@@ -955,7 +962,7 @@ static int split_hunk(struct add_p_state *s, struct file_diff *file_diff,
955962
context_line_count = 0;
956963

957964
while (splittable_into > 1) {
958-
ch = s->plain.buf[current];
965+
ch = normalize_marker(&s->plain.buf[current]);
959966

960967
if (!ch)
961968
BUG("buffer overrun while splitting hunks");
@@ -1173,14 +1180,14 @@ static ssize_t recount_edited_hunk(struct add_p_state *s, struct hunk *hunk,
11731180

11741181
header->old_count = header->new_count = 0;
11751182
for (i = hunk->start; i < hunk->end; ) {
1176-
switch (s->plain.buf[i]) {
1183+
switch(normalize_marker(&s->plain.buf[i])) {
11771184
case '-':
11781185
header->old_count++;
11791186
break;
11801187
case '+':
11811188
header->new_count++;
11821189
break;
1183-
case ' ': case '\r': case '\n':
1190+
case ' ':
11841191
header->old_count++;
11851192
header->new_count++;
11861193
break;

t/t3701-add-interactive.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,4 +1164,23 @@ test_expect_success 'reset -p with unmerged files' '
11641164
test_must_be_empty staged
11651165
'
11661166

1167+
test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' '
1168+
test_config diff.suppressBlankEmpty true &&
1169+
write_script fake-editor.sh <<-\EOF &&
1170+
tr F G <"$1" >"$1.tmp" &&
1171+
mv "$1.tmp" "$1"
1172+
EOF
1173+
1174+
test_write_lines a b "" c d "" e f "" >file &&
1175+
git add file &&
1176+
test_write_lines A b "" c D "" e F "" >file &&
1177+
(
1178+
test_set_editor "$(pwd)/fake-editor.sh" &&
1179+
test_write_lines s n y e q | git add -p file
1180+
) &&
1181+
git cat-file blob :file >actual &&
1182+
test_write_lines a b "" c D "" e G "" >expect &&
1183+
test_cmp expect actual
1184+
'
1185+
11671186
test_done

0 commit comments

Comments
 (0)