(CommandList
  children: [
    (Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (LhsName name:test_description)
          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]
        )
      ]
      spids: [4]
    )
    (C {(.)} {(./test-lib.sh)})
    (FuncDef
      name: cmp_cache_tree
      body: 
        (BraceGroup
          children: [
            (AndOr
              children: [
                (Pipeline
                  children: [
                    (C {(test-dump-cache-tree)})
                    (SimpleCommand
                      words: [{(sed)} {(-e)} {(SQ <"/#(ref)/d">)}]
                      redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(actual)} spids:[38])]
                    )
                  ]
                  negated: False
                )
                (AndOr
                  children: [
                    (SimpleCommand
                      words: [{(sed)} {(DQ (s/) ($ VSub_Name "$_x40") (/SHA/))}]
                      redirects: [
                        (Redir
                          op_id: Redir_Less
                          fd: -1
                          arg_word: {(actual)}
                          spids: [52]
                        )
                        (Redir
                          op_id: Redir_Great
                          fd: -1
                          arg_word: {(filtered)}
                          spids: [55]
                        )
                      ]
                    )
                    (C {(test_cmp)} {(DQ ($ VSub_Number "$1"))} {(filtered)})
                  ]
                  op_id: Op_DAmp
                )
              ]
              op_id: Op_DAmp
            )
          ]
          spids: [23]
        )
      spids: [18 22]
    )
    (FuncDef
      name: generate_expected_cache_tree_rec
      body: 
        (BraceGroup
          children: [
            (AndOr
              children: [
                (Assignment
                  keyword: Assign_None
                  pairs: [
                    (assign_pair
                      lhs: (LhsName name:dir)
                      op: Equal
                      rhs: 
                        {
                          (DQ ($ VSub_Number "$1") 
                            (BracedVarSub
                              token: <VSub_Number 1>
                              suffix_op: (StringUnary op_id:VTest_ColonPlus arg_word:{(Lit_Slash /)})
                              spids: [92 96]
                            )
                          )
                        }
                      spids: [89]
                    )
                  ]
                  spids: [89]
                )
                (AndOr
                  children: [
                    (Assignment
                      keyword: Assign_None
                      pairs: [
                        (assign_pair
                          lhs: (LhsName name:parent)
                          op: Equal
                          rhs: {(DQ ($ VSub_Number "$2"))}
                          spids: [102]
                        )
                      ]
                      spids: [102]
                    )
                    (AndOr
                      children: [
                        (Assignment
                          keyword: Assign_None
                          pairs: [
                            (assign_pair
                              lhs: (LhsName name:subtrees)
                              op: Equal
                              rhs: 
                                {
                                  (CommandSubPart
                                    command_list: 
                                      (CommandList
                                        children: [
                                          (Pipeline
                                            children: [
                                              (C {(git)} {(ls-files)})
                                              (C {(grep)} {(/)})
                                              (C {(cut)} {(-d)} {(/)} {(-f)} {(1)})
                                              (C {(uniq)})
                                            ]
                                            negated: False
                                          )
                                        ]
                                      )
                                    left_token: <Left_CommandSub "$(">
                                    spids: [119 139]
                                  )
                                }
                              spids: [118]
                            )
                          ]
                          spids: [118]
                        )
                        (AndOr
                          children: [
                            (Assignment
                              keyword: Assign_None
                              pairs: [
                                (assign_pair
                                  lhs: (LhsName name:subtree_count)
                                  op: Equal
                                  rhs: 
                                    {
                                      (CommandSubPart
                                        command_list: 
                                          (CommandList
                                            children: [
                                              (Pipeline
                                                children: [
                                                  (C {(echo)} {(DQ ($ VSub_Name "$subtrees"))})
                                                  (C {(awk)} {(-v)} {(Lit_VarLike "c=") (0)} 
                                                    {(SQ <"$1 != \"\" {++c} END {print c}">)}
                                                  )
                                                ]
                                                negated: False
                                              )
                                            ]
                                          )
                                        left_token: <Left_CommandSub "$(">
                                        spids: [145 162]
                                      )
                                    }
                                  spids: [144]
                                )
                              ]
                              spids: [144]
                            )
                            (AndOr
                              children: [
                                (Assignment
                                  keyword: Assign_None
                                  pairs: [
                                    (assign_pair
                                      lhs: (LhsName name:entries)
                                      op: Equal
                                      rhs: 
                                        {
                                          (CommandSubPart
                                            command_list: 
                                              (CommandList
                                                children: [
                                                  (Pipeline
                                                    children: [
                                                      (C {(git)} {(ls-files)})
                                                      (C {(wc)} {(-l)})
                                                    ]
                                                    negated: False
                                                  )
                                                ]
                                              )
                                            left_token: <Left_CommandSub "$(">
                                            spids: [168 176]
                                          )
                                        }
                                      spids: [167]
                                    )
                                  ]
                                  spids: [167]
                                )
                                (AndOr
                                  children: [
                                    (C {(printf)} 
                                      {
                                        (DQ ("SHA ") ($ VSub_Name "$dir") 
                                          (" (%d entries, %d subtrees)") (EscapedLiteralPart token:<Lit_EscapedChar "\\n">)
                                        )
                                      } {(DQ ($ VSub_Name "$entries"))} {(DQ ($ VSub_Name "$subtree_count"))}
                                    )
                                    (AndOr
                                      children: [
                                        (ForEach
                                          iter_name: subtree
                                          iter_words: [{($ VSub_Name "$subtrees")}]
                                          do_arg_iter: False
                                          body: 
                                            (DoGroup
                                              children: [
                                                (C {(cd)} {(DQ ($ VSub_Name "$subtree"))})
                                                (AndOr
                                                  children: [
                                                    (C {(generate_expected_cache_tree_rec)} 
                                                      {
                                                        (DQ ($ VSub_Name "$dir") 
                                                          ($ VSub_Name "$subtree")
                                                        )
                                                      } {(DQ ($ VSub_Name "$dir"))}
                                                    )
                                                    (ControlFlow
                                                      token: <ControlFlow_Return return>
                                                      arg_word: {(1)}
                                                    )
                                                  ]
                                                  op_id: Op_DPipe
                                                )
                                                (C {(cd)} {(..)})
                                              ]
                                              spids: [210 243]
                                            )
                                          spids: [206 -1]
                                        )
                                        (Assignment
                                          keyword: Assign_None
                                          pairs: [
                                            (assign_pair
                                              lhs: (LhsName name:dir)
                                              op: Equal
                                              rhs: {($ VSub_Name "$parent")}
                                              spids: [248]
                                            )
                                          ]
                                          spids: [248]
                                        )
                                      ]
                                      op_id: Op_DAmp
                                    )
                                  ]
                                  op_id: Op_DAmp
                                )
                              ]
                              op_id: Op_DAmp
                            )
                          ]
                          op_id: Op_DAmp
                        )
                      ]
                      op_id: Op_DAmp
                    )
                  ]
                  op_id: Op_DAmp
                )
              ]
              op_id: Op_DAmp
            )
          ]
          spids: [86]
        )
      spids: [81 85]
    )
    (FuncDef
      name: generate_expected_cache_tree
      body: 
        (BraceGroup
          children: [(Subshell child:(C {(generate_expected_cache_tree_rec)}) spids:[262268])]
          spids: [259]
        )
      spids: [254 258]
    )
    (FuncDef
      name: test_cache_tree
      body: 
        (BraceGroup
          children: [
            (AndOr
              children: [
                (SimpleCommand
                  words: [{(generate_expected_cache_tree)}]
                  redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(expect)} spids:[283])]
                )
                (C {(cmp_cache_tree)} {(expect)})
              ]
              op_id: Op_DAmp
            )
          ]
          spids: [278]
        )
      spids: [273 277]
    )
    (FuncDef
      name: test_invalid_cache_tree
      body: 
        (BraceGroup
          children: [
            (AndOr
              children: [
                (SimpleCommand
                  words: [
                    {(printf)}
                    {
                      (DQ ("invalid                                  %s ()") 
                        (EscapedLiteralPart token:<Lit_EscapedChar "\\n">)
                      )
                    }
                    {(DQ )}
                    {(DQ ($ VSub_At "$@"))}
                  ]
                  redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(expect)} spids:[318])]
                )
                (AndOr
                  children: [
                    (Pipeline
                      children: [
                        (C {(test-dump-cache-tree)})
                        (SimpleCommand
                          words: [
                            {(sed)}
                            {(-n)}
                            {(-e)}
                            {(DQ ("s/[0-9]* subtrees//"))}
                            {(-e)}
                            {(SQ <"/#(ref)/d">)}
                            {(-e)}
                            {(SQ <"/^invalid /p">)}
                          ]
                          redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(actual)} spids:[351])]
                        )
                      ]
                      negated: False
                    )
                    (C {(test_cmp)} {(expect)} {(actual)})
                  ]
                  op_id: Op_DAmp
                )
              ]
              op_id: Op_DAmp
            )
          ]
          spids: [301]
        )
      spids: [296 300]
    )
    (FuncDef
      name: test_no_cache_tree
      body: 
        (BraceGroup
          children: [
            (AndOr
              children: [
                (SimpleCommand
                  words: [{(Lit_Other ":")}]
                  redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(expect)} spids:[376])]
                )
                (C {(cmp_cache_tree)} {(expect)})
              ]
              op_id: Op_DAmp
            )
          ]
          spids: [371]
        )
      spids: [366 370]
    )
    (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">
        )
      }
    )
    (SimpleCommand
      words: [{(cat)}]
      redirects: [
        (Redir op_id:Redir_Great fd:-1 arg_word:{(before)} spids:[448])
        (HereDoc
          op_id: Redir_DLess
          fd: -1
          body: 
            {("SHA  (3 entries, 2 subtrees)\n") ("SHA dir1/ (1 entries, 0 subtrees)\n") 
              ("SHA dir2/ (1 entries, 0 subtrees)\n")
            }
          do_expansion: False
          here_end: EOF
          was_filled: True
          spids: [451]
        )
      ]
    )
    (SimpleCommand
      words: [{(cat)}]
      redirects: [
        (Redir op_id:Redir_Great fd:-1 arg_word:{(expect)} spids:[458])
        (HereDoc
          op_id: Redir_DLess
          fd: -1
          body: 
            {("invalid                                   (2 subtrees)\n") 
              ("invalid                                  dir1/ (0 subtrees)\n") ("SHA dir2/ (1 entries, 0 subtrees)\n")
            }
          do_expansion: False
          here_end: EOF
          was_filled: True
          spids: [461]
        )
      ]
    )
    (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)})
  ]
)