(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: { (DQ <'Test whether cache-tree is properly updated\n'> <'\n'> <'Tests whether various commands properly update and/or rewrite the\n'> <'cache-tree extension.\n'> ) } spids: [4] ) ] ) (C {<.>} {<'./test-lib.sh'>}) (command.ShFunction name: cmp_cache_tree body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp] children: [ (command.Pipeline children: [ (C {<test-dump-cache-tree>}) (command.Simple words: [{<sed>} {<-e>} {(SQ <'/#(ref)/d'>)}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<actual>} ) ] do_fork: T ) ] negated: F ) (command.Simple words: [{<sed>} {(DQ <'s/'> ($ Id.VSub_DollarName '$_x40') <'/SHA/'>)}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {<actual>} ) (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<filtered>} ) ] do_fork: T ) (C {<test_cmp>} {(DQ ($ Id.VSub_Number '$1'))} {<filtered>}) ] ) ] ) ) (command.ShFunction name: generate_expected_cache_tree_rec body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:dir) op: assign_op.Equal rhs: { (DQ ($ Id.VSub_Number '$1') (braced_var_sub token: <Id.VSub_Number 1> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonPlus arg_word: {<Id.Lit_Slash '/'>} ) ) ) } spids: [89] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:parent) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_Number '$2'))} spids: [102] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:subtrees) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [ (C {<git>} {<ls-files>}) (C {<grep>} {<'/'>}) (C {<cut>} {<-d>} {<'/'>} {<-f>} {<1>}) (C {<uniq>}) ] negated: F ) ) } spids: [118] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:subtree_count) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [ (C {<echo>} {(DQ ($ Id.VSub_DollarName '$subtrees'))}) (C {<awk>} {<-v>} {<Id.Lit_VarLike 'c='> <0>} {(SQ <'$1 != "" {++c} END {print c}'>)} ) ] negated: F ) ) } spids: [144] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:entries) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [(C {<git>} {<ls-files>}) (C {<wc>} {<-l>})] negated: F ) ) } spids: [167] ) ] ) (C {<printf>} { (DQ <'SHA '> ($ Id.VSub_DollarName '$dir') <' (%d entries, %d subtrees)'> <Id.Lit_Other '\\'> <n> ) } {(DQ ($ Id.VSub_DollarName '$entries'))} {(DQ ($ Id.VSub_DollarName '$subtree_count'))} ) (command.ForEach iter_name: subtree iter_words: [{($ Id.VSub_DollarName '$subtrees')}] do_arg_iter: F body: (command.DoGroup children: [ (C {<cd>} {(DQ ($ Id.VSub_DollarName '$subtree'))}) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<generate_expected_cache_tree_rec>} {(DQ ($ Id.VSub_DollarName '$dir') ($ Id.VSub_DollarName '$subtree'))} {(DQ ($ Id.VSub_DollarName '$dir'))} ) (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<1>} ) ] ) (C {<cd>} {<..>}) ] ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:dir) op: assign_op.Equal rhs: {($ Id.VSub_DollarName '$parent')} spids: [249] ) ] ) ] ) ] ) ) (command.ShFunction name: generate_expected_cache_tree body: (BraceGroup children:[(command.Subshell child:(C {<generate_expected_cache_tree_rec>}))]) ) (command.ShFunction name: test_cache_tree body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [{<generate_expected_cache_tree>}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>})] do_fork: T ) (C {<cmp_cache_tree>} {<expect>}) ] ) ] ) ) (command.ShFunction name: test_invalid_cache_tree body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp] children: [ (command.Simple words: [ {<printf>} {(DQ <'invalid %s ()'> <Id.Lit_Other '\\'> <n>)} {(DQ )} {(DQ ($ Id.VSub_At '$@'))} ] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>})] do_fork: T ) (command.Pipeline children: [ (C {<test-dump-cache-tree>}) (command.Simple words: [ {<sed>} {<-n>} {<-e>} {(DQ <'s/[0-9]* subtrees//'>)} {<-e>} {(SQ <'/#(ref)/d'>)} {<-e>} {(SQ <'/^invalid /p'>)} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<actual>} ) ] do_fork: T ) ] negated: F ) (C {<test_cmp>} {<expect>} {<actual>}) ] ) ] ) ) (command.ShFunction name: test_no_cache_tree body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [{<Id.Lit_Colon ':'>}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>})] do_fork: T ) (C {<cmp_cache_tree>} {<expect>}) ] ) ] ) ) (C {<test_expect_success>} {(SQ <'initial commit has cache-tree'>)} {(SQ <'\n'> <'\ttest_commit foo &&\n'> <'\ttest_cache_tree\n'>)} ) (C {<test_expect_success>} {(SQ <'read-tree HEAD establishes cache-tree'>)} {(SQ <'\n'> <'\tgit read-tree HEAD &&\n'> <'\ttest_cache_tree\n'>)} ) (C {<test_expect_success>} {(SQ <'git-add invalidates cache-tree'>)} { (SQ <'\n'> <'\ttest_when_finished "git reset --hard; git read-tree HEAD" &&\n'> <'\techo "I changed this file" >foo &&\n'> <'\tgit add foo &&\n'> <'\ttest_invalid_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'git-add in subdir invalidates cache-tree'>)} { (SQ <'\n'> <'\ttest_when_finished "git reset --hard; git read-tree HEAD" &&\n'> <'\tmkdir dirx &&\n'> <'\techo "I changed this file" >dirx/foo &&\n'> <'\tgit add dirx/foo &&\n'> <'\ttest_invalid_cache_tree\n'> ) } ) (command.Simple words: [{<cat>}] redirects: [ (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<before>}) (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: 460 stdin_parts: [ <'SHA (3 entries, 2 subtrees)\n'> <'SHA dir1/ (1 entries, 0 subtrees)\n'> <'SHA dir2/ (1 entries, 0 subtrees)\n'> ] ) ) ] do_fork: T ) (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: {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\E'>) <OF>} here_end_span_id: 474 stdin_parts: [ <'invalid (2 subtrees)\n'> <'invalid dir1/ (0 subtrees)\n'> <'SHA dir2/ (1 entries, 0 subtrees)\n'> ] ) ) ] do_fork: T ) (C {<test_expect_success>} {(SQ <'git-add in subdir does not invalidate sibling cache-tree'>)} { (SQ <'\n'> <'\tgit tag no-children &&\n'> <'\ttest_when_finished "git reset --hard no-children; git read-tree HEAD" &&\n'> <'\tmkdir dir1 dir2 &&\n'> <'\ttest_commit dir1/a &&\n'> <'\ttest_commit dir2/b &&\n'> <'\techo "I changed this file" >dir1/a &&\n'> <'\tcmp_cache_tree before &&\n'> <'\techo "I changed this file" >dir1/a &&\n'> <'\tgit add dir1/a &&\n'> <'\tcmp_cache_tree expect\n'> ) } ) (C {<test_expect_success>} {(SQ <'update-index invalidates cache-tree'>)} { (SQ <'\n'> <'\ttest_when_finished "git reset --hard; git read-tree HEAD" &&\n'> <'\techo "I changed this file" >foo &&\n'> <'\tgit update-index --add foo &&\n'> <'\ttest_invalid_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'write-tree establishes cache-tree'>)} {(SQ <'\n'> <'\ttest-scrap-cache-tree &&\n'> <'\tgit write-tree &&\n'> <'\ttest_cache_tree\n'>)} ) (C {<test_expect_success>} {(SQ <'test-scrap-cache-tree works'>)} { (SQ <'\n'> <'\tgit read-tree HEAD &&\n'> <'\ttest-scrap-cache-tree &&\n'> <'\ttest_no_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'second commit has cache-tree'>)} {(SQ <'\n'> <'\ttest_commit bar &&\n'> <'\ttest_cache_tree\n'>)} ) (C {<test_expect_success>} {<PERL>} {(SQ <'commit --interactive gives cache-tree on partial commit'>)} { (SQ <'\n'> <'\tcat <<-\\EOT >foo.c &&\n'> <'\tint foo()\n'> <'\t{\n'> <'\t\treturn 42;\n'> <'\t}\n'> <'\tint bar()\n'> <'\t{\n'> <'\t\treturn 42;\n'> <'\t}\n'> <'\tEOT\n'> <'\tgit add foo.c &&\n'> <'\ttest_invalid_cache_tree &&\n'> <'\tgit commit -m "add a file" &&\n'> <'\ttest_cache_tree &&\n'> <'\tcat <<-\\EOT >foo.c &&\n'> <'\tint foo()\n'> <'\t{\n'> <'\t\treturn 43;\n'> <'\t}\n'> <'\tint bar()\n'> <'\t{\n'> <'\t\treturn 44;\n'> <'\t}\n'> <'\tEOT\n'> <'\t(echo p; echo 1; echo; echo s; echo n; echo y; echo q) |\n'> <'\tgit commit --interactive -m foo &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'commit in child dir has cache-tree'>)} { (SQ <'\n'> <'\tmkdir dir &&\n'> <'\t>dir/child.t &&\n'> <'\tgit add dir/child.t &&\n'> <'\tgit commit -m dir/child.t &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'reset --hard gives cache-tree'>)} { (SQ <'\n'> <'\ttest-scrap-cache-tree &&\n'> <'\tgit reset --hard &&\n'> <'\ttest_cache_tree\n'>) } ) (C {<test_expect_success>} {(SQ <'reset --hard without index gives cache-tree'>)} {(SQ <'\n'> <'\trm -f .git/index &&\n'> <'\tgit reset --hard &&\n'> <'\ttest_cache_tree\n'>)} ) (C {<test_expect_success>} {(SQ <'checkout gives cache-tree'>)} {(SQ <'\n'> <'\tgit tag current &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\ttest_cache_tree\n'>)} ) (C {<test_expect_success>} {(SQ <'checkout -b gives cache-tree'>)} { (SQ <'\n'> <'\tgit checkout current &&\n'> <'\tgit checkout -b prev HEAD^ &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'checkout -B gives cache-tree'>)} { (SQ <'\n'> <'\tgit checkout current &&\n'> <'\tgit checkout -B prev HEAD^ &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'merge --ff-only maintains cache-tree'>)} { (SQ <'\n'> <'\tgit checkout current &&\n'> <'\tgit checkout -b changes &&\n'> <'\ttest_commit llamas &&\n'> <'\ttest_commit pachyderm &&\n'> <'\ttest_cache_tree &&\n'> <'\tgit checkout current &&\n'> <'\ttest_cache_tree &&\n'> <'\tgit merge --ff-only changes &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'merge maintains cache-tree'>)} { (SQ <'\n'> <'\tgit checkout current &&\n'> <'\tgit checkout -b changes2 &&\n'> <'\ttest_commit alpacas &&\n'> <'\ttest_cache_tree &&\n'> <'\tgit checkout current &&\n'> <'\ttest_commit struthio &&\n'> <'\ttest_cache_tree &&\n'> <'\tgit merge changes2 &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'partial commit gives cache-tree'>)} { (SQ <'\n'> <'\tgit checkout -b partial no-children &&\n'> <'\ttest_commit one &&\n'> <'\ttest_commit two &&\n'> <'\techo "some change" >one.t &&\n'> <'\tgit add one.t &&\n'> <'\techo "some other change" >two.t &&\n'> <'\tgit commit two.t -m partial &&\n'> <'\ttest_cache_tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'no phantom error when switching trees'>)} { (SQ <'\n'> <'\tmkdir newdir &&\n'> <'\t>newdir/one &&\n'> <'\tgit add newdir/one &&\n'> <'\tgit checkout 2>errors &&\n'> <'\t! test -s errors\n'> ) } ) (C {<test_expect_success>} {(SQ <'switching trees does not invalidate shared index'>)} { (SQ <'\n'> <'\tgit update-index --split-index &&\n'> <'\t>split &&\n'> <'\tgit add split &&\n'> <'\ttest-dump-split-index .git/index | grep -v ^own >before &&\n'> <'\tgit commit -m "as-is" &&\n'> <'\ttest-dump-split-index .git/index | grep -v ^own >after &&\n'> <'\ttest_cmp before after\n'> ) } ) (C {<test_done>}) ] )