(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(gitattributes)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (FuncDef name: attr_check body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:path) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [21] ) (assign_pair lhs: (LhsName name:expect) op: Equal rhs: {(DQ ($ VSub_Number "$2"))} spids: [26] ) ] spids: [21] ) (AndOr children: [ (SimpleCommand words: [ {(git)} {($ VSub_Number "$3")} {(check-attr)} {(test)} {(--)} {(DQ ($ VSub_Name "$path"))} ] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(actual)} spids: [47] ) (Redir op_id:Redir_Great fd:2 arg_word:{(err)} spids:[50]) ] ) (AndOr children: [ (SimpleCommand words: [{(echo)} {(DQ ($ VSub_Name "$path") (": test: ") ($ VSub_Number "$2"))}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(expect)} spids:[64])] ) (AndOr children: [ (C {(test_cmp)} {(expect)} {(actual)}) (C {(test_line_count)} {(Lit_Other "=")} {(0)} {(err)}) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [18] ) spids: [13 17] ) (C {(test_expect_success)} {(SQ <setup>)} { (SQ <"\n"> <"\tmkdir -p a/b/d a/c b &&\n"> <"\t(\n"> <"\t\techo \"[attr]notest !test\"\n"> <"\t\techo \"f\ttest=f\"\n"> <"\t\techo \"a/i test=a/i\"\n"> <"\t\techo \"onoff test -test\"\n"> <"\t\techo \"offon -test test\"\n"> <"\t\techo \"no notest\"\n"> <"\t\techo \"A/e/F test=A/e/F\"\n"> <"\t) >.gitattributes &&\n"> <"\t(\n"> <"\t\techo \"g test=a/g\" &&\n"> <"\t\techo \"b/g test=a/b/g\"\n"> <"\t) >a/.gitattributes &&\n"> <"\t(\n"> <"\t\techo \"h test=a/b/h\" &&\n"> <"\t\techo \"d/* test=a/b/d/*\"\n"> <"\t\techo \"d/yes notest\"\n"> <"\t) >a/b/.gitattributes &&\n"> <"\t(\n"> <"\t\techo \"global test=global\"\n"> <"\t) >\"$HOME\"/global-gitattributes &&\n"> <"\tcat <<-EOF >expect-all\n"> <"\tf: test: f\n"> <"\ta/f: test: f\n"> <"\ta/c/f: test: f\n"> <"\ta/g: test: a/g\n"> <"\ta/b/g: test: a/b/g\n"> <"\tb/g: test: unspecified\n"> <"\ta/b/h: test: a/b/h\n"> <"\ta/b/d/g: test: a/b/d/*\n"> <"\tonoff: test: unset\n"> <"\toffon: test: set\n"> <"\tno: notest: set\n"> <"\tno: test: unspecified\n"> <"\ta/b/d/no: notest: set\n"> <"\ta/b/d/no: test: a/b/d/*\n"> <"\ta/b/d/yes: notest: set\n"> <"\ta/b/d/yes: test: unspecified\n"> <"\tEOF\n"> ) } ) (C {(test_expect_success)} {(SQ <"command line checks">)} { (SQ <"\n"> <"\ttest_must_fail git check-attr &&\n"> <"\ttest_must_fail git check-attr -- &&\n"> <"\ttest_must_fail git check-attr test &&\n"> <"\ttest_must_fail git check-attr test -- &&\n"> <"\ttest_must_fail git check-attr -- f &&\n"> <"\techo \"f\" | test_must_fail git check-attr --stdin &&\n"> <"\techo \"f\" | test_must_fail git check-attr --stdin -- f &&\n"> <"\techo \"f\" | test_must_fail git check-attr --stdin test -- f &&\n"> <"\ttest_must_fail git check-attr \"\" -- f\n"> ) } ) (C {(test_expect_success)} {(SQ <"attribute test">)} { (SQ <"\n"> <"\tattr_check f f &&\n"> <"\tattr_check a/f f &&\n"> <"\tattr_check a/c/f f &&\n"> <"\tattr_check a/g a/g &&\n"> <"\tattr_check a/b/g a/b/g &&\n"> <"\tattr_check b/g unspecified &&\n"> <"\tattr_check a/b/h a/b/h &&\n"> <"\tattr_check a/b/d/g \"a/b/d/*\" &&\n"> <"\tattr_check onoff unset &&\n"> <"\tattr_check offon set &&\n"> <"\tattr_check no unspecified &&\n"> <"\tattr_check a/b/d/no \"a/b/d/*\" &&\n"> <"\tattr_check a/b/d/yes unspecified\n"> ) } ) (C {(test_expect_success)} {(SQ <"attribute matching is case sensitive when core.ignorecase=0">)} { (SQ <"\n"> <"\n"> <"\ttest_must_fail attr_check F f \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/F f \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/c/F f \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/G a/g \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/B/g a/b/g \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/b/G a/b/g \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/b/H a/b/h \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/b/D/g \"a/b/d/*\" \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check oNoFf unset \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check oFfOn set \"-c core.ignorecase=0\" &&\n"> <"\tattr_check NO unspecified \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/b/D/NO \"a/b/d/*\" \"-c core.ignorecase=0\" &&\n"> <"\tattr_check a/b/d/YES a/b/d/* \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check a/E/f \"A/e/F\" \"-c core.ignorecase=0\"\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"attribute matching is case insensitive when core.ignorecase=1">)} { (SQ <"\n"> <"\n"> <"\tattr_check F f \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/F f \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/c/F f \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/G a/g \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/B/g a/b/g \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/b/G a/b/g \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/b/H a/b/h \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/b/D/g \"a/b/d/*\" \"-c core.ignorecase=1\" &&\n"> <"\tattr_check oNoFf unset \"-c core.ignorecase=1\" &&\n"> <"\tattr_check oFfOn set \"-c core.ignorecase=1\" &&\n"> <"\tattr_check NO unspecified \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/b/D/NO \"a/b/d/*\" \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/b/d/YES unspecified \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/E/f \"A/e/F\" \"-c core.ignorecase=1\"\n"> <"\n"> ) } ) (C {(test_expect_success)} {(CASE_INSENSITIVE_FS)} {(SQ <"additional case insensitivity tests">)} { (SQ <"\n"> <"\ttest_must_fail attr_check a/B/D/g \"a/b/d/*\" \"-c core.ignorecase=0\" &&\n"> <"\ttest_must_fail attr_check A/B/D/NO \"a/b/d/*\" \"-c core.ignorecase=0\" &&\n"> <"\tattr_check A/b/h a/b/h \"-c core.ignorecase=1\" &&\n"> <"\tattr_check a/B/D/g \"a/b/d/*\" \"-c core.ignorecase=1\" &&\n"> <"\tattr_check A/B/D/NO \"a/b/d/*\" \"-c core.ignorecase=1\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"unnormalized paths">)} { (SQ <"\n"> <"\tattr_check ./f f &&\n"> <"\tattr_check ./a/g a/g &&\n"> <"\tattr_check a/./g a/g &&\n"> <"\tattr_check a/c/../b/g a/b/g\n"> ) } ) (C {(test_expect_success)} {(SQ <"relative paths">)} { (SQ <"\n"> <"\t(cd a && attr_check ../f f) &&\n"> <"\t(cd a && attr_check f f) &&\n"> <"\t(cd a && attr_check i a/i) &&\n"> <"\t(cd a && attr_check g a/g) &&\n"> <"\t(cd a && attr_check b/g a/b/g) &&\n"> <"\t(cd b && attr_check ../a/f f) &&\n"> <"\t(cd b && attr_check ../a/g a/g) &&\n"> <"\t(cd b && attr_check ../a/b/g a/b/g)\n"> ) } ) (C {(test_expect_success)} {(SQ <"prefixes are not confused with leading directories">)} { (SQ <"\n"> <"\tattr_check a_plus/g unspecified &&\n"> <"\tcat >expect <<-\\EOF &&\n"> <"\ta/g: test: a/g\n"> <"\ta_plus/g: test: unspecified\n"> <"\tEOF\n"> <"\tgit check-attr test a/g a_plus/g >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(SQ <core.attributesfile>)} { (SQ <"\n"> <"\tattr_check global unspecified &&\n"> <"\tgit config core.attributesfile \"$HOME/global-gitattributes\" &&\n"> <"\tattr_check global global &&\n"> <"\tgit config core.attributesfile \"~/global-gitattributes\" &&\n"> <"\tattr_check global global &&\n"> <"\techo \"global test=precedence\" >>.gitattributes &&\n"> <"\tattr_check global precedence\n"> ) } ) (C {(test_expect_success)} {(SQ <"attribute test: read paths from stdin">)} { (SQ <"\n"> <"\tgrep -v notest <expect-all >expect &&\n"> <"\tsed -e \"s/:.*//\" <expect | git check-attr --stdin test >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(SQ <"attribute test: --all option">)} { (SQ <"\n"> <"\tgrep -v unspecified <expect-all | sort >specified-all &&\n"> <"\tsed -e \"s/:.*//\" <expect-all | uniq >stdin-all &&\n"> <"\tgit check-attr --stdin --all <stdin-all | sort >actual &&\n"> <"\ttest_cmp specified-all actual\n"> ) } ) (C {(test_expect_success)} {(SQ <"attribute test: --cached option">)} { (SQ <"\n"> <"\t: >empty &&\n"> <"\tgit check-attr --cached --stdin --all <stdin-all | sort >actual &&\n"> <"\ttest_cmp empty actual &&\n"> <"\tgit add .gitattributes a/.gitattributes a/b/.gitattributes &&\n"> <"\tgit check-attr --cached --stdin --all <stdin-all | sort >actual &&\n"> <"\ttest_cmp specified-all actual\n"> ) } ) (C {(test_expect_success)} {(SQ <"root subdir attribute test">)} {(SQ <"\n"> <"\tattr_check a/i a/i &&\n"> <"\tattr_check subdir/a/i unspecified\n">)} ) (C {(test_expect_success)} {(SQ <"negative patterns">)} {(SQ <"\n"> <"\techo \"!f test=bar\" >.gitattributes &&\n"> <"\tgit check-attr test -- ">) (DQ ("'")) (SQ <"!f">) (DQ ("'")) (SQ <" 2>errors &&\n"> <"\ttest_i18ngrep \"Negative patterns are ignored\" errors\n">) } ) (C {(test_expect_success)} {(SQ <"patterns starting with exclamation">)} {(SQ <"\n"> <"\techo \"\\!f test=foo\" >.gitattributes &&\n"> <"\tattr_check \"!f\" foo\n">)} ) (C {(test_expect_success)} {(SQ <"\"**\" test">)} { (SQ <"\n"> <"\techo \"**/f foo=bar\" >.gitattributes &&\n"> <"\tcat <<\\EOF >expect &&\n"> <"f: foo: bar\n"> <"a/f: foo: bar\n"> <"a/b/f: foo: bar\n"> <"a/b/c/f: foo: bar\n"> <"EOF\n"> <"\tgit check-attr foo -- \"f\" >actual 2>err &&\n"> <"\tgit check-attr foo -- \"a/f\" >>actual 2>>err &&\n"> <"\tgit check-attr foo -- \"a/b/f\" >>actual 2>>err &&\n"> <"\tgit check-attr foo -- \"a/b/c/f\" >>actual 2>>err &&\n"> <"\ttest_cmp expect actual &&\n"> <"\ttest_line_count = 0 err\n"> ) } ) (C {(test_expect_success)} {(SQ <"\"**\" with no slashes test">)} { (SQ <"\n"> <"\techo \"a**f foo=bar\" >.gitattributes &&\n"> <"\tgit check-attr foo -- \"f\" >actual &&\n"> <"\tcat <<\\EOF >expect &&\n"> <"f: foo: unspecified\n"> <"af: foo: bar\n"> <"axf: foo: bar\n"> <"a/f: foo: unspecified\n"> <"a/b/f: foo: unspecified\n"> <"a/b/c/f: foo: unspecified\n"> <"EOF\n"> <"\tgit check-attr foo -- \"f\" >actual 2>err &&\n"> <"\tgit check-attr foo -- \"af\" >>actual 2>err &&\n"> <"\tgit check-attr foo -- \"axf\" >>actual 2>err &&\n"> <"\tgit check-attr foo -- \"a/f\" >>actual 2>>err &&\n"> <"\tgit check-attr foo -- \"a/b/f\" >>actual 2>>err &&\n"> <"\tgit check-attr foo -- \"a/b/c/f\" >>actual 2>>err &&\n"> <"\ttest_cmp expect actual &&\n"> <"\ttest_line_count = 0 err\n"> ) } ) (C {(test_expect_success)} {(SQ <"using --git-dir and --work-tree">)} { (SQ <"\n"> <"\tmkdir unreal real &&\n"> <"\tgit init real &&\n"> <"\techo \"file test=in-real\" >real/.gitattributes &&\n"> <"\t(\n"> <"\t\tcd unreal &&\n"> <"\t\tattr_check file in-real \"--git-dir ../real/.git --work-tree ../real\"\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"setup bare">)} {(SQ <"\n"> <"\tgit clone --bare . bare.git\n">)}) (C {(test_expect_success)} {(SQ <"bare repository: check that .gitattribute is ignored">)} { (SQ <"\n"> <"\t(\n"> <"\t\tcd bare.git &&\n"> <"\t\t(\n"> <"\t\t\techo \"f\ttest=f\"\n"> <"\t\t\techo \"a/i test=a/i\"\n"> <"\t\t) >.gitattributes &&\n"> <"\t\tattr_check f unspecified &&\n"> <"\t\tattr_check a/f unspecified &&\n"> <"\t\tattr_check a/c/f unspecified &&\n"> <"\t\tattr_check a/i unspecified &&\n"> <"\t\tattr_check subdir/a/i unspecified\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"bare repository: check that --cached honors index">)} { (SQ <"\n"> <"\t(\n"> <"\t\tcd bare.git &&\n"> <"\t\tGIT_INDEX_FILE=../.git/index \\\n"> <"\t\tgit check-attr --cached --stdin --all <../stdin-all |\n"> <"\t\tsort >actual &&\n"> <"\t\ttest_cmp ../specified-all actual\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"bare repository: test info/attributes">)} { (SQ <"\n"> <"\t(\n"> <"\t\tcd bare.git &&\n"> <"\t\t(\n"> <"\t\t\techo \"f\ttest=f\"\n"> <"\t\t\techo \"a/i test=a/i\"\n"> <"\t\t) >info/attributes &&\n"> <"\t\tattr_check f f &&\n"> <"\t\tattr_check a/f f &&\n"> <"\t\tattr_check a/c/f f &&\n"> <"\t\tattr_check a/i a/i &&\n"> <"\t\tattr_check subdir/a/i unspecified\n"> <"\t)\n"> ) } ) (C {(test_done)}) ] )