Skip to content

Commit

Permalink
core.whitespace: cr-at-eol
Browse files Browse the repository at this point in the history
This new error mode allows a line to have a carriage return at the
end of the line when checking and fixing trailing whitespace errors.

Some people like to keep CRLF line ending recorded in the repository,
and still want to take advantage of the automated trailing whitespace
stripping.  We still show ^M in the diff output piped to "less" to
remind them that they do have the CR at the end, but these carriage
return characters at the end are no longer flagged as errors.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Junio C Hamano committed Feb 5, 2008
1 parent c1beba5 commit b2979ff
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ core.whitespace::
error (enabled by default).
* `indent-with-non-tab` treats a line that is indented with 8 or more
space characters as an error (not enabled by default).
* `cr-at-eol` treats a carriage-return at the end of line as
part of the line terminator, i.e. with it, `trailing-space`
does not trigger if the character before such a carriage-return
is not a whitespace (not enabled by default).

alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g.
Expand Down
18 changes: 14 additions & 4 deletions builtin-apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,7 @@ static int copy_wsfix(char *output, const char *patch, int plen,
*/
int i;
int add_nl_to_tail = 0;
int add_cr_to_tail = 0;
int fixed = 0;
int last_tab_in_indent = -1;
int last_space_in_indent = -1;
Expand All @@ -1536,12 +1537,19 @@ static int copy_wsfix(char *output, const char *patch, int plen,
*/
if ((ws_rule & WS_TRAILING_SPACE) &&
(2 < plen && isspace(patch[plen-2]))) {
if (patch[plen-1] == '\n')
if (patch[plen - 1] == '\n') {
add_nl_to_tail = 1;
plen--;
while (0 < plen && isspace(patch[plen-1]))
plen--;
fixed = 1;
if (1 < plen && patch[plen - 1] == '\r') {
add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL);
plen--;
}
}
if (0 < plen && isspace(patch[plen - 1])) {
while (0 < plen && isspace(patch[plen-1]))
plen--;
fixed = 1;
}
}

/*
Expand Down Expand Up @@ -1602,6 +1610,8 @@ static int copy_wsfix(char *output, const char *patch, int plen,
}

memcpy(output, patch, plen);
if (add_cr_to_tail)
output[plen++] = '\r';
if (add_nl_to_tail)
output[plen++] = '\n';
if (fixed && count_error)
Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, i
#define WS_TRAILING_SPACE 01
#define WS_SPACE_BEFORE_TAB 02
#define WS_INDENT_WITH_NON_TAB 04
#define WS_CR_AT_EOL 010
#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)
extern unsigned whitespace_rule_cfg;
extern unsigned whitespace_rule(const char *);
Expand Down
40 changes: 40 additions & 0 deletions t/t4019-diff-wserror.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ test_expect_success setup '
echo " Eight SP indent" >>F &&
echo " HT and SP indent" >>F &&
echo "With trailing SP " >>F &&
echo "Carriage ReturnQ" | tr Q "\015" >>F &&
echo "No problem" >>F
'
Expand All @@ -27,6 +28,7 @@ test_expect_success default '
grep Eight normal >/dev/null &&
grep HT error >/dev/null &&
grep With error >/dev/null &&
grep Return error >/dev/null &&
grep No normal >/dev/null
'
Expand All @@ -41,6 +43,7 @@ test_expect_success 'without -trail' '
grep Eight normal >/dev/null &&
grep HT error >/dev/null &&
grep With normal >/dev/null &&
grep Return normal >/dev/null &&
grep No normal >/dev/null
'
Expand All @@ -56,6 +59,7 @@ test_expect_success 'without -trail (attribute)' '
grep Eight normal >/dev/null &&
grep HT error >/dev/null &&
grep With normal >/dev/null &&
grep Return normal >/dev/null &&
grep No normal >/dev/null
'
Expand All @@ -71,6 +75,7 @@ test_expect_success 'without -space' '
grep Eight normal >/dev/null &&
grep HT normal >/dev/null &&
grep With error >/dev/null &&
grep Return error >/dev/null &&
grep No normal >/dev/null
'
Expand All @@ -86,6 +91,7 @@ test_expect_success 'without -space (attribute)' '
grep Eight normal >/dev/null &&
grep HT normal >/dev/null &&
grep With error >/dev/null &&
grep Return error >/dev/null &&
grep No normal >/dev/null
'
Expand All @@ -101,6 +107,7 @@ test_expect_success 'with indent-non-tab only' '
grep Eight error >/dev/null &&
grep HT normal >/dev/null &&
grep With normal >/dev/null &&
grep Return normal >/dev/null &&
grep No normal >/dev/null
'
Expand All @@ -116,6 +123,39 @@ test_expect_success 'with indent-non-tab only (attribute)' '
grep Eight error >/dev/null &&
grep HT normal >/dev/null &&
grep With normal >/dev/null &&
grep Return normal >/dev/null &&
grep No normal >/dev/null
'

test_expect_success 'with cr-at-eol' '
rm -f .gitattributes
git config core.whitespace cr-at-eol
git diff --color >output
grep "$blue_grep" output >error
grep -v "$blue_grep" output >normal
grep Eight normal >/dev/null &&
grep HT error >/dev/null &&
grep With error >/dev/null &&
grep Return normal >/dev/null &&
grep No normal >/dev/null
'

test_expect_success 'with cr-at-eol (attribute)' '
git config --unset core.whitespace
echo "F whitespace=trailing,cr-at-eol" >.gitattributes
git diff --color >output
grep "$blue_grep" output >error
grep -v "$blue_grep" output >normal
grep Eight normal >/dev/null &&
grep HT error >/dev/null &&
grep With error >/dev/null &&
grep Return normal >/dev/null &&
grep No normal >/dev/null
'
Expand Down
15 changes: 13 additions & 2 deletions ws.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static struct whitespace_rule {
{ "trailing-space", WS_TRAILING_SPACE },
{ "space-before-tab", WS_SPACE_BEFORE_TAB },
{ "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
{ "cr-at-eol", WS_CR_AT_EOL },
};

unsigned parse_whitespace_rule(const char *string)
Expand Down Expand Up @@ -124,13 +125,19 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
int written = 0;
int trailing_whitespace = -1;
int trailing_newline = 0;
int trailing_carriage_return = 0;
int i;

/* Logic is simpler if we temporarily ignore the trailing newline. */
if (len > 0 && line[len - 1] == '\n') {
trailing_newline = 1;
len--;
}
if ((ws_rule & WS_CR_AT_EOL) &&
len > 0 && line[len - 1] == '\r') {
trailing_carriage_return = 1;
len--;
}

/* Check for trailing whitespace. */
if (ws_rule & WS_TRAILING_SPACE) {
Expand Down Expand Up @@ -176,8 +183,10 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
}

if (stream) {
/* Now the rest of the line starts at written.
* The non-highlighted part ends at trailing_whitespace. */
/*
* Now the rest of the line starts at "written".
* The non-highlighted part ends at "trailing_whitespace".
*/
if (trailing_whitespace == -1)
trailing_whitespace = len;

Expand All @@ -196,6 +205,8 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
len - trailing_whitespace, 1, stream);
fputs(reset, stream);
}
if (trailing_carriage_return)
fputc('\r', stream);
if (trailing_newline)
fputc('\n', stream);
}
Expand Down

0 comments on commit b2979ff

Please sign in to comment.