(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: (BraceGroup children:[(C {<printf>} {(SQ <'%s'>)} {(DQ ($ Id.VSub_Star '$*'))})])
    )
    (command.ShFunction
      name: test_blob_does_not_exist
      body: 
        (BraceGroup
          children: [
            (C {<test_expect_success>} {(SQ <'blob does not exist in database'>)} 
              {
                (DQ <'\n'> <'\t\ttest_must_fail git cat-file blob '> ($ Id.VSub_Number '$1') <'\n'> 
                  <'\t'>
                )
              }
            )
          ]
        )
    )
    (command.ShFunction
      name: test_blob_exists
      body: 
        (BraceGroup
          children: [
            (C {<test_expect_success>} {(SQ <'blob exists in database'>)} 
              {(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: 
        (BraceGroup
          children: [
            (command.Simple
              words: [{<echo_without_newline>} {(DQ ($ Id.VSub_DollarName '$hello_content'))}]
              redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<hello>})]
              do_fork: T
            )
            (command.Simple
              words: [{<echo_without_newline>} {(DQ ($ Id.VSub_DollarName '$example_content'))}]
              redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<example>})]
              do_fork: T
            )
          ]
        )
    )
    (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: 
        (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: 
        (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 <'\n'> <'\techo example | test_must_fail git hash-object --stdin --stdin\n'>)}
    )
    (C {<test_expect_success>} {(DQ <'Can\'t use --stdin and --stdin-paths together'>)} 
      {
        (SQ <'\n'> <'\techo example | test_must_fail git hash-object --stdin --stdin-paths &&\n'> 
          <'\techo example | test_must_fail git hash-object --stdin-paths --stdin\n'>
        )
      }
    )
    (C {<test_expect_success>} {(DQ <'Can\'t pass filenames as arguments with --stdin-paths'>)} 
      {(SQ <'\n'> <'\techo example | test_must_fail git hash-object --stdin-paths hello\n'>)}
    )
    (C {<test_expect_success>} {(DQ <'Can\'t use --path with --stdin-paths'>)} 
      {(SQ <'\n'> <'\techo example | test_must_fail git hash-object --stdin-paths --path=foo\n'>)}
    )
    (C {<test_expect_success>} {(DQ <'Can\'t use --path with --no-filters'>)} 
      {(SQ <'\n'> <'\ttest_must_fail git hash-object --no-filters --path=foo\n'>)}
    )
    (C {<push_repo>})
    (C {<test_expect_success>} {(SQ <'hash a file'>)} 
      {(SQ <'\n'> <'\ttest $hello_sha1 = $(git hash-object hello)\n'>)}
    )
    (C {<test_blob_does_not_exist>} {($ Id.VSub_DollarName '$hello_sha1')})
    (C {<test_expect_success>} {(SQ <'hash from stdin'>)} 
      {(SQ <'\n'> <'\ttest $example_sha1 = $(git hash-object --stdin < example)\n'>)}
    )
    (C {<test_blob_does_not_exist>} {($ Id.VSub_DollarName '$example_sha1')})
    (C {<test_expect_success>} {(SQ <'hash a file and write to database'>)} 
      {(SQ <'\n'> <'\ttest $hello_sha1 = $(git hash-object -w hello)\n'>)}
    )
    (C {<test_blob_exists>} {($ Id.VSub_DollarName '$hello_sha1')})
    (C {<test_expect_success>} 
      {(SQ <'git hash-object --stdin file1 <file0 first operates on file0, then file1'>)} 
      {
        (SQ <'\n'> <'\techo foo > file1 &&\n'> <'\tobname0=$(echo bar | git hash-object --stdin) &&\n'> 
          <'\tobname1=$(git hash-object file1) &&\n'> <'\tobname0new=$(echo bar | git hash-object --stdin file1 | sed -n -e 1p) &&\n'> 
          <'\tobname1new=$(echo bar | git hash-object --stdin file1 | sed -n -e 2p) &&\n'> <'\ttest "$obname0" = "$obname0new" &&\n'> <'\ttest "$obname1" = "$obname1new"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'set up crlf tests'>)} 
      {
        (SQ <'\n'> <'\techo fooQ | tr Q "\\\\015" >file0 &&\n'> <'\tcp file0 file1 &&\n'> 
          <'\techo "file0 -crlf" >.gitattributes &&\n'> <'\techo "file1 crlf" >>.gitattributes &&\n'> <'\tgit config core.autocrlf true &&\n'> 
          <'\tfile0_sha=$(git hash-object file0) &&\n'> <'\tfile1_sha=$(git hash-object file1) &&\n'> <'\ttest "$file0_sha" != "$file1_sha"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'check that appropriate filter is invoke when --path is used'>)} 
      {
        (SQ <'\n'> <'\tpath1_sha=$(git hash-object --path=file1 file0) &&\n'> 
          <'\tpath0_sha=$(git hash-object --path=file0 file1) &&\n'> <'\ttest "$file0_sha" = "$path0_sha" &&\n'> <'\ttest "$file1_sha" = "$path1_sha" &&\n'> 
          <'\tpath1_sha=$(cat file0 | git hash-object --path=file1 --stdin) &&\n'> <'\tpath0_sha=$(cat file1 | git hash-object --path=file0 --stdin) &&\n'> 
          <'\ttest "$file0_sha" = "$path0_sha" &&\n'> <'\ttest "$file1_sha" = "$path1_sha"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'gitattributes also work in a subdirectory'>)} 
      {
        (SQ <'\n'> <'\tmkdir subdir &&\n'> <'\t(\n'> <'\t\tcd subdir &&\n'> 
          <'\t\tsubdir_sha0=$(git hash-object ../file0) &&\n'> <'\t\tsubdir_sha1=$(git hash-object ../file1) &&\n'> <'\t\ttest "$file0_sha" = "$subdir_sha0" &&\n'> 
          <'\t\ttest "$file1_sha" = "$subdir_sha1"\n'> <'\t)\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'check that --no-filters option works'>)} 
      {
        (SQ <'\n'> <'\tnofilters_file1=$(git hash-object --no-filters file1) &&\n'> 
          <'\ttest "$file0_sha" = "$nofilters_file1" &&\n'> <'\tnofilters_file1=$(cat file1 | git hash-object --stdin) &&\n'> 
          <'\ttest "$file0_sha" = "$nofilters_file1"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'check that --no-filters option works with --stdin-paths'>)} 
      {
        (SQ <'\n'> 
          <'\tnofilters_file1=$(echo "file1" | git hash-object --stdin-paths --no-filters) &&\n'> <'\ttest "$file0_sha" = "$nofilters_file1"\n'>
        )
      }
    )
    (C {<pop_repo>})
    (command.ForEach
      iter_names: [args]
      iterable: (for_iter.Words words:[{(DQ <'-w --stdin'>)} {(DQ <'--stdin -w'>)}])
      body: 
        (command.DoGroup
          children: [
            (C {<push_repo>})
            (C {<test_expect_success>} 
              {(DQ <'hash from stdin and write to database ('> ($ Id.VSub_DollarName '$args') <')'>)} {(SQ <'\n'> <'\t\ttest $example_sha1 = $(git hash-object $args < example)\n'> <'\t'>)}
            )
            (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 <'\n'> 
          <
'\ttest "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"\n'
          >
        )
      }
    )
    (command.ForEach
      iter_names: [args]
      iterable: (for_iter.Words words:[{(DQ <'-w --stdin-paths'>)} {(DQ <'--stdin-paths -w'>)}])
      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 <'\n'> 
                  <
'\t\ttest "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)"\n'
                  > <'\t'>
                )
              }
            )
            (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 <'too-short tree'>)} 
      {
        (SQ <'\n'> <'\techo abc >malformed-tree &&\n'> 
          <'\ttest_must_fail git hash-object -t tree malformed-tree 2>err &&\n'> <'\ttest_i18ngrep "too-short tree object" err\n'>
        )
      }
    )
    (command.ShFunction
      name: hex2oct
      body: (BraceGroup children:[(C {<perl>} {<-ne>} {(SQ <'printf "\\\\%03o", hex for /../g'>)})])
    )
    (C {<test_expect_success>} {(SQ <'malformed mode in tree'>)} 
      {
        (SQ <'\n'> <'\thex_sha1=$(echo foo | git hash-object --stdin -w) &&\n'> 
          <'\tbin_sha1=$(echo $hex_sha1 | hex2oct) &&\n'> <'\tprintf "9100644 \\0$bin_sha1" >tree-with-malformed-mode &&\n'> 
          <'\ttest_must_fail git hash-object -t tree tree-with-malformed-mode 2>err &&\n'> <'\ttest_i18ngrep "malformed mode in tree entry" err\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'empty filename in tree'>)} 
      {
        (SQ <'\n'> <'\thex_sha1=$(echo foo | git hash-object --stdin -w) &&\n'> 
          <'\tbin_sha1=$(echo $hex_sha1 | hex2oct) &&\n'> <'\tprintf "100644 \\0$bin_sha1" >tree-with-empty-filename &&\n'> 
          <'\ttest_must_fail git hash-object -t tree tree-with-empty-filename 2>err &&\n'> <'\ttest_i18ngrep "empty filename in tree entry" err\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'corrupt commit'>)} 
      {(SQ <'\n'> <'\ttest_must_fail git hash-object -t commit --stdin </dev/null\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'corrupt tag'>)} 
      {(SQ <'\n'> <'\ttest_must_fail git hash-object -t tag --stdin </dev/null\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'hash-object complains about bogus type name'>)} 
      {(SQ <'\n'> <'\ttest_must_fail git hash-object -t bogus --stdin </dev/null\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'hash-object complains about truncated type name'>)} 
      {(SQ <'\n'> <'\ttest_must_fail git hash-object -t bl --stdin </dev/null\n'>)}
    )
    (C {<test_expect_success>} {(SQ <--literally>)} 
      {
        (SQ <'\n'> <'\tt=1234567890 &&\n'> 
          <'\techo example | git hash-object -t $t --literally --stdin\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--literally with extra-long type'>)} 
      {
        (SQ <'\n'> <'\tt=12345678901234567890123456789012345678901234567890 &&\n'> 
          <'\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'> <'\techo example | git hash-object -t $t --literally --stdin\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)