@matheusbsbs / matheus-bagliano / commits / b2979ff599
Fork 0

core.whitespace: cr-at-eol

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>

Junio C Hamano committed Jan 15, 2008 at 00:59 UTC b2979ff599a6bcf9dbf5e2ef1e32b81a1b88e115
5 files changed +72 -6
Documentation/config.txt
+4
@@ -308,6 +308,10 @@ core.whitespace::
308 error (enabled by default).
309 * `indent-with-non-tab` treats a line that is indented with 8 or more
310 space characters as an error (not enabled by default).
311 +* `cr-at-eol` treats a carriage-return at the end of line as
312 + part of the line terminator, i.e. with it, `trailing-space`
313 + does not trigger if the character before such a carriage-return
314 + is not a whitespace (not enabled by default).
315
316 alias.*::
317 Command aliases for the linkgit:git[1] command wrapper - e.g.
builtin-apply.c
+14 -4
@@ -1525,6 +1525,7 @@ static int copy_wsfix(char *output, const char *patch, int plen,
1525 */
1526 int i;
1527 int add_nl_to_tail = 0;
1528 + int add_cr_to_tail = 0;
1529 int fixed = 0;
1530 int last_tab_in_indent = -1;
1531 int last_space_in_indent = -1;
@@ -1536,12 +1537,19 @@ static int copy_wsfix(char *output, const char *patch, int plen,
1537 */
1538 if ((ws_rule & WS_TRAILING_SPACE) &&
1539 (2 < plen && isspace(patch[plen-2]))) {
1539 - if (patch[plen-1] == '\n')
1540 + if (patch[plen - 1] == '\n') {
1541 add_nl_to_tail = 1;
1541 - plen--;
1542 - while (0 < plen && isspace(patch[plen-1]))
1542 plen--;
1544 - fixed = 1;
1543 + if (1 < plen && patch[plen - 1] == '\r') {
1544 + add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL);
1545 + plen--;
1546 + }
1547 + }
1548 + if (0 < plen && isspace(patch[plen - 1])) {
1549 + while (0 < plen && isspace(patch[plen-1]))
1550 + plen--;
1551 + fixed = 1;
1552 + }
1553 }
1554
1555 /*
@@ -1602,6 +1610,8 @@ static int copy_wsfix(char *output, const char *patch, int plen,
1610 }
1611
1612 memcpy(output, patch, plen);
1613 + if (add_cr_to_tail)
1614 + output[plen++] = '\r';
1615 if (add_nl_to_tail)
1616 output[plen++] = '\n';
1617 if (fixed && count_error)
cache.h
+1
@@ -652,6 +652,7 @@ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, i
652 #define WS_TRAILING_SPACE 01
653 #define WS_SPACE_BEFORE_TAB 02
654 #define WS_INDENT_WITH_NON_TAB 04
655 +#define WS_CR_AT_EOL 010
656 #define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)
657 extern unsigned whitespace_rule_cfg;
658 extern unsigned whitespace_rule(const char *);
t/t4019-diff-wserror.sh
+40
@@ -12,6 +12,7 @@ test_expect_success setup '
12 echo " Eight SP indent" >>F &&
13 echo " HT and SP indent" >>F &&
14 echo "With trailing SP " >>F &&
15 + echo "Carriage ReturnQ" | tr Q "\015" >>F &&
16 echo "No problem" >>F
17
18 '
@@ -27,6 +28,7 @@ test_expect_success default '
28 grep Eight normal >/dev/null &&
29 grep HT error >/dev/null &&
30 grep With error >/dev/null &&
31 + grep Return error >/dev/null &&
32 grep No normal >/dev/null
33
34 '
@@ -41,6 +43,7 @@ test_expect_success 'without -trail' '
43 grep Eight normal >/dev/null &&
44 grep HT error >/dev/null &&
45 grep With normal >/dev/null &&
46 + grep Return normal >/dev/null &&
47 grep No normal >/dev/null
48
49 '
@@ -56,6 +59,7 @@ test_expect_success 'without -trail (attribute)' '
59 grep Eight normal >/dev/null &&
60 grep HT error >/dev/null &&
61 grep With normal >/dev/null &&
62 + grep Return normal >/dev/null &&
63 grep No normal >/dev/null
64
65 '
@@ -71,6 +75,7 @@ test_expect_success 'without -space' '
75 grep Eight normal >/dev/null &&
76 grep HT normal >/dev/null &&
77 grep With error >/dev/null &&
78 + grep Return error >/dev/null &&
79 grep No normal >/dev/null
80
81 '
@@ -86,6 +91,7 @@ test_expect_success 'without -space (attribute)' '
91 grep Eight normal >/dev/null &&
92 grep HT normal >/dev/null &&
93 grep With error >/dev/null &&
94 + grep Return error >/dev/null &&
95 grep No normal >/dev/null
96
97 '
@@ -101,6 +107,7 @@ test_expect_success 'with indent-non-tab only' '
107 grep Eight error >/dev/null &&
108 grep HT normal >/dev/null &&
109 grep With normal >/dev/null &&
110 + grep Return normal >/dev/null &&
111 grep No normal >/dev/null
112
113 '
@@ -116,6 +123,39 @@ test_expect_success 'with indent-non-tab only (attribute)' '
123 grep Eight error >/dev/null &&
124 grep HT normal >/dev/null &&
125 grep With normal >/dev/null &&
126 + grep Return normal >/dev/null &&
127 + grep No normal >/dev/null
128 +
129 +'
130 +
131 +test_expect_success 'with cr-at-eol' '
132 +
133 + rm -f .gitattributes
134 + git config core.whitespace cr-at-eol
135 + git diff --color >output
136 + grep "$blue_grep" output >error
137 + grep -v "$blue_grep" output >normal
138 +
139 + grep Eight normal >/dev/null &&
140 + grep HT error >/dev/null &&
141 + grep With error >/dev/null &&
142 + grep Return normal >/dev/null &&
143 + grep No normal >/dev/null
144 +
145 +'
146 +
147 +test_expect_success 'with cr-at-eol (attribute)' '
148 +
149 + git config --unset core.whitespace
150 + echo "F whitespace=trailing,cr-at-eol" >.gitattributes
151 + git diff --color >output
152 + grep "$blue_grep" output >error
153 + grep -v "$blue_grep" output >normal
154 +
155 + grep Eight normal >/dev/null &&
156 + grep HT error >/dev/null &&
157 + grep With error >/dev/null &&
158 + grep Return normal >/dev/null &&
159 grep No normal >/dev/null
160
161 '
ws.c
+13 -2
@@ -14,6 +14,7 @@ static struct whitespace_rule {
14 { "trailing-space", WS_TRAILING_SPACE },
15 { "space-before-tab", WS_SPACE_BEFORE_TAB },
16 { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
17 + { "cr-at-eol", WS_CR_AT_EOL },
18 };
19
20 unsigned parse_whitespace_rule(const char *string)
@@ -124,6 +125,7 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
125 int written = 0;
126 int trailing_whitespace = -1;
127 int trailing_newline = 0;
128 + int trailing_carriage_return = 0;
129 int i;
130
131 /* 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,
133 trailing_newline = 1;
134 len--;
135 }
136 + if ((ws_rule & WS_CR_AT_EOL) &&
137 + len > 0 && line[len - 1] == '\r') {
138 + trailing_carriage_return = 1;
139 + len--;
140 + }
141
142 /* Check for trailing whitespace. */
143 if (ws_rule & WS_TRAILING_SPACE) {
@@ -176,8 +183,10 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
183 }
184
185 if (stream) {
179 - /* Now the rest of the line starts at written.
180 - * The non-highlighted part ends at trailing_whitespace. */
186 + /*
187 + * Now the rest of the line starts at "written".
188 + * The non-highlighted part ends at "trailing_whitespace".
189 + */
190 if (trailing_whitespace == -1)
191 trailing_whitespace = len;
192
@@ -196,6 +205,8 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
205 len - trailing_whitespace, 1, stream);
206 fputs(reset, stream);
207 }
208 + if (trailing_carriage_return)
209 + fputc('\r', stream);
210 if (trailing_newline)
211 fputc('\n', stream);
212 }