(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'Test notes trees that also contain non-notes'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:number_of_commits)
          op: assign_op.Equal
          rhs: {<100>}
          spids: [15]
        )
      ]
    )
    (command.ShFunction
      name: start_note_commit
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (C {<test_tick>})
                (command.Simple
                  words: [{<cat>}]
                  redirects: [
                    (redir
                      op: <Id.Redir_DLess '<<'>
                      loc: (redir_loc.Fd fd:0)
                      arg: 
                        (redir_param.MultiLine
                          here_begin: {<INPUT_END>}
                          here_end_span_id: 52
                          stdin_parts: [
                            <'commit refs/notes/commits\n'>
                            <'committer '>
                            ($ Id.VSub_DollarName '$GIT_COMMITTER_NAME')
                            <' <'>
                            ($ Id.VSub_DollarName '$GIT_COMMITTER_EMAIL')
                            <'> '>
                            ($ Id.VSub_DollarName '$GIT_COMMITTER_DATE')
                            <'\n'>
                            <'data <<COMMIT\n'>
                            <'notes\n'>
                            <'COMMIT\n'>
                            <'\n'>
                            <'from refs/notes/commits^0\n'>
                            <'deleteall\n'>
                          ]
                        )
                    )
                  ]
                  do_fork: T
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: verify_notes
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Pipeline
                  children: [
                    (C {<git>} {<log>})
                    (command.Simple
                      words: [{<grep>} {(DQ <'^    '>)}]
                      redirects: [
                        (redir
                          op: <Id.Redir_Great '>'>
                          loc: (redir_loc.Fd fd:1)
                          arg: {<output>}
                        )
                      ]
                      do_fork: T
                    )
                  ]
                  negated: F
                )
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:i)
                      op: assign_op.Equal
                      rhs: {($ Id.VSub_DollarName '$number_of_commits')}
                      spids: [84]
                    )
                  ]
                )
                (command.WhileUntil
                  keyword: <Id.KW_While while>
                  cond: [
                    (command.Sentence
                      child: 
                        (C {<Id.Lit_LBracket '['>} {($ Id.VSub_DollarName '$i')} {<-gt>} {<0>} 
                          {<Id.Lit_RBracket ']'>}
                        )
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                  body: 
                    (command.DoGroup
                      children: [
                        (command.Sentence
                          child: 
                            (command.AndOr
                              ops: [Id.Op_DAmp Id.Op_DAmp]
                              children: [
                                (C {<echo>} {(DQ <'    commit #'> ($ Id.VSub_DollarName '$i'))})
                                (C {<echo>} {(DQ <'    note for commit #'> ($ Id.VSub_DollarName '$i'))})
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:i)
                                      op: assign_op.Equal
                                      rhs: 
                                        {
                                          (word_part.ArithSub
                                            anode: 
                                              (arith_expr.Binary
                                                op_id: Id.Arith_Minus
                                                left: {($ Id.VSub_DollarName '$i')}
                                                right: {<Id.Lit_Digits 1>}
                                              )
                                          )
                                        }
                                      spids: [126]
                                    )
                                  ]
                                )
                              ]
                            )
                          terminator: <Id.Op_Semi _>
                        )
                      ]
                    )
                  redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>})]
                )
                (C {<test_cmp>} {<expect>} {<output>})
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {(DQ <'setup: create a couple of commits'>)} 
      {
        (SQ <'\n'> <'\n'> <'\ttest_tick &&\n'> <'\tcat <<INPUT_END >input &&\n'> 
          <'commit refs/heads/master\n'> <'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'> <'data <<COMMIT\n'> 
          <'commit #1\n'> <'COMMIT\n'> <'\n'> <'M 644 inline file\n'> <'data <<EOF\n'> <'file in commit #1\n'> <'EOF\n'> <'\n'> 
          <'INPUT_END\n'> <'\n'> <'\ttest_tick &&\n'> <'\tcat <<INPUT_END >>input &&\n'> <'commit refs/heads/master\n'> 
          <'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'> <'data <<COMMIT\n'> <'commit #2\n'> <'COMMIT\n'> <'\n'> <'M 644 inline file\n'> <'data <<EOF\n'> 
          <'file in commit #2\n'> <'EOF\n'> <'\n'> <'INPUT_END\n'> <'\tgit fast-import --quiet <input\n'>
        )
      }
    )
    (C {<test_expect_success>} {(DQ <'create a notes tree with both notes and non-notes'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tcommit1=$(git rev-parse refs/heads/master^) &&\n'> 
          <'\tcommit2=$(git rev-parse refs/heads/master) &&\n'> <'\ttest_tick &&\n'> <'\tcat <<INPUT_END >input &&\n'> <'commit refs/notes/commits\n'> 
          <'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'> <'data <<COMMIT\n'> <'notes commit #1\n'> <'COMMIT\n'> <'\n'> <'N inline $commit1\n'> <'data <<EOF\n'> 
          <'note for commit #1\n'> <'EOF\n'> <'\n'> <'N inline $commit2\n'> <'data <<EOF\n'> <'note for commit #2\n'> <'EOF\n'> <'\n'> 
          <'INPUT_END\n'> <'\ttest_tick &&\n'> <'\tcat <<INPUT_END >>input &&\n'> <'commit refs/notes/commits\n'> 
          <'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'> <'data <<COMMIT\n'> <'notes commit #2\n'> <'COMMIT\n'> <'\n'> <'M 644 inline foobar/non-note.txt\n'> 
          <'data <<EOF\n'> <'A non-note in a notes tree\n'> <'EOF\n'> <'\n'> <'N inline $commit2\n'> <'data <<EOF\n'> 
          <'edited note for commit #2\n'> <'EOF\n'> <'\n'> <'INPUT_END\n'> <'\ttest_tick &&\n'> <'\tcat <<INPUT_END >>input &&\n'> 
          <'commit refs/notes/commits\n'> <'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'> <'data <<COMMIT\n'> 
          <'notes commit #3\n'> <'COMMIT\n'> <'\n'> <'N inline $commit1\n'> <'data <<EOF\n'> <'edited note for commit #1\n'> <'EOF\n'> 
          <'\n'> <'M 644 inline deadbeef\n'> <'data <<EOF\n'> <'non-note with SHA1-like name\n'> <'EOF\n'> <'\n'> 
          <'M 644 inline de/adbeef\n'> <'data <<EOF\n'> <'another non-note with SHA1-like name\n'> <'EOF\n'> <'\n'> 
          <'M 644 inline de/adbeefdeadbeefdeadbeefdeadbeefdeadbeef\n'> <'data <<EOF\n'> <'This is actually a valid note, albeit to a non-existing object.\n'> 
          <'It is needed in order to trigger the "mishandling" of the dead/beef non-note.\n'> <'EOF\n'> <'\n'> <'M 644 inline dead/beef\n'> <'data <<EOF\n'> 
          <'yet another non-note with SHA1-like name\n'> <'EOF\n'> <'\n'> <'INPUT_END\n'> <'\tgit fast-import --quiet <input &&\n'> 
          <'\tgit config core.notesRef refs/notes/commits\n'>
        )
      }
    )
    (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: {<EXPECT_END>}
              here_end_span_id: 298
              stdin_parts: [
                <'    commit #2\n'>
                <'    edited note for commit #2\n'>
                <'    commit #1\n'>
                <'    edited note for commit #1\n'>
              ]
            )
        )
      ]
      do_fork: T
    )
    (C {<test_expect_success>} {(DQ <'verify contents of notes'>)} 
      {(SQ <'\n'> <'\n'> <'\tgit log | grep "^    " > actual &&\n'> <'\ttest_cmp expect actual\n'>)}
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect_nn1>})
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.MultiLine
              here_begin: {<EXPECT_END>}
              here_end_span_id: 324
              stdin_parts: [<'A non-note in a notes tree\n'>]
            )
        )
      ]
      do_fork: T
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect_nn2>})
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.MultiLine
              here_begin: {<EXPECT_END>}
              here_end_span_id: 335
              stdin_parts: [<'non-note with SHA1-like name\n'>]
            )
        )
      ]
      do_fork: T
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect_nn3>})
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.MultiLine
              here_begin: {<EXPECT_END>}
              here_end_span_id: 346
              stdin_parts: [<'another non-note with SHA1-like name\n'>]
            )
        )
      ]
      do_fork: T
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect_nn4>})
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.MultiLine
              here_begin: {<EXPECT_END>}
              here_end_span_id: 357
              stdin_parts: [<'yet another non-note with SHA1-like name\n'>]
            )
        )
      ]
      do_fork: T
    )
    (C {<test_expect_success>} {(DQ <'verify contents of non-notes'>)} 
      {
        (SQ <'\n'> <'\n'> 
          <'\tgit cat-file -p refs/notes/commits:foobar/non-note.txt > actual_nn1 &&\n'> <'\ttest_cmp expect_nn1 actual_nn1 &&\n'> 
          <'\tgit cat-file -p refs/notes/commits:deadbeef > actual_nn2 &&\n'> <'\ttest_cmp expect_nn2 actual_nn2 &&\n'> 
          <'\tgit cat-file -p refs/notes/commits:de/adbeef > actual_nn3 &&\n'> <'\ttest_cmp expect_nn3 actual_nn3 &&\n'> 
          <'\tgit cat-file -p refs/notes/commits:dead/beef > actual_nn4 &&\n'> <'\ttest_cmp expect_nn4 actual_nn4\n'>
        )
      }
    )
    (C {<test_expect_success>} {(DQ <'git-notes preserves non-notes'>)} 
      {(SQ <'\n'> <'\n'> <'\ttest_tick &&\n'> <'\tgit notes add -f -m "foo bar"\n'>)}
    )
    (C {<test_expect_success>} {(DQ <'verify contents of non-notes after git-notes'>)} 
      {
        (SQ <'\n'> <'\n'> 
          <'\tgit cat-file -p refs/notes/commits:foobar/non-note.txt > actual_nn1 &&\n'> <'\ttest_cmp expect_nn1 actual_nn1 &&\n'> 
          <'\tgit cat-file -p refs/notes/commits:deadbeef > actual_nn2 &&\n'> <'\ttest_cmp expect_nn2 actual_nn2 &&\n'> 
          <'\tgit cat-file -p refs/notes/commits:de/adbeef > actual_nn3 &&\n'> <'\ttest_cmp expect_nn3 actual_nn3 &&\n'> 
          <'\tgit cat-file -p refs/notes/commits:dead/beef > actual_nn4 &&\n'> <'\ttest_cmp expect_nn4 actual_nn4\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)