{"thread":{"id":"10584","subject":"[PATCH 1/2] War on whitespace: first, a bit of retreat.","startedAt":"2007-11-02T07:34:05Z","lastAt":"2007-11-14T00:46:19Z","messageCount":12,"participants":["Junio C Hamano","David Symonds","Andreas Ericsson","Jakub Narebski","J. Bruce Fields","Josh Triplett"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"57933","messageId":"7vwst15ceq.fsf@gitster.siamese.dyndns.org","threadId":"10584","inReplyTo":null,"subject":"[PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-02T07:34:05Z","receivedAt":"2007-11-02T07:34:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This introduces core.whitespace configuration variable that lets\nyou specify the definition of \"whitespace error\".\n\nCurrently there are two kinds of whitespace errors defined:\n\n * trailing-space: trailing whitespaces at the end of the line.\n\n * space-before-tab: a SP appears immediately before HT in the\n   indent part of the line.\n\nYou can specify the desired types of errors to be detected by\nlisting their names (unique abbreviations are accepted)\nseparated by comma.  By default, these two errors are always\ndetected, as that is the traditional behaviour.  You can disable\ndetection of a particular type of error by prefixing a '-' in\nfront of the name of the error, like this:\n\n\t[core]\n\t\twhitespace = -trailing-space\n\nThis patch teaches the code to output colored diff with\nDIFF_WHITESPACE color to highlight the detected whitespace\nerrors to honor the new configuration.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n cache.h       |    9 +++++++++\n config.c      |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n diff.c        |   13 ++++++++-----\n environment.c |    1 +\n 4 files changed, 70 insertions(+), 5 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex bfffa05..a6e5988 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -602,4 +602,13 @@ extern int diff_auto_refresh_index;\n /* match-trees.c */\n void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);\n \n+/*\n+ * whitespace rules.\n+ * used by both diff and apply\n+ */\n+#define WS_TRAILING_SPACE\t01\n+#define WS_SPACE_BEFORE_TAB\t02\n+#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)\n+extern unsigned whitespace_rule;\n+\n #endif /* CACHE_H */\ndiff --git a/config.c b/config.c\nindex dc3148d..ffb418c 100644\n--- a/config.c\n+++ b/config.c\n@@ -246,6 +246,53 @@ static unsigned long get_unit_factor(const char *end)\n \tdie(\"unknown unit: '%s'\", end);\n }\n \n+static struct whitespace_rule {\n+\tconst char *rule_name;\n+\tunsigned rule_bits;\n+} whitespace_rule_names[] = {\n+\t{ \"trailing-space\", WS_TRAILING_SPACE },\n+\t{ \"space-before-tab\", WS_SPACE_BEFORE_TAB },\n+};\n+\n+static unsigned parse_whitespace_rule(const char *string)\n+{\n+\tunsigned rule = WS_DEFAULT_RULE;\n+\n+\twhile (string) {\n+\t\tint i;\n+\t\tsize_t len;\n+\t\tconst char *ep;\n+\t\tint negated = 0;\n+\n+\t\tstring = string + strspn(string, \", \\t\\n\\r\");\n+\t\tep = strchr(string, ',');\n+\t\tif (!ep)\n+\t\t\tlen = strlen(string);\n+\t\telse\n+\t\t\tlen = ep - string;\n+\n+\t\tif (*string == '-') {\n+\t\t\tnegated = 1;\n+\t\t\tstring++;\n+\t\t\tlen--;\n+\t\t}\n+\t\tif (!len)\n+\t\t\tbreak;\n+\t\tfor (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) {\n+\t\t\tif (strncmp(whitespace_rule_names[i].rule_name,\n+\t\t\t\t    string, len))\n+\t\t\t\tcontinue;\n+\t\t\tif (negated)\n+\t\t\t\trule &= ~whitespace_rule_names[i].rule_bits;\n+\t\t\telse\n+\t\t\t\trule |= whitespace_rule_names[i].rule_bits;\n+\t\t\tbreak;\n+\t\t}\n+\t\tstring = ep;\n+\t}\n+\treturn rule;\n+}\n+\n int git_parse_long(const char *value, long *ret)\n {\n \tif (value && *value) {\n@@ -431,6 +478,11 @@ int git_default_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"core.whitespace\")) {\n+\t\twhitespace_rule = parse_whitespace_rule(value);\n+\t\treturn 0;\n+\t}\n+\n \t/* Add other config variables here and to Documentation/config.txt. */\n \treturn 0;\n }\ndiff --git a/diff.c b/diff.c\nindex a6aaaf7..2112353 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -508,7 +508,8 @@ static void emit_line_with_ws(int nparents,\n \tfor (i = col0; i < len; i++) {\n \t\tif (line[i] == '\\t') {\n \t\t\tlast_tab_in_indent = i;\n-\t\t\tif (0 <= last_space_in_indent)\n+\t\t\tif ((whitespace_rule & WS_SPACE_BEFORE_TAB) &&\n+\t\t\t    0 <= last_space_in_indent)\n \t\t\t\tneed_highlight_leading_space = 1;\n \t\t}\n \t\telse if (line[i] == ' ')\n@@ -540,10 +541,12 @@ static void emit_line_with_ws(int nparents,\n \ttail = len - 1;\n \tif (line[tail] == '\\n' && i < tail)\n \t\ttail--;\n-\twhile (i < tail) {\n-\t\tif (!isspace(line[tail]))\n-\t\t\tbreak;\n-\t\ttail--;\n+\tif (whitespace_rule & WS_TRAILING_SPACE) {\n+\t\twhile (i < tail) {\n+\t\t\tif (!isspace(line[tail]))\n+\t\t\t\tbreak;\n+\t\t\ttail--;\n+\t\t}\n \t}\n \tif ((i < tail && line[tail + 1] != '\\n')) {\n \t\t/* This has whitespace between tail+1..len */\ndiff --git a/environment.c b/environment.c\nindex b5a6c69..624dd96 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -35,6 +35,7 @@ int pager_in_use;\n int pager_use_color = 1;\n char *editor_program;\n int auto_crlf = 0;\t/* 1: both ways, -1: only when adding git objects */\n+unsigned whitespace_rule = WS_DEFAULT_RULE;\n \n /* This is set by setup_git_dir_gently() and/or git_default_config() */\n char *git_work_tree_cfg;\n-- \n1.5.3.5.1452.ga93d\n"},{"id":"57934","messageId":"7vr6j95c84.fsf@gitster.siamese.dyndns.org","threadId":"10584","inReplyTo":"7vwst15ceq.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 2/2] git-diff: complain about >=8 consecutive spaces in initial indent","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-02T07:38:03Z","receivedAt":"2007-11-02T07:38:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This introduces a new whitespace error type, \"indent-with-non-tab\".\nThe error is about starting a line with 8 or more SP, instead of\nindenting it with a HT.\n\nThis is not enabled by default, as some projects employ an\nindenting policy to use only SPs and no HTs.\n\nThe kernel folks and git contributors may want to enable this\ndetection with:\n\n\t[core]\n\t\twhitespace = indent-with-non-tab\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * Obviously, it is too late at night for me to do the same for\n   git-apply, but it's Ok as I know there are capable interested\n   parties on the list.  Hint, hint...\n\n cache.h  |    1 +\n config.c |    1 +\n diff.c   |   14 ++++++++++++--\n 3 files changed, 14 insertions(+), 2 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex a6e5988..3f42827 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -608,6 +608,7 @@ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, i\n  */\n #define WS_TRAILING_SPACE\t01\n #define WS_SPACE_BEFORE_TAB\t02\n+#define WS_INDENT_WITH_NON_TAB\t04\n #define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)\n extern unsigned whitespace_rule;\n \ndiff --git a/config.c b/config.c\nindex ffb418c..d5b9766 100644\n--- a/config.c\n+++ b/config.c\n@@ -252,6 +252,7 @@ static struct whitespace_rule {\n } whitespace_rule_names[] = {\n \t{ \"trailing-space\", WS_TRAILING_SPACE },\n \t{ \"space-before-tab\", WS_SPACE_BEFORE_TAB },\n+\t{ \"indent-with-non-tab\", WS_INDENT_WITH_NON_TAB },\n };\n \n static unsigned parse_whitespace_rule(const char *string)\ndiff --git a/diff.c b/diff.c\nindex 2112353..6bb902f 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -502,8 +502,11 @@ static void emit_line_with_ws(int nparents,\n \tint i;\n \tint tail = len;\n \tint need_highlight_leading_space = 0;\n-\t/* The line is a newly added line.  Does it have funny leading\n-\t * whitespaces?  In indent, SP should never precede a TAB.\n+\t/*\n+\t * The line is a newly added line.  Does it have funny leading\n+\t * whitespaces?  In indent, SP should never precede a TAB.  In\n+\t * addition, under \"indent with non tab\" rule, there should not\n+\t * be more than 8 consecutive spaces.\n \t */\n \tfor (i = col0; i < len; i++) {\n \t\tif (line[i] == '\\t') {\n@@ -517,6 +520,13 @@ static void emit_line_with_ws(int nparents,\n \t\telse\n \t\t\tbreak;\n \t}\n+\tif ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&\n+\t    0 <= last_space_in_indent &&\n+\t    last_tab_in_indent < 0 &&\n+\t    8 <= (i - col0)) {\n+\t\tlast_tab_in_indent = i;\n+\t\tneed_highlight_leading_space = 1;\n+\t}\n \tfputs(set, stdout);\n \tfwrite(line, col0, 1, stdout);\n \tfputs(reset, stdout);\n-- \n1.5.3.5.1452.ga93d\n"},{"id":"57959","messageId":"ee77f5c20711020314h43290dbs8141cb3905c867@mail.gmail.com","threadId":"10584","inReplyTo":"7vwst15ceq.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"David Symonds","fromEmail":"dsymonds@gmail.com","sentAt":"2007-11-02T10:14:23Z","receivedAt":"2007-11-02T10:14:23Z","isPatch":true,"sender":{"key":"dsymonds@gmail.com","avatar":"https://gravatar.com/avatar/b22f5051cbfc11836e36cf7a690e6cde4e225d835e13295ff98d15c7a9ee3c0f?d=mp&s=160"},"body":"On 11/2/07, Junio C Hamano <gitster@pobox.com> wrote:\n> This introduces core.whitespace configuration variable that lets\n> you specify the definition of \"whitespace error\".\n>\n> Currently there are two kinds of whitespace errors defined:\n>\n>  * trailing-space: trailing whitespaces at the end of the line.\n>\n>  * space-before-tab: a SP appears immediately before HT in the\n>    indent part of the line.\n\n>         [core]\n>                 whitespace = -trailing-space\n\nCould I suggest naming the option 'whitespaceError', so it's clearer\nthat it's a negative setting?\n\n\nDave.\n"},{"id":"57966","messageId":"472AFFE4.9060004@op5.se","threadId":"10584","inReplyTo":"ee77f5c20711020314h43290dbs8141cb3905c867@mail.gmail.com","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2007-11-02T10:45:56Z","receivedAt":"2007-11-02T10:45:56Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"David Symonds wrote:\n> On 11/2/07, Junio C Hamano <gitster@pobox.com> wrote:\n>> This introduces core.whitespace configuration variable that lets\n>> you specify the definition of \"whitespace error\".\n>>\n>> Currently there are two kinds of whitespace errors defined:\n>>\n>>  * trailing-space: trailing whitespaces at the end of the line.\n>>\n>>  * space-before-tab: a SP appears immediately before HT in the\n>>    indent part of the line.\n> \n>>         [core]\n>>                 whitespace = -trailing-space\n> \n> Could I suggest naming the option 'whitespaceError', so it's clearer\n> that it's a negative setting?\n> \n\nWhich would also open the window for \"WhitespaceWarning\" and \"WhitespaceAutofix\"\nlater on, using the same semantics. Personally, I'd like to get warnings for\nnon-tab-indent^H^H^H indent-with-non-tab (rename that option, perhaps?), autofix\nfor trailing-whitespace and errors for space-before-tab, with command-line\nswitch to override config settings.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"57971","messageId":"ee77f5c20711020450hdfe064fsace9349fe6494ec9@mail.gmail.com","threadId":"10584","inReplyTo":"472AFFE4.9060004@op5.se","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"David Symonds","fromEmail":"dsymonds@gmail.com","sentAt":"2007-11-02T11:50:36Z","receivedAt":"2007-11-02T11:50:36Z","isPatch":true,"sender":{"key":"dsymonds@gmail.com","avatar":"https://gravatar.com/avatar/b22f5051cbfc11836e36cf7a690e6cde4e225d835e13295ff98d15c7a9ee3c0f?d=mp&s=160"},"body":"On 11/2/07, Andreas Ericsson <ae@op5.se> wrote:\n> David Symonds wrote:\n> > On 11/2/07, Junio C Hamano <gitster@pobox.com> wrote:\n> >> This introduces core.whitespace configuration variable that lets\n> >> you specify the definition of \"whitespace error\".\n> >>\n> >> Currently there are two kinds of whitespace errors defined:\n> >>\n> >>  * trailing-space: trailing whitespaces at the end of the line.\n> >>\n> >>  * space-before-tab: a SP appears immediately before HT in the\n> >>    indent part of the line.\n> >\n> >>         [core]\n> >>                 whitespace = -trailing-space\n> >\n> > Could I suggest naming the option 'whitespaceError', so it's clearer\n> > that it's a negative setting?\n> >\n>\n> Which would also open the window for \"WhitespaceWarning\" and \"WhitespaceAutofix\"\n> later on, using the same semantics.\n\nMaybe cut straight to the chase:\n\n[core]\n        whitespace.trailing = error\n        whitespace.space-before-tab = error\n        whitespace.8-spaces = warn\n\nThere'd be at least \"error\", \"warn\"; \"okay\" and \"autofix\" would be\nother sensible values. I'm willing to help code this up if this sounds\ngood.\n\n\nDave.\n"},{"id":"57973","messageId":"fgf4qu$e8c$1@ger.gmane.org","threadId":"10584","inReplyTo":"ee77f5c20711020450hdfe064fsace9349fe6494ec9@mail.gmail.com","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-11-02T12:25:32Z","receivedAt":"2007-11-02T12:25:32Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"David Symonds wrote:\n> On 11/2/07, Andreas Ericsson <ae@op5.se> wrote:\n>> David Symonds wrote:\n>>> On 11/2/07, Junio C Hamano <gitster@pobox.com> wrote:\n>>>> This introduces core.whitespace configuration variable that lets\n>>>> you specify the definition of \"whitespace error\".\n>>>>\n>>>> Currently there are two kinds of whitespace errors defined:\n>>>>\n>>>>  * trailing-space: trailing whitespaces at the end of the line.\n>>>>\n>>>>  * space-before-tab: a SP appears immediately before HT in the\n>>>>    indent part of the line.\n>>>\n>>>>         [core]\n>>>>                 whitespace = -trailing-space\n>>>\n>>> Could I suggest naming the option 'whitespaceError', so it's clearer\n>>> that it's a negative setting?\n>>\n>> Which would also open the window for \"WhitespaceWarning\" and \"WhitespaceAutofix\"\n>> later on, using the same semantics.\n> \n> Maybe cut straight to the chase:\n> \n> [core]\n>         whitespace.trailing = error\n>         whitespace.space-before-tab = error\n>         whitespace.8-spaces = warn\n> \n> There'd be at least \"error\", \"warn\"; \"okay\" and \"autofix\" would be\n> other sensible values. I'm willing to help code this up if this sounds\n> good.\n\nNice idea, but the syntax is\n\n[core \"whitespace\"]\n        trailing = error\n        space-before-tab = error\n        indent-with-space = warn\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"57977","messageId":"ee77f5c20711020553x1a329fa5g90f38d5b8c1a062e@mail.gmail.com","threadId":"10584","inReplyTo":"fgf4qu$e8c$1@ger.gmane.org","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"David Symonds","fromEmail":"dsymonds@gmail.com","sentAt":"2007-11-02T12:53:24Z","receivedAt":"2007-11-02T12:53:24Z","isPatch":true,"sender":{"key":"dsymonds@gmail.com","avatar":"https://gravatar.com/avatar/b22f5051cbfc11836e36cf7a690e6cde4e225d835e13295ff98d15c7a9ee3c0f?d=mp&s=160"},"body":"On 11/2/07, Jakub Narebski <jnareb@gmail.com> wrote:\n> Nice idea, but the syntax is\n>\n> [core \"whitespace\"]\n>         trailing = error\n>         space-before-tab = error\n>         indent-with-space = warn\n\nWhoops, of course. My brain is a bit muddled tonight.\n\n\n\nDave.\n"},{"id":"57980","messageId":"ee77f5c20711020626s2ec21f1p68f7602dedfdb33a@mail.gmail.com","threadId":"10584","inReplyTo":"ee77f5c20711020553x1a329fa5g90f38d5b8c1a062e@mail.gmail.com","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"David Symonds","fromEmail":"dsymonds@gmail.com","sentAt":"2007-11-02T13:26:32Z","receivedAt":"2007-11-02T13:26:32Z","isPatch":true,"sender":{"key":"dsymonds@gmail.com","avatar":"https://gravatar.com/avatar/b22f5051cbfc11836e36cf7a690e6cde4e225d835e13295ff98d15c7a9ee3c0f?d=mp&s=160"},"body":"On 11/2/07, David Symonds <dsymonds@gmail.com> wrote:\n> On 11/2/07, Jakub Narebski <jnareb@gmail.com> wrote:\n> > Nice idea, but the syntax is\n> >\n> > [core \"whitespace\"]\n> >         trailing = error\n> >         space-before-tab = error\n> >         indent-with-space = warn\n>\n> Whoops, of course. My brain is a bit muddled tonight.\n\nOkay, I've put my money where my mouth is, and coded up an equivalent\nto Junio's patch from the start of this thread. I'll send it through\nin a couple of minutes.\n\n\nDave.\n"},{"id":"58011","messageId":"20071102174552.GE15595@fieldses.org","threadId":"10584","inReplyTo":"7vwst15ceq.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2007-11-02T17:45:52Z","receivedAt":"2007-11-02T17:45:52Z","isPatch":true,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Fri, Nov 02, 2007 at 12:34:05AM -0700, Junio C Hamano wrote:\n> This introduces core.whitespace configuration variable that lets\n> you specify the definition of \"whitespace error\".\n> \n> Currently there are two kinds of whitespace errors defined:\n> \n>  * trailing-space: trailing whitespaces at the end of the line.\n> \n>  * space-before-tab: a SP appears immediately before HT in the\n>    indent part of the line.\n\nThe whitespace policy varies based on the project (and in some cases,\nbased on the file within that project).  It shouldn't vary from user to\nuser or repo to repo.  So the configuration variable mechanism seems a\npoor match.  Would it be possible to use something like gitattributes\ninstead?  Then the whitespace policy would be associated with the\nproject itself, would automatically be propagated on clone, etc.\n\nThanks for working on this.\n\n--b.\n\n> \n> You can specify the desired types of errors to be detected by\n> listing their names (unique abbreviations are accepted)\n> separated by comma.  By default, these two errors are always\n> detected, as that is the traditional behaviour.  You can disable\n> detection of a particular type of error by prefixing a '-' in\n> front of the name of the error, like this:\n> \n> \t[core]\n> \t\twhitespace = -trailing-space\n> \n> This patch teaches the code to output colored diff with\n> DIFF_WHITESPACE color to highlight the detected whitespace\n> errors to honor the new configuration.\n> \n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  cache.h       |    9 +++++++++\n>  config.c      |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n>  diff.c        |   13 ++++++++-----\n>  environment.c |    1 +\n>  4 files changed, 70 insertions(+), 5 deletions(-)\n> \n> diff --git a/cache.h b/cache.h\n> index bfffa05..a6e5988 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -602,4 +602,13 @@ extern int diff_auto_refresh_index;\n>  /* match-trees.c */\n>  void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);\n>  \n> +/*\n> + * whitespace rules.\n> + * used by both diff and apply\n> + */\n> +#define WS_TRAILING_SPACE\t01\n> +#define WS_SPACE_BEFORE_TAB\t02\n> +#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)\n> +extern unsigned whitespace_rule;\n> +\n>  #endif /* CACHE_H */\n> diff --git a/config.c b/config.c\n> index dc3148d..ffb418c 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -246,6 +246,53 @@ static unsigned long get_unit_factor(const char *end)\n>  \tdie(\"unknown unit: '%s'\", end);\n>  }\n>  \n> +static struct whitespace_rule {\n> +\tconst char *rule_name;\n> +\tunsigned rule_bits;\n> +} whitespace_rule_names[] = {\n> +\t{ \"trailing-space\", WS_TRAILING_SPACE },\n> +\t{ \"space-before-tab\", WS_SPACE_BEFORE_TAB },\n> +};\n> +\n> +static unsigned parse_whitespace_rule(const char *string)\n> +{\n> +\tunsigned rule = WS_DEFAULT_RULE;\n> +\n> +\twhile (string) {\n> +\t\tint i;\n> +\t\tsize_t len;\n> +\t\tconst char *ep;\n> +\t\tint negated = 0;\n> +\n> +\t\tstring = string + strspn(string, \", \\t\\n\\r\");\n> +\t\tep = strchr(string, ',');\n> +\t\tif (!ep)\n> +\t\t\tlen = strlen(string);\n> +\t\telse\n> +\t\t\tlen = ep - string;\n> +\n> +\t\tif (*string == '-') {\n> +\t\t\tnegated = 1;\n> +\t\t\tstring++;\n> +\t\t\tlen--;\n> +\t\t}\n> +\t\tif (!len)\n> +\t\t\tbreak;\n> +\t\tfor (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) {\n> +\t\t\tif (strncmp(whitespace_rule_names[i].rule_name,\n> +\t\t\t\t    string, len))\n> +\t\t\t\tcontinue;\n> +\t\t\tif (negated)\n> +\t\t\t\trule &= ~whitespace_rule_names[i].rule_bits;\n> +\t\t\telse\n> +\t\t\t\trule |= whitespace_rule_names[i].rule_bits;\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\tstring = ep;\n> +\t}\n> +\treturn rule;\n> +}\n> +\n>  int git_parse_long(const char *value, long *ret)\n>  {\n>  \tif (value && *value) {\n> @@ -431,6 +478,11 @@ int git_default_config(const char *var, const char *value)\n>  \t\treturn 0;\n>  \t}\n>  \n> +\tif (!strcmp(var, \"core.whitespace\")) {\n> +\t\twhitespace_rule = parse_whitespace_rule(value);\n> +\t\treturn 0;\n> +\t}\n> +\n>  \t/* Add other config variables here and to Documentation/config.txt. */\n>  \treturn 0;\n>  }\n> diff --git a/diff.c b/diff.c\n> index a6aaaf7..2112353 100644\n> --- a/diff.c\n> +++ b/diff.c\n> @@ -508,7 +508,8 @@ static void emit_line_with_ws(int nparents,\n>  \tfor (i = col0; i < len; i++) {\n>  \t\tif (line[i] == '\\t') {\n>  \t\t\tlast_tab_in_indent = i;\n> -\t\t\tif (0 <= last_space_in_indent)\n> +\t\t\tif ((whitespace_rule & WS_SPACE_BEFORE_TAB) &&\n> +\t\t\t    0 <= last_space_in_indent)\n>  \t\t\t\tneed_highlight_leading_space = 1;\n>  \t\t}\n>  \t\telse if (line[i] == ' ')\n> @@ -540,10 +541,12 @@ static void emit_line_with_ws(int nparents,\n>  \ttail = len - 1;\n>  \tif (line[tail] == '\\n' && i < tail)\n>  \t\ttail--;\n> -\twhile (i < tail) {\n> -\t\tif (!isspace(line[tail]))\n> -\t\t\tbreak;\n> -\t\ttail--;\n> +\tif (whitespace_rule & WS_TRAILING_SPACE) {\n> +\t\twhile (i < tail) {\n> +\t\t\tif (!isspace(line[tail]))\n> +\t\t\t\tbreak;\n> +\t\t\ttail--;\n> +\t\t}\n>  \t}\n>  \tif ((i < tail && line[tail + 1] != '\\n')) {\n>  \t\t/* This has whitespace between tail+1..len */\n> diff --git a/environment.c b/environment.c\n> index b5a6c69..624dd96 100644\n> --- a/environment.c\n> +++ b/environment.c\n> @@ -35,6 +35,7 @@ int pager_in_use;\n>  int pager_use_color = 1;\n>  char *editor_program;\n>  int auto_crlf = 0;\t/* 1: both ways, -1: only when adding git objects */\n> +unsigned whitespace_rule = WS_DEFAULT_RULE;\n>  \n>  /* This is set by setup_git_dir_gently() and/or git_default_config() */\n>  char *git_work_tree_cfg;\n> -- \n> 1.5.3.5.1452.ga93d\n> \n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"58065","messageId":"7v7il0yrl3.fsf@gitster.siamese.dyndns.org","threadId":"10584","inReplyTo":"20071102174552.GE15595@fieldses.org","subject":"Re: [PATCH 1/2] War on whitespace: first, a bit of retreat.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-03T02:45:44Z","receivedAt":"2007-11-03T02:45:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> The whitespace policy varies based on the project (and in some cases,\n> based on the file within that project).  It shouldn't vary from user to\n> user or repo to repo.  So the configuration variable mechanism seems a\n> poor match.  Would it be possible to use something like gitattributes\n> instead?  Then the whitespace policy would be associated with the\n> project itself, would automatically be propagated on clone, etc.\n\nThe use of gitattributes certainly sounds like a good way to\ngo.  A project like git may say \"HT indent for C sources, SP\nonly for Python parts\".\n\nHaving said that, I've added a few tests and merged the result\nto 'next' already.  We can improve it to use attributes instead\nwhile on 'next'.\n\nAnd the git-apply side needs a matching adjustment.\n"},{"id":"59772","messageId":"473A3552.3060907@freedesktop.org","threadId":"10584","inReplyTo":"7vr6j95c84.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] git-diff: complain about >=8 consecutive spaces in initial indent","fromName":"Josh Triplett","fromEmail":"josh@freedesktop.org","sentAt":"2007-11-13T23:37:54Z","receivedAt":"2007-11-13T23:37:54Z","isPatch":true,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"[CCing David Symonds, because the same comment also applies to his\npatches.]\n\nJunio C Hamano wrote:\n> This introduces a new whitespace error type, \"indent-with-non-tab\".\n> The error is about starting a line with 8 or more SP, instead of\n> indenting it with a HT.\n> \n> This is not enabled by default, as some projects employ an\n> indenting policy to use only SPs and no HTs.\n> \n> The kernel folks and git contributors may want to enable this\n> detection with:\n> \n> \t[core]\n> \t\twhitespace = indent-with-non-tab\n\nThis seems somewhat broken, whether a project uses tabs for\nindentation or not.  Lines can still legitimately start with many\nspaces.  Tab-based indentation should only use tabs to line up with\nother tabs, not with characters.  (Unfortunately most editors get this\nwrong when indenting with tabs.  I use spaces, not because I\nideologically oppose tabs, but because I can't get any editor I want\nto use to do the right thing with tabs.)\n\nMy standard test case for this:\n\nfprintf(\"some very long string\",\n        arguments);\n\nType the first line, and press enter.  A good editor should indent to\nthe open parenthesis.  However, it should not use a tab, because it\nneeds to match up with the length of \"fprintf(\".  All the editors I\nknow of use a tab; they just blindly replace a tab-width worth of\nspaces with a tab in initial indentation.\n\nThat statement would normally appear indented in a function, so the\ncontinuation line should have tabs up to the indentation level of the\nfprintf, and then 8 spaces.  An example more likely to appear at the\nstart of the line, where this indent-with-non-tab heuristic would flag\nit:\n\n#define macro(arg1, arg2) macro_content \\\n                          more_macro_content\n\nAnother example:\n\nsome_type function_name(arg1, arg2, argred, argblue,\n                        argmore, argless)\n\nAgain, the indentation should use spaces if it wants to line up after\nthe open parenthesis, whether the project uses tabs or spaces for indentation.\n\n(Those examples may or may not match all coding styles; some just\nindent the continuation lines by a fixed number of tabs, and also\ntreat the first line as a continuation line to keep the indentation\nconsistent.  Just presenting them as examples.)\n\n- Josh Triplett\n\n"},{"id":"59796","messageId":"7vabphr6w4.fsf@gitster.siamese.dyndns.org","threadId":"10584","inReplyTo":"473A3552.3060907@freedesktop.org","subject":"Re: [PATCH 2/2] git-diff: complain about >=8 consecutive spaces in initial indent","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-14T00:46:19Z","receivedAt":"2007-11-14T00:46:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josh Triplett <josh@freedesktop.org> writes:\n\n> My standard test case for this:\n>\n> fprintf(\"some very long string\",\n>         arguments);\n>\n> Type the first line, and press enter.  A good editor should indent to\n> the open parenthesis.  However, it should not use a tab, because it\n> needs to match up with the length of \"fprintf(\".\n\nSorry, I do not want to go into ideology or be anal, but I have\nto disagree.  Tab width is 8 spaces (in the kernel and git), so\n\"fprintf(\" from the beginning of the line and an HT at the\nbeginning of the line have the same width.\n\nYour project may have different conventions.  Then you do not\nhave to use that option to check for 8 or more leading spaces.\n\nAnd honestly, I think responding to that by saying \"but somebody\ncan have tab width that is not 8\" is irrelevant.  Somebody else\ncan even use a non-proportional font to print it, so your 8\nspaces and \"fprintf(\" won't line up ANYWAY.\n\nIf you REALLY want to be anal, then the rules to follow would\nbe:\n\n - Do not assume you know the width of a HT, other than that the\n   same number of HT at the beginning of two lines indent to the\n   same distance from the left margin, and more of them indent\n   deeper;\n\n - Do not assume the text will be printed in monospace;\n\nwhich leads to:\n\n - Indent with the same number of HT from the beginning of\n   lines.  Go deeper with one more HT, go shallower with one\n   less HT.\n\n - Start the continuation line with the same number of HT to\n   indent but DO NOT BOTHER aligning.  There is no alignment,\n   period.\n\nI happen to choose to be less anal, and accept 8 space HT _and_\nmonospace font.  So \"complaining at >=8 SP at the beginning\"\nmakes perfect sense, so does a corresponding patch to convert\nsuch runs of SPs to HTs with \"git-apply --whitespace=fix\" (which\nshould require an option to be enabled, and the is not here\nyet) when applying a patch.\n"}]}