3 # Copyright (c) 2009 Johan Herland
6 test_description='test git fast-import of notes objects'
7 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
8 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
14 cat >input <<INPUT_END
15 commit refs/heads/main
16 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
23 file foo in first commit
28 file bar in first commit
31 M 644 inline baz/xyzzy
33 file baz/xyzzy in first commit
36 commit refs/heads/main
37 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
44 file foo in second commit
47 M 755 inline baz/xyzzy
49 file baz/xyzzy in second commit
52 commit refs/heads/main
53 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
60 file foo in third commit
63 commit refs/heads/main
64 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
71 file bar in fourth commit
76 test_expect_success 'set up main branch' '
78 git fast-import <input &&
82 commit4=$(git rev-parse refs/heads/main)
83 commit3=$(git rev-parse "$commit4^")
84 commit2=$(git rev-parse "$commit4~2")
85 commit1=$(git rev-parse "$commit4~3")
88 cat >input <<INPUT_END
89 commit refs/notes/test
90 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
97 first note for first commit
100 M 755 inline $commit2
102 first note for second commit
107 cat >expect <<EXPECT_END
111 first note for second commit
113 first note for first commit
116 test_expect_success 'add notes with simple M command' '
118 git fast-import <input &&
119 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
120 test_cmp expect actual
125 cat >input <<INPUT_END
127 commit refs/notes/test
128 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
133 from refs/notes/test^0
136 first note for third commit
141 first note for fourth commit
146 cat >expect <<EXPECT_END
148 first note for fourth commit
150 first note for third commit
152 first note for second commit
154 first note for first commit
157 test_expect_success 'add notes with simple N command' '
159 git fast-import <input &&
160 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
161 test_cmp expect actual
166 cat >input <<INPUT_END
167 commit refs/notes/test
168 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
173 from refs/notes/test^0
176 second note for first commit
181 second note for second commit
186 second note for third commit
191 second note for fourth commit
196 cat >expect <<EXPECT_END
198 second note for fourth commit
200 second note for third commit
202 second note for second commit
204 second note for first commit
207 test_expect_success 'update existing notes with N command' '
209 git fast-import <input &&
210 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
211 test_cmp expect actual
216 cat >input <<INPUT_END
217 commit refs/notes/test
218 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
223 from refs/notes/test^0
224 M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
226 prefix of note for third commit
229 M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
231 prefix of note for fourth commit
234 M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
236 pre-prefix of note for fourth commit
241 third note for first commit
246 third note for second commit
251 third note for third commit
256 third note for fourth commit
264 cat >expect <<EXPECT_END
266 pre-prefix of note for fourth commit
268 prefix of note for fourth commit
270 third note for fourth commit
272 prefix of note for third commit
274 third note for third commit
276 third note for second commit
278 third note for first commit
281 test_expect_success 'add concatenation notes with M command' '
283 git fast-import <input &&
284 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
285 test_cmp expect actual
290 cat >input <<INPUT_END
291 commit refs/notes/test
292 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
297 from refs/notes/test^0
302 cat >expect <<EXPECT_END
309 test_expect_success 'verify that deleteall also removes notes' '
311 git fast-import <input &&
312 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
313 test_cmp expect actual
318 cat >input <<INPUT_END
319 commit refs/notes/test
320 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
325 from refs/notes/test^0
326 M 644 inline $commit1
328 third note for first commit
331 M 644 inline $commit3
333 third note for third commit
338 fourth note for first commit
343 fourth note for third commit
348 cat >expect <<EXPECT_END
351 fourth note for third commit
354 fourth note for first commit
357 test_expect_success 'verify that later N commands override earlier M commands' '
359 git fast-import <input &&
360 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
361 test_cmp expect actual
365 # Write fast-import commands to create the given number of commits
366 fast_import_commits () {
371 while test $my_i -lt $my_num_commits
375 cat >>"$my_append_to_file" <<INPUT_END
378 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
385 file contents in commit #$my_i
392 # Write fast-import commands to create the given number of notes annotating
393 # the commits created by fast_import_commits()
394 fast_import_notes () {
400 cat >>"$my_append_to_file" <<INPUT_END
402 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
404 committing $my_num_commits notes
410 while test $my_i -lt $my_num_commits
413 cat >>"$my_append_to_file" <<INPUT_END
416 note for commit #$my_i$my_note_append
426 # Create lots of commits
427 fast_import_commits "refs/heads/many_commits" $num_commits input
428 # Create one note per above commit
429 fast_import_notes "refs/notes/many_notes" $num_commits input
430 # Add a couple of non-notes as well
432 cat >>input <<INPUT_END
433 commit refs/notes/many_notes
434 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
436 committing some non-notes to the notes tree
439 M 755 inline foobar/non-note.txt
441 This is not a note, but rather a regular file residing in a notes tree
444 M 644 inline deadbeef
449 M 644 inline de/adbeef
451 Another non-note file
455 # Finally create the expected output from all these notes and commits
459 cat >>expect <<EXPECT_END
466 test_expect_success 'add lots of commits and notes' '
468 git fast-import <input &&
469 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
470 grep "^ " > actual &&
471 test_cmp expect actual
475 test_expect_success 'verify that lots of notes trigger a fanout scheme' '
476 hexsz=$(test_oid hexsz) &&
478 # None of the entries in the top-level notes tree should be a full SHA1
479 git ls-tree --name-only refs/notes/many_notes |
482 if test $(expr length "$path") -ge $hexsz
490 # Create another notes tree from the one above
492 cat >>input <<INPUT_END
493 commit refs/heads/other_commits
494 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
496 commit #$(($num_commit + 1))
499 from refs/heads/many_commits
502 file contents in commit #$(($num_commit + 1))
505 commit refs/notes/other_notes
506 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
508 committing one more note on a tree imported from a previous notes tree
511 M 040000 $(git log --no-walk --format=%T refs/notes/many_notes)$SP
512 N inline :$(($num_commit + 1))
514 note for commit #$(($num_commit + 1))
518 test_expect_success 'verify that importing a notes tree respects the fanout scheme' '
519 git fast-import <input &&
521 # None of the entries in the top-level notes tree should be a full SHA1
522 git ls-tree --name-only refs/notes/other_notes |
525 if test $(expr length "$path") -ge $hexsz
532 cat >>expect_non-note1 << EOF
533 This is not a note, but rather a regular file residing in a notes tree
536 cat >>expect_non-note2 << EOF
540 cat >>expect_non-note3 << EOF
541 Another non-note file
544 test_expect_success 'verify that non-notes are untouched by a fanout change' '
546 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
547 test_cmp expect_non-note1 actual &&
548 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
549 test_cmp expect_non-note2 actual &&
550 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
551 test_cmp expect_non-note3 actual
555 # Change the notes for the three top commits
557 cat >input <<INPUT_END
558 commit refs/notes/many_notes
559 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
561 changing notes for the top three commits
563 from refs/notes/many_notes^0
571 cat >>input <<INPUT_END
572 N inline refs/heads/many_commits~$j
574 changed note for commit #$i
577 cat >>expect <<EXPECT_END
579 changed note for commit #$i
585 test_expect_success 'change a few existing notes' '
587 git fast-import <input &&
588 GIT_NOTES_REF=refs/notes/many_notes git log -n3 refs/heads/many_commits |
589 grep "^ " > actual &&
590 test_cmp expect actual
594 test_expect_success 'verify that changing notes respect existing fanout' '
596 # None of the entries in the top-level notes tree should be a full SHA1
597 git ls-tree --name-only refs/notes/many_notes |
600 if test $(expr length "$path") -ge $hexsz
610 cat >input <<INPUT_END
611 commit refs/notes/many_notes
612 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
614 removing all notes but $remaining_notes
616 from refs/notes/many_notes^0
619 i=$(($num_commits - $remaining_notes))
620 for sha1 in $(git rev-list -n $i refs/heads/many_commits)
622 cat >>input <<INPUT_END
631 cat >>expect <<EXPECT_END
634 if test $i -le $remaining_notes
636 cat >>expect <<EXPECT_END
643 test_expect_success 'remove lots of notes' '
645 git fast-import <input &&
646 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
647 grep "^ " > actual &&
648 test_cmp expect actual
652 test_expect_success 'verify that removing notes trigger fanout consolidation' '
653 # All entries in the top-level notes tree should be a full SHA1
654 git ls-tree --name-only -r refs/notes/many_notes |
657 # Explicitly ignore the non-note paths
658 test "$path" = "foobar/non-note.txt" && continue
659 test "$path" = "deadbeef" && continue
660 test "$path" = "de/adbeef" && continue
662 if test $(expr length "$path") -ne $hexsz
670 test_expect_success 'verify that non-notes are untouched by a fanout change' '
672 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
673 test_cmp expect_non-note1 actual &&
674 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
675 test_cmp expect_non-note2 actual &&
676 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
677 test_cmp expect_non-note3 actual
687 fast_import_commits "refs/heads/more_commits" $num_commits input
688 # Create one note per above commit per notes ref
690 while test $i -lt $num_notes_refs
693 fast_import_notes "refs/notes/more_notes_$i" $num_commits input
695 # Trigger branch reloading in git-fast-import by repeating the note creation
697 while test $i -lt $num_notes_refs
700 fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
702 # Finally create the expected output from the notes in refs/notes/more_notes_1
706 note_data="note for commit #$i"
707 if test $i -le $some_commits
709 note_data="$note_data (2)"
711 cat >>expect <<EXPECT_END
718 test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
720 git fast-import --active-branches=5 <input &&
721 GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
722 grep "^ " > actual &&
723 test_cmp expect actual