(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)}) ] )