Skip to content

Commit fc7abcd

Browse files
committed
diff: correct suppress_blank_empty hack
The suppress-blank-empty feature abused the CONTEXT_INCOMPLETE symbol that was meant to be used only for "\ No newline at the end of file" code path. The intent of the feature was to turn a context line we receive from xdiff machinery (which always uses ' ' for context lines, even an empty one) and spit it out as a truly empty line. Perform such a conversion very locally at where a line from xdiff that begins with ' ' is handled for output; there are many checks before the control reaches such place that checks the first letter of the diff output line to see if it is a context line, and having to check for '\n' and treat it as a special case is error prone. In order to catch similar hacks in the future, make sure the code path that is meant for "\ No newline" case checks the first byte is indeed a backslash. Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent f83d1af commit fc7abcd

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

diff.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,11 @@ static void emit_line_ws_markup(struct diff_options *o,
13211321
const char *ws = NULL;
13221322
int sign = o->output_indicators[sign_index];
13231323

1324+
if (diff_suppress_blank_empty &&
1325+
sign_index == OUTPUT_INDICATOR_CONTEXT &&
1326+
len == 1 && line[0] == '\n')
1327+
sign = 0;
1328+
13241329
if (o->ws_error_highlight & ws_rule) {
13251330
ws = diff_get_color_opt(o, DIFF_WHITESPACE);
13261331
if (!*ws)
@@ -1498,15 +1503,9 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
14981503
case DIFF_SYMBOL_WORDS:
14991504
context = diff_get_color_opt(o, DIFF_CONTEXT);
15001505
reset = diff_get_color_opt(o, DIFF_RESET);
1501-
/*
1502-
* Skip the prefix character, if any. With
1503-
* diff_suppress_blank_empty, there may be
1504-
* none.
1505-
*/
1506-
if (line[0] != '\n') {
1507-
line++;
1508-
len--;
1509-
}
1506+
1507+
/* Skip the prefix character */
1508+
line++; len--;
15101509
emit_line(o, context, reset, line, len);
15111510
break;
15121511
case DIFF_SYMBOL_FILEPAIR_PLUS:
@@ -2375,12 +2374,6 @@ static int fn_out_consume(void *priv, char *line, unsigned long len)
23752374
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
23762375
}
23772376

2378-
if (diff_suppress_blank_empty
2379-
&& len == 2 && line[0] == ' ' && line[1] == '\n') {
2380-
line[0] = '\n';
2381-
len = 1;
2382-
}
2383-
23842377
if (line[0] == '@') {
23852378
if (ecbdata->diff_words)
23862379
diff_words_flush(ecbdata);
@@ -2431,12 +2424,14 @@ static int fn_out_consume(void *priv, char *line, unsigned long len)
24312424
ecbdata->lno_in_preimage++;
24322425
emit_context_line(ecbdata, line + 1, len - 1);
24332426
break;
2434-
default:
2427+
case '\\':
24352428
/* incomplete line at the end */
24362429
ecbdata->lno_in_preimage++;
24372430
emit_diff_symbol(o, DIFF_SYMBOL_CONTEXT_INCOMPLETE,
24382431
line, len, 0);
24392432
break;
2433+
default:
2434+
BUG("fn_out_consume: unknown line '%s'", line);
24402435
}
24412436
return 0;
24422437
}

0 commit comments

Comments
 (0)