(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: { (SQ <'git ls-files --others --exclude\n'> <'\n'> <'This test runs git ls-files --others and tests --exclude patterns.\n'> ) } spids: [13] ) ] ) (C {<.>} {<'./test-lib.sh'>}) (C {<rm>} {<-fr>} {<one>} {<three>}) (command.ForEach iter_name: dir iter_words: [{<.>} {<one>} {<'one/two'>} {<three>}] do_arg_iter: F body: (command.DoGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<mkdir>} {<-p>} {($ Id.VSub_DollarName '$dir')}) (command.ForEach iter_name: i iter_words: [{<1>} {<2>} {<3>} {<4>} {<5>} {<6>} {<7>} {<8>}] do_arg_iter: F body: (command.DoGroup children: [ (command.Simple redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {($ Id.VSub_DollarName '$dir') <'/a.'> ($ Id.VSub_DollarName '$i')} ) ] do_fork: F ) ] ) ) ] ) ] ) ) (command.Simple redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{(DQ <'#ignore1'>)})] do_fork: F ) (command.Simple redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{(DQ <'#ignore2'>)})] do_fork: F ) (command.Simple redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{(DQ <'#hidden'>)})] do_fork: F ) (command.Simple words: [{<cat>}] redirects: [ (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>}) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine here_begin: {<EOF>} here_end_span_id: 139 stdin_parts: [ <'a.2\n'> <'a.4\n'> <'a.5\n'> <'a.8\n'> <'one/a.3\n'> <'one/a.4\n'> <'one/a.5\n'> <'one/a.7\n'> <'one/two/a.2\n'> <'one/two/a.3\n'> <'one/two/a.5\n'> <'one/two/a.7\n'> <'one/two/a.8\n'> <'three/a.2\n'> <'three/a.3\n'> <'three/a.4\n'> <'three/a.5\n'> <'three/a.8\n'> ] ) ) ] do_fork: T ) (command.Simple words: [ {<echo>} { (SQ <'.gitignore\n'> <'\\#ignore1\n'> <'\\#ignore2*\n'> <'\\#hid*n\n'> <'output\n'> <'expect\n'> <'.gitignore\n'> <'*.7\n'> <'!*.8'> ) } ] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<'.git/ignore'>})] do_fork: T ) (command.Simple words: [{<echo>} {(SQ <'*.1\n'> <'/*.3\n'> <'!*.6'>)}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<.gitignore>})] do_fork: T ) (command.Simple words: [{<echo>} {(SQ <'*.2\n'> <'two/*.4\n'> <'!*.7\n'> <'*.8'>)}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<'one/.gitignore'>})] do_fork: T ) (command.Simple words: [{<echo>} {(SQ <'!*.2\n'> <'!*.8'>)}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<'one/two/.gitignore'>})] do_fork: T ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:allignores) op: assign_op.Equal rhs: {(SQ <'.gitignore one/.gitignore one/two/.gitignore'>)} spids: [193] ) ] ) (C {<test_expect_success>} {(SQ <'git ls-files --others with various exclude options.'>)} { (SQ <'git ls-files --others \\\n'> <' --exclude=\\*.6 \\\n'> <' --exclude-per-directory=.gitignore \\\n'> <' --exclude-from=.git/ignore \\\n'> <' >output &&\n'> <' test_cmp expect output'> ) } ) (command.Simple words: [{<printf>} {(SQ <'*.1\\r\\n/*.3\\r\\n!*.6\\r\\n'>)}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<.gitignore>})] do_fork: T ) (C {<test_expect_success>} {(SQ <'git ls-files --others with \\r\\n line endings.'>)} { (SQ <'git ls-files --others \\\n'> <' --exclude=\\*.6 \\\n'> <' --exclude-per-directory=.gitignore \\\n'> <' --exclude-from=.git/ignore \\\n'> <' >output &&\n'> <' test_cmp expect output'> ) } ) (C {<test_expect_success>} {(SQ <'setup skip-worktree gitignore'>)} { (SQ <'\n'> <'\tgit add $allignores &&\n'> <'\tgit update-index --skip-worktree $allignores &&\n'> <'\trm $allignores\n'> ) } ) (C {<test_expect_success>} {(SQ <'git ls-files --others with various exclude options.'>)} { (SQ <'git ls-files --others \\\n'> <' --exclude=\\*.6 \\\n'> <' --exclude-per-directory=.gitignore \\\n'> <' --exclude-from=.git/ignore \\\n'> <' >output &&\n'> <' test_cmp expect output'> ) } ) (C {<test_expect_success>} {(SQ <'restore gitignore'>)} { (SQ <'\n'> <'\tgit checkout --ignore-skip-worktree-bits $allignores &&\n'> <'\trm .git/index\n'> ) } ) (command.Simple words: [{<cat>}] redirects: [ (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<excludes-file>}) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine here_begin: {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\E'>) <OF>} here_end_span_id: 312 stdin_parts: [<'*.[1-8]\n'> <'e*\n'> <'\\#*\n'>] ) ) ] do_fork: T ) (C {<git>} {<config>} {<core.excludesFile>} {<excludes-file>}) (command.Pipeline children: [ (C {<git>} {<-c>} {<status.displayCommentPrefix> <Id.Lit_Equals '='> <true>} {<status>}) (command.Simple words: [{<grep>} {(DQ <'^#\t'>)}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<output>})] do_fork: T ) ] negated: F ) (command.Simple words: [{<cat>}] redirects: [ (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>}) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine here_begin: {<EOF>} here_end_span_id: 362 stdin_parts: [ <'#\t.gitignore\n'> <'#\ta.6\n'> <'#\tone/\n'> <'#\toutput\n'> <'#\tthree/\n'> ] ) ) ] do_fork: T ) (C {<test_expect_success>} {(SQ <'git status honors core.excludesfile'>)} {(SQ <'test_cmp expect output'>)} ) (C {<test_expect_success>} {(SQ <'trailing slash in exclude allows directory match(1)'>)} { (SQ <'\n'> <'\n'> <'\tgit ls-files --others --exclude=one/ >output &&\n'> <'\tif grep "^one/" output\n'> <'\tthen\n'> <'\t\techo Ooops\n'> <'\t\tfalse\n'> <'\telse\n'> <'\t\t: happy\n'> <'\tfi\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'trailing slash in exclude allows directory match (2)'>)} { (SQ <'\n'> <'\n'> <'\tgit ls-files --others --exclude=one/two/ >output &&\n'> <'\tif grep "^one/two/" output\n'> <'\tthen\n'> <'\t\techo Ooops\n'> <'\t\tfalse\n'> <'\telse\n'> <'\t\t: happy\n'> <'\tfi\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'trailing slash in exclude forces directory match (1)'>)} { (SQ <'\n'> <'\n'> <'\t>two &&\n'> <'\tgit ls-files --others --exclude=two/ >output &&\n'> <'\tgrep "^two" output\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'trailing slash in exclude forces directory match (2)'>)} { (SQ <'\n'> <'\n'> <'\tgit ls-files --others --exclude=one/a.1/ >output &&\n'> <'\tgrep "^one/a.1" output\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'negated exclude matches can override previous ones'>)} { (SQ <'\n'> <'\n'> <'\tgit ls-files --others --exclude="a.*" --exclude="!a.1" >output &&\n'> <'\tgrep "^a.1" output\n'> ) } ) (C {<test_expect_success>} {(SQ <'excluded directory overrides content patterns'>)} { (SQ <'\n'> <'\n'> <'\tgit ls-files --others --exclude="one" --exclude="!one/a.1" >output &&\n'> <'\tif grep "^one/a.1" output\n'> <'\tthen\n'> <'\t\tfalse\n'> <'\tfi\n'> ) } ) (C {<test_expect_success>} {(SQ <'negated directory doesn'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'t affect content patterns'>) } { (SQ <'\n'> <'\n'> <'\tgit ls-files --others --exclude="!one" --exclude="one/a.1" >output &&\n'> <'\tif grep "^one/a.1" output\n'> <'\tthen\n'> <'\t\tfalse\n'> <'\tfi\n'> ) } ) (C {<test_expect_success>} {(SQ <'subdirectory ignore (setup)'>)} { (SQ <'\n'> <'\tmkdir -p top/l1/l2 &&\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit init &&\n'> <'\t\techo /.gitignore >.gitignore &&\n'> <'\t\techo l1 >>.gitignore &&\n'> <'\t\techo l2 >l1/.gitignore &&\n'> <'\t\t>l1/l2/l1\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'subdirectory ignore (toplevel)'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit ls-files -o --exclude-standard\n'> <'\t) >actual &&\n'> <'\t>expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'subdirectory ignore (l1/l2)'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top/l1/l2 &&\n'> <'\t\tgit ls-files -o --exclude-standard\n'> <'\t) >actual &&\n'> <'\t>expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'subdirectory ignore (l1)'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top/l1 &&\n'> <'\t\tgit ls-files -o --exclude-standard\n'> <'\t) >actual &&\n'> <'\t>expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'show/hide empty ignored directory (setup)'>)} {(SQ <'\n'> <'\trm top/l1/l2/l1 &&\n'> <'\trm top/l1/.gitignore\n'>)} ) (C {<test_expect_success>} {(SQ <'show empty ignored directory with --directory'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit ls-files -o -i --exclude l1 --directory\n'> <'\t) >actual &&\n'> <'\techo l1/ >expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'hide empty ignored directory with --no-empty-directory'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit ls-files -o -i --exclude l1 --directory --no-empty-directory\n'> <'\t) >actual &&\n'> <'\t>expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'show/hide empty ignored sub-directory (setup)'>)} { (SQ <'\n'> <'\t> top/l1/tracked &&\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit add -f l1/tracked\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'show empty ignored sub-directory with --directory'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit ls-files -o -i --exclude l1 --directory\n'> <'\t) >actual &&\n'> <'\techo l1/l2/ >expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'hide empty ignored sub-directory with --no-empty-directory'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tcd top &&\n'> <'\t\tgit ls-files -o -i --exclude l1 --directory --no-empty-directory\n'> <'\t) >actual &&\n'> <'\t>expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'pattern matches prefix completely'>)} { (SQ <'\n'> <'\t: >expect &&\n'> <'\tgit ls-files -i -o --exclude "/three/a.3[abc]" >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'ls-files with "**" patterns'>)} { (SQ <'\n'> <'\tcat <<\\EOF >expect &&\n'> <'a.1\n'> <'one/a.1\n'> <'one/two/a.1\n'> <'three/a.1\n'> <'EOF\n'> <'\tgit ls-files -o -i --exclude "**/a.1" >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'ls-files with "**" patterns and no slashes'>)} { (SQ <'\n'> <'\t: >expect &&\n'> <'\tgit ls-files -o -i --exclude "one**a.1" >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_done>}) ] )