diff options
-rw-r--r-- | Documentation/config.txt | 4 | ||||
-rw-r--r-- | builtin-apply.c | 18 | ||||
-rw-r--r-- | cache.h | 1 | ||||
-rwxr-xr-x | t/t4019-diff-wserror.sh | 40 | ||||
-rw-r--r-- | ws.c | 15 |
5 files changed, 72 insertions, 6 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index 4e222f15a..44cb640fb 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -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. diff --git a/builtin-apply.c b/builtin-apply.c index fccf4a40c..2b8ba81d8 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -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; @@ -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; + } } /* @@ -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) @@ -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 *); diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index 67e080bdb..0d9cbb626 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -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 ' @@ -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 ' @@ -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 ' @@ -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 ' @@ -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 ' @@ -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 ' @@ -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 ' @@ -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 ' @@ -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) @@ -124,6 +125,7 @@ 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. */ @@ -131,6 +133,11 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule, 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) { @@ -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; @@ -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); } |