(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: 
            {
              (SQ 
                (Token
                  id: Id.Lit_Chars
                  val: 'Test notes trees that also contain non-notes'
                  span_id: 6
                )
              )
            }
          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: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (C {(test_tick)})
                (command.Simple
                  words: [{(cat)}]
                  redirects: [
                    (redir.HereDoc
                      op: (Token id:Id.Redir_DLess val:'<<' span_id:34)
                      fd: -1
                      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')
                      ]
                    )
                  ]
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: verify_notes
      body: 
        (command.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.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:77)
                          fd: -1
                          arg_word: {(output)}
                        )
                      ]
                    )
                  ]
                  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: (Token id:Id.KW_While val:while span_id:90)
                  cond: [
                    (command.Sentence
                      child: 
                        (C {(Id.Lit_LBracket '[')} {($ Id.VSub_DollarName '$i')} {(-gt)} {(0)} 
                          {(Id.Lit_RBracket ']')}
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:101)
                    )
                  ]
                  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: 
                                                  (arith_expr.ArithWord
                                                    w: {($ Id.VSub_DollarName '$i')}
                                                  )
                                                right: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                                              )
                                          )
                                        }
                                      spids: [126]
                                    )
                                  ]
                                )
                              ]
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:133)
                        )
                      ]
                    )
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:138)
                      fd: -1
                      arg_word: {(expect)}
                    )
                  ]
                )
                (C {(test_cmp)} {(expect)} {(output)})
              ]
            )
          ]
        )
    )
    (C {(test_expect_success)} {(DQ ('setup: create a couple of commits'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:161) (Token id:Id.Lit_Chars val:'\n' span_id:162) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:163) (Token id:Id.Lit_Chars val:'\tcat <<INPUT_END >input &&\n' span_id:164) 
          (Token id:Id.Lit_Chars val:'commit refs/heads/master\n' span_id:165) 
          (Token
            id: Id.Lit_Chars
            val: 'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'
            span_id: 166
          ) (Token id:Id.Lit_Chars val:'data <<COMMIT\n' span_id:167) 
          (Token id:Id.Lit_Chars val:'commit #1\n' span_id:168) (Token id:Id.Lit_Chars val:'COMMIT\n' span_id:169) (Token id:Id.Lit_Chars val:'\n' span_id:170) 
          (Token id:Id.Lit_Chars val:'M 644 inline file\n' span_id:171) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:172) 
          (Token id:Id.Lit_Chars val:'file in commit #1\n' span_id:173) (Token id:Id.Lit_Chars val:'EOF\n' span_id:174) (Token id:Id.Lit_Chars val:'\n' span_id:175) 
          (Token id:Id.Lit_Chars val:'INPUT_END\n' span_id:176) (Token id:Id.Lit_Chars val:'\n' span_id:177) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:178) (Token id:Id.Lit_Chars val:'\tcat <<INPUT_END >>input &&\n' span_id:179) 
          (Token id:Id.Lit_Chars val:'commit refs/heads/master\n' span_id:180) 
          (Token
            id: Id.Lit_Chars
            val: 'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'
            span_id: 181
          ) (Token id:Id.Lit_Chars val:'data <<COMMIT\n' span_id:182) 
          (Token id:Id.Lit_Chars val:'commit #2\n' span_id:183) (Token id:Id.Lit_Chars val:'COMMIT\n' span_id:184) (Token id:Id.Lit_Chars val:'\n' span_id:185) 
          (Token id:Id.Lit_Chars val:'M 644 inline file\n' span_id:186) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:187) 
          (Token id:Id.Lit_Chars val:'file in commit #2\n' span_id:188) (Token id:Id.Lit_Chars val:'EOF\n' span_id:189) (Token id:Id.Lit_Chars val:'\n' span_id:190) 
          (Token id:Id.Lit_Chars val:'INPUT_END\n' span_id:191) (Token id:Id.Lit_Chars val:'\tgit fast-import --quiet <input\n' span_id:192)
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('create a notes tree with both notes and non-notes'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:203) (Token id:Id.Lit_Chars val:'\n' span_id:204) 
          (Token
            id: Id.Lit_Chars
            val: '\tcommit1=$(git rev-parse refs/heads/master^) &&\n'
            span_id: 205
          ) (Token id:Id.Lit_Chars val:'\tcommit2=$(git rev-parse refs/heads/master) &&\n' span_id:206) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:207) (Token id:Id.Lit_Chars val:'\tcat <<INPUT_END >input &&\n' span_id:208) 
          (Token id:Id.Lit_Chars val:'commit refs/notes/commits\n' span_id:209) 
          (Token
            id: Id.Lit_Chars
            val: 'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'
            span_id: 210
          ) (Token id:Id.Lit_Chars val:'data <<COMMIT\n' span_id:211) 
          (Token id:Id.Lit_Chars val:'notes commit #1\n' span_id:212) (Token id:Id.Lit_Chars val:'COMMIT\n' span_id:213) (Token id:Id.Lit_Chars val:'\n' span_id:214) 
          (Token id:Id.Lit_Chars val:'N inline $commit1\n' span_id:215) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:216) 
          (Token id:Id.Lit_Chars val:'note for commit #1\n' span_id:217) (Token id:Id.Lit_Chars val:'EOF\n' span_id:218) (Token id:Id.Lit_Chars val:'\n' span_id:219) 
          (Token id:Id.Lit_Chars val:'N inline $commit2\n' span_id:220) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:221) 
          (Token id:Id.Lit_Chars val:'note for commit #2\n' span_id:222) (Token id:Id.Lit_Chars val:'EOF\n' span_id:223) (Token id:Id.Lit_Chars val:'\n' span_id:224) 
          (Token id:Id.Lit_Chars val:'INPUT_END\n' span_id:225) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:226) 
          (Token id:Id.Lit_Chars val:'\tcat <<INPUT_END >>input &&\n' span_id:227) (Token id:Id.Lit_Chars val:'commit refs/notes/commits\n' span_id:228) 
          (Token
            id: Id.Lit_Chars
            val: 'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'
            span_id: 229
          ) (Token id:Id.Lit_Chars val:'data <<COMMIT\n' span_id:230) 
          (Token id:Id.Lit_Chars val:'notes commit #2\n' span_id:231) (Token id:Id.Lit_Chars val:'COMMIT\n' span_id:232) (Token id:Id.Lit_Chars val:'\n' span_id:233) 
          (Token id:Id.Lit_Chars val:'M 644 inline foobar/non-note.txt\n' span_id:234) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:235) 
          (Token id:Id.Lit_Chars val:'A non-note in a notes tree\n' span_id:236) (Token id:Id.Lit_Chars val:'EOF\n' span_id:237) (Token id:Id.Lit_Chars val:'\n' span_id:238) 
          (Token id:Id.Lit_Chars val:'N inline $commit2\n' span_id:239) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:240) 
          (Token id:Id.Lit_Chars val:'edited note for commit #2\n' span_id:241) (Token id:Id.Lit_Chars val:'EOF\n' span_id:242) (Token id:Id.Lit_Chars val:'\n' span_id:243) 
          (Token id:Id.Lit_Chars val:'INPUT_END\n' span_id:244) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:245) 
          (Token id:Id.Lit_Chars val:'\tcat <<INPUT_END >>input &&\n' span_id:246) (Token id:Id.Lit_Chars val:'commit refs/notes/commits\n' span_id:247) 
          (Token
            id: Id.Lit_Chars
            val: 'committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n'
            span_id: 248
          ) (Token id:Id.Lit_Chars val:'data <<COMMIT\n' span_id:249) 
          (Token id:Id.Lit_Chars val:'notes commit #3\n' span_id:250) (Token id:Id.Lit_Chars val:'COMMIT\n' span_id:251) (Token id:Id.Lit_Chars val:'\n' span_id:252) 
          (Token id:Id.Lit_Chars val:'N inline $commit1\n' span_id:253) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:254) 
          (Token id:Id.Lit_Chars val:'edited note for commit #1\n' span_id:255) (Token id:Id.Lit_Chars val:'EOF\n' span_id:256) (Token id:Id.Lit_Chars val:'\n' span_id:257) 
          (Token id:Id.Lit_Chars val:'M 644 inline deadbeef\n' span_id:258) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:259) 
          (Token id:Id.Lit_Chars val:'non-note with SHA1-like name\n' span_id:260) (Token id:Id.Lit_Chars val:'EOF\n' span_id:261) (Token id:Id.Lit_Chars val:'\n' span_id:262) 
          (Token id:Id.Lit_Chars val:'M 644 inline de/adbeef\n' span_id:263) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:264) 
          (Token id:Id.Lit_Chars val:'another non-note with SHA1-like name\n' span_id:265) (Token id:Id.Lit_Chars val:'EOF\n' span_id:266) (Token id:Id.Lit_Chars val:'\n' span_id:267) 
          (Token
            id: Id.Lit_Chars
            val: 'M 644 inline de/adbeefdeadbeefdeadbeefdeadbeefdeadbeef\n'
            span_id: 268
          ) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:269) 
          (Token
            id: Id.Lit_Chars
            val: 'This is actually a valid note, albeit to a non-existing object.\n'
            span_id: 270
          ) 
          (Token
            id: Id.Lit_Chars
            val: 'It is needed in order to trigger the "mishandling" of the dead/beef non-note.\n'
            span_id: 271
          ) (Token id:Id.Lit_Chars val:'EOF\n' span_id:272) (Token id:Id.Lit_Chars val:'\n' span_id:273) 
          (Token id:Id.Lit_Chars val:'M 644 inline dead/beef\n' span_id:274) (Token id:Id.Lit_Chars val:'data <<EOF\n' span_id:275) 
          (Token
            id: Id.Lit_Chars
            val: 'yet another non-note with SHA1-like name\n'
            span_id: 276
          ) (Token id:Id.Lit_Chars val:'EOF\n' span_id:277) (Token id:Id.Lit_Chars val:'\n' span_id:278) 
          (Token id:Id.Lit_Chars val:'INPUT_END\n' span_id:279) (Token id:Id.Lit_Chars val:'\tgit fast-import --quiet <input &&\n' span_id:280) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit config core.notesRef refs/notes/commits\n'
            span_id: 281
          )
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:287)
          fd: -1
          arg_word: {(expect)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:290)
          fd: -1
          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')
          ]
        )
      ]
    )
    (C {(test_expect_success)} {(DQ ('verify contents of notes'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:307) (Token id:Id.Lit_Chars val:'\n' span_id:308) 
          (Token id:Id.Lit_Chars val:'\tgit log | grep "^    " > actual &&\n' span_id:309) (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:310)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:316)
          fd: -1
          arg_word: {(expect_nn1)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:319)
          fd: -1
          here_begin: {(EXPECT_END)}
          here_end_span_id: 324
          stdin_parts: [('A non-note in a notes tree\n')]
        )
      ]
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:327)
          fd: -1
          arg_word: {(expect_nn2)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:330)
          fd: -1
          here_begin: {(EXPECT_END)}
          here_end_span_id: 335
          stdin_parts: [('non-note with SHA1-like name\n')]
        )
      ]
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:338)
          fd: -1
          arg_word: {(expect_nn3)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:341)
          fd: -1
          here_begin: {(EXPECT_END)}
          here_end_span_id: 346
          stdin_parts: [('another non-note with SHA1-like name\n')]
        )
      ]
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:349)
          fd: -1
          arg_word: {(expect_nn4)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:352)
          fd: -1
          here_begin: {(EXPECT_END)}
          here_end_span_id: 357
          stdin_parts: [('yet another non-note with SHA1-like name\n')]
        )
      ]
    )
    (C {(test_expect_success)} {(DQ ('verify contents of non-notes'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:366) (Token id:Id.Lit_Chars val:'\n' span_id:367) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:foobar/non-note.txt > actual_nn1 &&\n'
            span_id: 368
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn1 actual_nn1 &&\n' span_id:369) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:deadbeef > actual_nn2 &&\n'
            span_id: 370
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn2 actual_nn2 &&\n' span_id:371) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:de/adbeef > actual_nn3 &&\n'
            span_id: 372
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn3 actual_nn3 &&\n' span_id:373) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:dead/beef > actual_nn4 &&\n'
            span_id: 374
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn4 actual_nn4\n' span_id:375)
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('git-notes preserves non-notes'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:386) (Token id:Id.Lit_Chars val:'\n' span_id:387) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:388) (Token id:Id.Lit_Chars val:'\tgit notes add -f -m "foo bar"\n' span_id:389)
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('verify contents of non-notes after git-notes'))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:400) (Token id:Id.Lit_Chars val:'\n' span_id:401) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:foobar/non-note.txt > actual_nn1 &&\n'
            span_id: 402
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn1 actual_nn1 &&\n' span_id:403) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:deadbeef > actual_nn2 &&\n'
            span_id: 404
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn2 actual_nn2 &&\n' span_id:405) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:de/adbeef > actual_nn3 &&\n'
            span_id: 406
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn3 actual_nn3 &&\n' span_id:407) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit cat-file -p refs/notes/commits:dead/beef > actual_nn4 &&\n'
            span_id: 408
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect_nn4 actual_nn4\n' span_id:409)
        )
      }
    )
    (C {(test_done)})
  ]
)