(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(DQ ('git hash-object'))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (command.ShFunction
      name: echo_without_newline
      body: 
        (command.BraceGroup
          children: [
            (C {(printf)} {(SQ (Token id:Id.Lit_Chars val:'%s' span_id:25))} {(DQ ($ Id.VSub_Star '$*'))})
          ]
        )
    )
    (command.ShFunction
      name: test_blob_does_not_exist
      body: 
        (command.BraceGroup
          children: [
            (C {(test_expect_success)} 
              {(SQ (Token id:Id.Lit_Chars val:'blob does not exist in database' span_id:45))} {(DQ ('\n') ('\t\ttest_must_fail git cat-file blob ') ($ Id.VSub_Number '$1') ('\n') ('\t'))}
            )
          ]
        )
    )
    (command.ShFunction
      name: test_blob_exists
      body: 
        (command.BraceGroup
          children: [
            (C {(test_expect_success)} 
              {(SQ (Token id:Id.Lit_Chars val:'blob exists in database' span_id:69))} {(DQ ('\n') ('\t\tgit cat-file blob ') ($ Id.VSub_Number '$1') ('\n') ('\t'))}
            )
          ]
        )
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:hello_content)
          op: assign_op.Equal
          rhs: {(DQ ('Hello World'))}
          spids: [83]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:hello_sha1)
          op: assign_op.Equal
          rhs: {(5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689)}
          spids: [88]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:example_content)
          op: assign_op.Equal
          rhs: {(DQ ('This is an example'))}
          spids: [92]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:example_sha1)
          op: assign_op.Equal
          rhs: {(ddd3f836d3e3fbb7ae289aa9ae83536f76956399)}
          spids: [97]
        )
      ]
    )
    (command.ShFunction
      name: setup_repo
      body: 
        (command.BraceGroup
          children: [
            (command.Simple
              words: [{(echo_without_newline)} {(DQ ($ Id.VSub_DollarName '$hello_content'))}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_Great val:'>' span_id:114)
                  fd: -1
                  arg_word: {(hello)}
                )
              ]
            )
            (command.Simple
              words: [{(echo_without_newline)} {(DQ ($ Id.VSub_DollarName '$example_content'))}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_Great val:'>' span_id:125)
                  fd: -1
                  arg_word: {(example)}
                )
              ]
            )
          ]
        )
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_repo)
          op: assign_op.Equal
          rhs: {(test)}
          spids: [132]
        )
      ]
    )
    (command.ShFunction
      name: push_repo
      body: 
        (command.BraceGroup
          children: [
            (C {(test_create_repo)} {($ Id.VSub_DollarName '$test_repo')})
            (C {(cd)} {($ Id.VSub_DollarName '$test_repo')})
            (C {(setup_repo)})
          ]
        )
    )
    (command.ShFunction
      name: pop_repo
      body: 
        (command.BraceGroup
          children: [(C {(cd)} {(..)}) (C {(rm)} {(-rf)} {($ Id.VSub_DollarName '$test_repo')})]
        )
    )
    (C {(setup_repo)})
    (C {(test_expect_success)} {(DQ ("multiple '--stdin's are rejected"))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:193) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | test_must_fail git hash-object --stdin --stdin\n'
            span_id: 194
          )
        )
      }
    )
    (C {(test_expect_success)} {(DQ ("Can't use --stdin and --stdin-paths together"))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:205) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | test_must_fail git hash-object --stdin --stdin-paths &&\n'
            span_id: 206
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | test_must_fail git hash-object --stdin-paths --stdin\n'
            span_id: 207
          )
        )
      }
    )
    (C {(test_expect_success)} {(DQ ("Can't pass filenames as arguments with --stdin-paths"))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:218) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | test_must_fail git hash-object --stdin-paths hello\n'
            span_id: 219
          )
        )
      }
    )
    (C {(test_expect_success)} {(DQ ("Can't use --path with --stdin-paths"))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:230) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | test_must_fail git hash-object --stdin-paths --path=foo\n'
            span_id: 231
          )
        )
      }
    )
    (C {(test_expect_success)} {(DQ ("Can't use --path with --no-filters"))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:242) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object --no-filters --path=foo\n'
            span_id: 243
          )
        )
      }
    )
    (C {(push_repo)})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'hash a file' span_id:257))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:261) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $hello_sha1 = $(git hash-object hello)\n'
            span_id: 262
          )
        )
      }
    )
    (C {(test_blob_does_not_exist)} {($ Id.VSub_DollarName '$hello_sha1')})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'hash from stdin' span_id:274))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:278) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $example_sha1 = $(git hash-object --stdin < example)\n'
            span_id: 279
          )
        )
      }
    )
    (C {(test_blob_does_not_exist)} {($ Id.VSub_DollarName '$example_sha1')})
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'hash a file and write to database' span_id:291))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:295) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $hello_sha1 = $(git hash-object -w hello)\n'
            span_id: 296
          )
        )
      }
    )
    (C {(test_blob_exists)} {($ Id.VSub_DollarName '$hello_sha1')})
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'git hash-object --stdin file1 <file0 first operates on file0, then file1'
            span_id: 308
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:312) 
          (Token id:Id.Lit_Chars val:'\techo foo > file1 &&\n' span_id:313) (Token id:Id.Lit_Chars val:'\tobname0=$(echo bar | git hash-object --stdin) &&\n' span_id:314) 
          (Token id:Id.Lit_Chars val:'\tobname1=$(git hash-object file1) &&\n' span_id:315) 
          (Token
            id: Id.Lit_Chars
            val: '\tobname0new=$(echo bar | git hash-object --stdin file1 | sed -n -e 1p) &&\n'
            span_id: 316
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tobname1new=$(echo bar | git hash-object --stdin file1 | sed -n -e 2p) &&\n'
            span_id: 317
          ) (Token id:Id.Lit_Chars val:'\ttest "$obname0" = "$obname0new" &&\n' span_id:318) 
          (Token id:Id.Lit_Chars val:'\ttest "$obname1" = "$obname1new"\n' span_id:319)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'set up crlf tests' span_id:326))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:330) 
          (Token
            id: Id.Lit_Chars
            val: '\techo fooQ | tr Q "\\\\015" >file0 &&\n'
            span_id: 331
          ) (Token id:Id.Lit_Chars val:'\tcp file0 file1 &&\n' span_id:332) 
          (Token
            id: Id.Lit_Chars
            val: '\techo "file0 -crlf" >.gitattributes &&\n'
            span_id: 333
          ) (Token id:Id.Lit_Chars val:'\techo "file1 crlf" >>.gitattributes &&\n' span_id:334) 
          (Token id:Id.Lit_Chars val:'\tgit config core.autocrlf true &&\n' span_id:335) (Token id:Id.Lit_Chars val:'\tfile0_sha=$(git hash-object file0) &&\n' span_id:336) 
          (Token
            id: Id.Lit_Chars
            val: '\tfile1_sha=$(git hash-object file1) &&\n'
            span_id: 337
          ) (Token id:Id.Lit_Chars val:'\ttest "$file0_sha" != "$file1_sha"\n' span_id:338)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'check that appropriate filter is invoke when --path is used'
            span_id: 345
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:349) 
          (Token
            id: Id.Lit_Chars
            val: '\tpath1_sha=$(git hash-object --path=file1 file0) &&\n'
            span_id: 350
          ) (Token id:Id.Lit_Chars val:'\tpath0_sha=$(git hash-object --path=file0 file1) &&\n' span_id:351) 
          (Token id:Id.Lit_Chars val:'\ttest "$file0_sha" = "$path0_sha" &&\n' span_id:352) (Token id:Id.Lit_Chars val:'\ttest "$file1_sha" = "$path1_sha" &&\n' span_id:353) 
          (Token
            id: Id.Lit_Chars
            val: '\tpath1_sha=$(cat file0 | git hash-object --path=file1 --stdin) &&\n'
            span_id: 354
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tpath0_sha=$(cat file1 | git hash-object --path=file0 --stdin) &&\n'
            span_id: 355
          ) (Token id:Id.Lit_Chars val:'\ttest "$file0_sha" = "$path0_sha" &&\n' span_id:356) 
          (Token id:Id.Lit_Chars val:'\ttest "$file1_sha" = "$path1_sha"\n' span_id:357)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'gitattributes also work in a subdirectory' span_id:364))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:368) 
          (Token id:Id.Lit_Chars val:'\tmkdir subdir &&\n' span_id:369) (Token id:Id.Lit_Chars val:'\t(\n' span_id:370) 
          (Token id:Id.Lit_Chars val:'\t\tcd subdir &&\n' span_id:371) (Token id:Id.Lit_Chars val:'\t\tsubdir_sha0=$(git hash-object ../file0) &&\n' span_id:372) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tsubdir_sha1=$(git hash-object ../file1) &&\n'
            span_id: 373
          ) (Token id:Id.Lit_Chars val:'\t\ttest "$file0_sha" = "$subdir_sha0" &&\n' span_id:374) 
          (Token
            id: Id.Lit_Chars
            val: '\t\ttest "$file1_sha" = "$subdir_sha1"\n'
            span_id: 375
          ) (Token id:Id.Lit_Chars val:'\t)\n' span_id:376)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'check that --no-filters option works' span_id:383))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:387) 
          (Token
            id: Id.Lit_Chars
            val: '\tnofilters_file1=$(git hash-object --no-filters file1) &&\n'
            span_id: 388
          ) (Token id:Id.Lit_Chars val:'\ttest "$file0_sha" = "$nofilters_file1" &&\n' span_id:389) 
          (Token
            id: Id.Lit_Chars
            val: '\tnofilters_file1=$(cat file1 | git hash-object --stdin) &&\n'
            span_id: 390
          ) (Token id:Id.Lit_Chars val:'\ttest "$file0_sha" = "$nofilters_file1"\n' span_id:391)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'check that --no-filters option works with --stdin-paths'
            span_id: 398
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:402) 
          (Token
            id: Id.Lit_Chars
            val: 
'\tnofilters_file1=$(echo "file1" | git hash-object --stdin-paths --no-filters) &&\n'
            span_id: 403
          ) (Token id:Id.Lit_Chars val:'\ttest "$file0_sha" = "$nofilters_file1"\n' span_id:404)
        )
      }
    )
    (C {(pop_repo)})
    (command.ForEach
      iter_name: args
      iter_words: [{(DQ ('-w --stdin'))} {(DQ ('--stdin -w'))}]
      do_arg_iter: F
      body: 
        (command.DoGroup
          children: [
            (C {(push_repo)})
            (C {(test_expect_success)} 
              {(DQ ('hash from stdin and write to database (') ($ Id.VSub_DollarName '$args') (')'))} 
              {
                (SQ (Token id:Id.Lit_Chars val:'\n' span_id:442) 
                  (Token
                    id: Id.Lit_Chars
                    val: '\t\ttest $example_sha1 = $(git hash-object $args < example)\n'
                    span_id: 443
                  ) (Token id:Id.Lit_Chars val:'\t' span_id:444)
                )
              }
            )
            (C {(test_blob_exists)} {($ Id.VSub_DollarName '$example_sha1')})
            (C {(pop_repo)})
          ]
        )
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:filenames)
          op: assign_op.Equal
          rhs: {(DQ ('hello\n') (example))}
          spids: [460]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:sha1s)
          op: assign_op.Equal
          rhs: 
            {(DQ ($ Id.VSub_DollarName '$hello_sha1') ('\n') ($ Id.VSub_DollarName '$example_sha1'))}
          spids: [467]
        )
      ]
    )
    (C {(test_expect_success)} {(DQ ('hash two files with names on stdin'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:482) 
          (Token
            id: Id.Lit_Chars
            val: 
'\ttest "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"\n'
            span_id: 483
          )
        )
      }
    )
    (command.ForEach
      iter_name: args
      iter_words: [{(DQ ('-w --stdin-paths'))} {(DQ ('--stdin-paths -w'))}]
      do_arg_iter: F
      body: 
        (command.DoGroup
          children: [
            (C {(push_repo)})
            (C {(test_expect_success)} 
              {
                (DQ ('hash two files with names on stdin and write to database (') 
                  ($ Id.VSub_DollarName '$args') (')')
                )
              } 
              {
                (SQ (Token id:Id.Lit_Chars val:'\n' span_id:518) 
                  (Token
                    id: Id.Lit_Chars
                    val: 
'\t\ttest "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)"\n'
                    span_id: 519
                  ) (Token id:Id.Lit_Chars val:'\t' span_id:520)
                )
              }
            )
            (C {(test_blob_exists)} {($ Id.VSub_DollarName '$hello_sha1')})
            (C {(test_blob_exists)} {($ Id.VSub_DollarName '$example_sha1')})
            (C {(pop_repo)})
          ]
        )
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'too-short tree' span_id:544))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:548) 
          (Token id:Id.Lit_Chars val:'\techo abc >malformed-tree &&\n' span_id:549) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t tree malformed-tree 2>err &&\n'
            span_id: 550
          ) (Token id:Id.Lit_Chars val:'\ttest_i18ngrep "too-short tree object" err\n' span_id:551)
        )
      }
    )
    (command.ShFunction
      name: hex2oct
      body: 
        (command.BraceGroup
          children: [
            (C {(perl)} {(-ne)} 
              {(SQ (Token id:Id.Lit_Chars val:'printf "\\\\%03o", hex for /../g' span_id:567))}
            )
          ]
        )
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'malformed mode in tree' span_id:576))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:580) 
          (Token
            id: Id.Lit_Chars
            val: '\thex_sha1=$(echo foo | git hash-object --stdin -w) &&\n'
            span_id: 581
          ) (Token id:Id.Lit_Chars val:'\tbin_sha1=$(echo $hex_sha1 | hex2oct) &&\n' span_id:582) 
          (Token
            id: Id.Lit_Chars
            val: '\tprintf "9100644 \\0$bin_sha1" >tree-with-malformed-mode &&\n'
            span_id: 583
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t tree tree-with-malformed-mode 2>err &&\n'
            span_id: 584
          ) (Token id:Id.Lit_Chars val:'\ttest_i18ngrep "malformed mode in tree entry" err\n' span_id:585)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'empty filename in tree' span_id:592))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:596) 
          (Token
            id: Id.Lit_Chars
            val: '\thex_sha1=$(echo foo | git hash-object --stdin -w) &&\n'
            span_id: 597
          ) (Token id:Id.Lit_Chars val:'\tbin_sha1=$(echo $hex_sha1 | hex2oct) &&\n' span_id:598) 
          (Token
            id: Id.Lit_Chars
            val: '\tprintf "100644 \\0$bin_sha1" >tree-with-empty-filename &&\n'
            span_id: 599
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t tree tree-with-empty-filename 2>err &&\n'
            span_id: 600
          ) (Token id:Id.Lit_Chars val:'\ttest_i18ngrep "empty filename in tree entry" err\n' span_id:601)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'corrupt commit' span_id:608))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:612) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t commit --stdin </dev/null\n'
            span_id: 613
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'corrupt tag' span_id:620))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:624) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t tag --stdin </dev/null\n'
            span_id: 625
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'hash-object complains about bogus type name' span_id:632))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:636) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t bogus --stdin </dev/null\n'
            span_id: 637
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'hash-object complains about truncated type name' span_id:644))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:648) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git hash-object -t bl --stdin </dev/null\n'
            span_id: 649
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:--literally span_id:656))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:660) 
          (Token id:Id.Lit_Chars val:'\tt=1234567890 &&\n' span_id:661) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | git hash-object -t $t --literally --stdin\n'
            span_id: 662
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'--literally with extra-long type' span_id:669))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:673) 
          (Token
            id: Id.Lit_Chars
            val: '\tt=12345678901234567890123456789012345678901234567890 &&\n'
            span_id: 674
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tt="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" &&\n'
            span_id: 675
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\techo example | git hash-object -t $t --literally --stdin\n'
            span_id: 676
          )
        )
      }
    )
    (C {(test_done)})
  ]
)