emit_line(o, "", "", line, len);
break;
case DIFF_SYMBOL_CONTEXT_INCOMPLETE:
- set = diff_get_color_opt(o, DIFF_CONTEXT);
+ if ((flags & WS_INCOMPLETE_LINE) &&
+ (flags & o->ws_error_highlight))
+ set = diff_get_color_opt(o, DIFF_WHITESPACE);
+ else
+ set = diff_get_color_opt(o, DIFF_CONTEXT);
reset = diff_get_color_opt(o, DIFF_RESET);
emit_line(o, set, reset, line, len);
break;
static void emit_incomplete_line(struct emit_callback *ecbdata,
const char *line, int len)
{
+ int last_line_kind = ecbdata->last_line_kind;
+ unsigned flags = (last_line_kind == '+'
+ ? WSEH_NEW
+ : last_line_kind == '-'
+ ? WSEH_OLD
+ : WSEH_CONTEXT) | ecbdata->ws_rule;
emit_diff_symbol(ecbdata->opt, DIFF_SYMBOL_CONTEXT_INCOMPLETE,
- line, len, 0);
+ line, len, flags);
}
static void emit_hunk_header(struct emit_callback *ecbdata,
struct diff_options *o;
unsigned ws_rule;
unsigned status;
+ int last_line_kind;
};
static int is_conflict_marker(const char *line, int marker_size, unsigned long len)
static int checkdiff_consume(void *priv, char *line, unsigned long len)
{
struct checkdiff_t *data = priv;
+ int last_line_kind;
int marker_size = data->conflict_marker_size;
const char *ws = diff_get_color(data->o->use_color, DIFF_WHITESPACE);
const char *reset = diff_get_color(data->o->use_color, DIFF_RESET);
assert(data->o);
line_prefix = diff_line_prefix(data->o);
+ last_line_kind = data->last_line_kind;
+ data->last_line_kind = line[0];
if (line[0] == '+') {
unsigned bad;
data->lineno++;
data->o->file, set, reset, ws);
} else if (line[0] == ' ') {
data->lineno++;
+ } else if (line[0] == '\\') {
+ /* no newline at the end of the line */
+ if ((data->ws_rule & WS_INCOMPLETE_LINE) &&
+ (last_line_kind == '+')) {
+ unsigned bad = WS_INCOMPLETE_LINE;
+ data->status |= bad;
+ err = whitespace_error_string(bad);
+ fprintf(data->o->file, "%s%s:%d: %s.\n",
+ line_prefix, data->filename, data->lineno, err);
+ free(err);
+ }
}
return 0;
}
'
done
+test_expect_success "incomplete line in both pre- and post-image context" '
+ (echo foo && echo baz | tr -d "\012") >x &&
+ git add x &&
+ (echo bar && echo baz | tr -d "\012") >x &&
+ git diff x &&
+ git -c core.whitespace=incomplete diff --check x &&
+ git diff -R x &&
+ git -c core.whitespace=incomplete diff -R --check x
+'
+
+test_expect_success "incomplete lines on both pre- and post-image" '
+ # The interpretation taken here is "since you are toucing
+ # the line anyway, you would better fix the incomplete line
+ # while you are at it." but this is debatable.
+ echo foo | tr -d "\012" >x &&
+ git add x &&
+ echo bar | tr -d "\012" >x &&
+ git diff x &&
+ test_must_fail git -c core.whitespace=incomplete diff --check x &&
+ git diff -R x &&
+ test_must_fail git -c core.whitespace=incomplete diff -R --check x
+'
+
+test_expect_success "fix incomplete line in pre-image" '
+ echo foo | tr -d "\012" >x &&
+ git add x &&
+ echo bar >x &&
+ git diff x &&
+ git -c core.whitespace=incomplete diff --check x &&
+ git diff -R x &&
+ test_must_fail git -c core.whitespace=incomplete diff -R --check x
+'
+
+test_expect_success "new incomplete line in post-image" '
+ echo foo >x &&
+ git add x &&
+ echo bar | tr -d "\012" >x &&
+ git diff x &&
+ test_must_fail git -c core.whitespace=incomplete diff --check x &&
+ git diff -R x &&
+ git -c core.whitespace=incomplete diff -R --check x
+'
+
test_expect_success "Ray Lehtiniemi's example" '
cat <<-\EOF >x &&
do {
{
echo "0. blank-at-eol " &&
echo "1. still-blank-at-eol " &&
- echo "2. and a new line "
+ echo "2. and a new line " &&
+ printf "3. and more"
} >x &&
new_hash_x=$(git hash-object x) &&
after=$(git rev-parse --short "$new_hash_x") &&
<BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
- <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <CYAN>@@ -1,2 +1,4 @@<RESET>
0. blank-at-eol <RESET>
<RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
<GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
<GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
+ <GREEN>+<RESET><GREEN>3. and more<RESET>
+ <BLUE>\ No newline at end of file<RESET>
EOF
cat >expect.all <<-EOF &&
<BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
- <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <CYAN>@@ -1,2 +1,4 @@<RESET>
<RESET>0. blank-at-eol<RESET><BLUE> <RESET>
<RED>-<RESET><RED>1. blank-at-eol<RESET><BLUE> <RESET>
<GREEN>+<RESET><GREEN>1. still-blank-at-eol<RESET><BLUE> <RESET>
<GREEN>+<RESET><GREEN>2. and a new line<RESET><BLUE> <RESET>
+ <GREEN>+<RESET><GREEN>3. and more<RESET>
+ <BLUE>\ No newline at end of file<RESET>
EOF
cat >expect.none <<-EOF
<BOLD>index $before..$after 100644<RESET>
<BOLD>--- a/x<RESET>
<BOLD>+++ b/x<RESET>
- <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <CYAN>@@ -1,2 +1,4 @@<RESET>
0. blank-at-eol <RESET>
<RED>-1. blank-at-eol <RESET>
<GREEN>+1. still-blank-at-eol <RESET>
<GREEN>+2. and a new line <RESET>
+ <GREEN>+3. and more<RESET>
+ \ No newline at end of file<RESET>
EOF
'
test_expect_success 'test --ws-error-highlight option' '
+ git config core.whitespace blank-at-eol,incomplete-line &&
git diff --color --ws-error-highlight=default,old >current.raw &&
test_decode_color <current.raw >current &&
'
test_expect_success 'test diff.wsErrorHighlight config' '
+ git config core.whitespace blank-at-eol,incomplete-line &&
git -c diff.wsErrorHighlight=default,old diff --color >current.raw &&
test_decode_color <current.raw >current &&
'
test_expect_success 'option overrides diff.wsErrorHighlight' '
+ git config core.whitespace blank-at-eol,incomplete-line &&
git -c diff.wsErrorHighlight=none \
diff --color --ws-error-highlight=default,old >current.raw &&
'
test_expect_success 'detect moved code, complete file' '
+ git config core.whitespace blank-at-eol &&
+
git reset --hard &&
cat <<-\EOF >test.c &&
#include<stdio.h>