#!/bin/sh global test_description := ''diff whitespace error detection'' source ./test-lib.sh test_expect_success setup ' git config diff.color.whitespace "blue reverse" && >F && git add F && 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 && echo >>F ' global blue_grep := ''7;34m'' ;# ESC [ 7 ; 3 4 m printf "\033[%s" $blue_grep >check-grep if shell {grep $blue_grep /dev/null 2>&1 { global grep_a := 'grep' } elif shell {grep -a $blue_grep /dev/null 2>&1 { global grep_a := ''grep -a'' } else { global grep_a := 'grep' ;# expected to fail... } rm -f check-grep proc prepare_output { git diff --color >output $grep_a $blue_grep output >error $grep_a -v $blue_grep output >normal return 0 } test_expect_success default ' prepare_output && 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 ' test_expect_success 'default (attribute)' ' test_might_fail git config --unset core.whitespace && echo "F whitespace" >.gitattributes && prepare_output && grep Eight error >/dev/null && grep HT error >/dev/null && grep With error >/dev/null && grep Return error >/dev/null && grep No normal >/dev/null ' test_expect_success 'default, tabwidth=10 (attribute)' ' git config core.whitespace "tabwidth=10" && echo "F whitespace" >.gitattributes && prepare_output && 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 ' test_expect_success 'no check (attribute)' ' test_might_fail git config --unset core.whitespace && echo "F -whitespace" >.gitattributes && prepare_output && grep Eight normal >/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 'no check, tabwidth=10 (attribute), must be irrelevant' ' git config core.whitespace "tabwidth=10" && echo "F -whitespace" >.gitattributes && prepare_output && grep Eight normal >/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 'without -trail' ' rm -f .gitattributes && git config core.whitespace -trail && prepare_output && 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 ' test_expect_success 'without -trail (attribute)' ' test_might_fail git config --unset core.whitespace && echo "F whitespace=-trail" >.gitattributes && prepare_output && 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 ' test_expect_success 'without -space' ' rm -f .gitattributes && git config core.whitespace -space && prepare_output && 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 ' test_expect_success 'without -space (attribute)' ' test_might_fail git config --unset core.whitespace && echo "F whitespace=-space" >.gitattributes && prepare_output && 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 ' test_expect_success 'with indent-non-tab only' ' rm -f .gitattributes && git config core.whitespace indent,-trailing,-space && prepare_output && 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 indent-non-tab only (attribute)' ' test_might_fail git config --unset core.whitespace && echo "F whitespace=indent,-trailing,-space" >.gitattributes && prepare_output && 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 indent-non-tab only, tabwidth=10' ' rm -f .gitattributes && git config core.whitespace indent,tabwidth=10,-trailing,-space && prepare_output && grep Eight normal >/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 indent-non-tab only, tabwidth=10 (attribute)' ' test_might_fail git config --unset core.whitespace && echo "F whitespace=indent,-trailing,-space,tabwidth=10" >.gitattributes && prepare_output && grep Eight normal >/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 && prepare_output && 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)' ' test_might_fail git config --unset core.whitespace && echo "F whitespace=trailing,cr-at-eol" >.gitattributes && prepare_output && 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 'trailing empty lines (1)' ' rm -f .gitattributes && test_must_fail git diff --check >output && grep "new blank line at" output && grep "trailing whitespace" output ' test_expect_success 'trailing empty lines (2)' ' echo "F -whitespace" >.gitattributes && git diff --check >output && ! test -s output ' test_expect_success 'checkdiff shows correct line number for trailing blank lines' ' printf "a\nb\n" > G && git add G && printf "x\nx\nx\na\nb\nc\n\n" > G && [ "$(git diff --check -- G)" = "G:7: new blank line at EOF." ] ' test_expect_success 'do not color trailing cr in context' ' test_might_fail git config --unset core.whitespace && rm -f .gitattributes && echo AAAQ | tr Q "\015" >G && git add G && echo BBBQ | tr Q "\015" >>G && git diff --color G | tr "\015" Q >output && grep "BBB.*${blue_grep}Q" output && grep "AAA.*\[mQ" output ' test_expect_success 'color new trailing blank lines' ' { echo a; echo b; echo; echo; } >x && git add x && { echo a; echo; echo; echo; echo c; echo; echo; echo; echo; } >x && git diff --color x >output && cnt=$($grep_a "${blue_grep}" output | wc -l) && test $cnt = 2 ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"diff whitespace error detection">)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(setup)} { (SQ <"\n"> <"\n"> <"\tgit config diff.color.whitespace \"blue reverse\" &&\n"> <"\t>F &&\n"> <"\tgit add F &&\n"> <"\techo \" Eight SP indent\" >>F &&\n"> <"\techo \" \tHT and SP indent\" >>F &&\n"> <"\techo \"With trailing SP \" >>F &&\n"> <"\techo \"Carriage ReturnQ\" | tr Q \"\\015\" >>F &&\n"> <"\techo \"No problem\" >>F &&\n"> <"\techo >>F\n"> <"\n"> ) } ) (Sentence child: (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:blue_grep) op:Equal rhs:{(SQ <"7;34m">)} spids:[35])] spids: [35] ) terminator: ) (SimpleCommand words: [ {(printf)} {(DQ (EscapedLiteralPart token:) ("33[%s"))} {(DQ ($ VSub_Name "$blue_grep"))} ] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(check-grep)} spids:[56])] ) (If arms: [ (if_arm cond: [ (Subshell child: (Pipeline children: [ (SimpleCommand words: [{(grep)} {(DQ ($ VSub_Name "$blue_grep"))}] redirects: [(Redir op_id:Redir_Less fd:-1 arg_word:{(check-grep)} spids:[68])] ) (C {(grep)} {(DQ ($ VSub_Name "$blue_grep"))}) ] negated: False ) redirects: [ (Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[80]) (Redir op_id:Redir_GreatAnd fd:2 arg_word:{(1)} spids:[83]) ] spids: [61 78] ) ] action: [ (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:grep_a) op:Equal rhs:{(grep)} spids:[89])] spids: [89] ) ] spids: [-1 86] ) (if_arm cond: [ (Subshell child: (Pipeline children: [ (SimpleCommand words: [{(grep)} {(-a)} {(DQ ($ VSub_Name "$blue_grep"))}] redirects: [(Redir op_id:Redir_Less fd:-1 arg_word:{(check-grep)} spids:[103])] ) (C {(grep)} {(-a)} {(DQ ($ VSub_Name "$blue_grep"))}) ] negated: False ) redirects: [ (Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[117]) (Redir op_id:Redir_GreatAnd fd:2 arg_word:{(1)} spids:[120]) ] spids: [94 115] ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:grep_a) op: Equal rhs: {(SQ <"grep -a">)} spids: [126] ) ] spids: [126] ) ] spids: [92 123] ) ] else_action: [ (Sentence child: (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:grep_a) op:Equal rhs:{(grep)} spids:[134])] spids: [134] ) terminator: ) ] spids: [131 141] ) (C {(rm)} {(-f)} {(check-grep)}) (FuncDef name: prepare_output body: (BraceGroup children: [ (SimpleCommand words: [{(git)} {(diff)} {(--color)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(output)} spids:[164])] ) (SimpleCommand words: [{($ VSub_Name "$grep_a")} {(DQ ($ VSub_Name "$blue_grep"))} {(output)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(error)} spids:[176])] ) (SimpleCommand words: [{($ VSub_Name "$grep_a")} {(-v)} {(DQ ($ VSub_Name "$blue_grep"))} {(output)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(normal)} spids:[190])] ) (ControlFlow token: arg_word:{(0)}) ] spids: [155] ) spids: [150 154] ) (C {(test_expect_success)} {(default)} { (SQ <"\n"> <"\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return error >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"default (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F whitespace\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight error >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return error >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"default, tabwidth=10 (attribute)">)} { (SQ <"\n"> <"\n"> <"\tgit config core.whitespace \"tabwidth=10\" &&\n"> <"\techo \"F whitespace\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return error >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"no check (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F -whitespace\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"no check, tabwidth=10 (attribute), must be irrelevant">)} { (SQ <"\n"> <"\n"> <"\tgit config core.whitespace \"tabwidth=10\" &&\n"> <"\techo \"F -whitespace\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"without -trail">)} { (SQ <"\n"> <"\n"> <"\trm -f .gitattributes &&\n"> <"\tgit config core.whitespace -trail &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"without -trail (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F whitespace=-trail\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"without -space">)} { (SQ <"\n"> <"\n"> <"\trm -f .gitattributes &&\n"> <"\tgit config core.whitespace -space &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return error >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"without -space (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F whitespace=-space\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return error >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"with indent-non-tab only">)} { (SQ <"\n"> <"\n"> <"\trm -f .gitattributes &&\n"> <"\tgit config core.whitespace indent,-trailing,-space &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight error >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"with indent-non-tab only (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F whitespace=indent,-trailing,-space\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight error >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"with indent-non-tab only, tabwidth=10">)} { (SQ <"\n"> <"\n"> <"\trm -f .gitattributes &&\n"> <"\tgit config core.whitespace indent,tabwidth=10,-trailing,-space &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"with indent-non-tab only, tabwidth=10 (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F whitespace=indent,-trailing,-space,tabwidth=10\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT normal >/dev/null &&\n"> <"\tgrep With normal >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"with cr-at-eol">)} { (SQ <"\n"> <"\n"> <"\trm -f .gitattributes &&\n"> <"\tgit config core.whitespace cr-at-eol &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"with cr-at-eol (attribute)">)} { (SQ <"\n"> <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\techo \"F whitespace=trailing,cr-at-eol\" >.gitattributes &&\n"> <"\tprepare_output &&\n"> <"\n"> <"\tgrep Eight normal >/dev/null &&\n"> <"\tgrep HT error >/dev/null &&\n"> <"\tgrep With error >/dev/null &&\n"> <"\tgrep Return normal >/dev/null &&\n"> <"\tgrep No normal >/dev/null\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"trailing empty lines (1)">)} { (SQ <"\n"> <"\n"> <"\trm -f .gitattributes &&\n"> <"\ttest_must_fail git diff --check >output &&\n"> <"\tgrep \"new blank line at\" output &&\n"> <"\tgrep \"trailing whitespace\" output\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"trailing empty lines (2)">)} { (SQ <"\n"> <"\n"> <"\techo \"F -whitespace\" >.gitattributes &&\n"> <"\tgit diff --check >output &&\n"> <"\t! test -s output\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"checkdiff shows correct line number for trailing blank lines">)} { (SQ <"\n"> <"\n"> <"\tprintf \"a\\nb\\n\" > G &&\n"> <"\tgit add G &&\n"> <"\tprintf \"x\\nx\\nx\\na\\nb\\nc\\n\\n\" > G &&\n"> <"\t[ \"$(git diff --check -- G)\" = \"G:7: new blank line at EOF.\" ]\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"do not color trailing cr in context">)} { (SQ <"\n"> <"\ttest_might_fail git config --unset core.whitespace &&\n"> <"\trm -f .gitattributes &&\n"> <"\techo AAAQ | tr Q \"\\015\" >G &&\n"> <"\tgit add G &&\n"> <"\techo BBBQ | tr Q \"\\015\" >>G &&\n"> <"\tgit diff --color G | tr \"\\015\" Q >output &&\n"> <"\tgrep \"BBB.*${blue_grep}Q\" output &&\n"> <"\tgrep \"AAA.*\\[mQ\" output\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"color new trailing blank lines">)} { (SQ <"\n"> <"\t{ echo a; echo b; echo; echo; } >x &&\n"> <"\tgit add x &&\n"> <"\t{ echo a; echo; echo; echo; echo c; echo; echo; echo; echo; } >x &&\n"> <"\tgit diff --color x >output &&\n"> <"\tcnt=$($grep_a \"${blue_grep}\" output | wc -l) &&\n"> <"\ttest $cnt = 2\n"> ) } ) (C {(test_done)}) ] )