3 # Copyright (c) 2009 Johan Herland
6 test_description='test git fast-import of notes objects'
11 cat >input <<INPUT_END
12 commit refs/heads/master
13 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
20 file foo in first commit
25 file bar in first commit
28 M 644 inline baz/xyzzy
30 file baz/xyzzy in first commit
33 commit refs/heads/master
34 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
41 file foo in second commit
44 M 755 inline baz/xyzzy
46 file baz/xyzzy in second commit
49 commit refs/heads/master
50 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
57 file foo in third commit
60 commit refs/heads/master
61 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
68 file bar in fourth commit
73 test_expect_success 'set up master branch' '
75 git fast-import <input &&
76 git whatchanged master
79 commit4=$(git rev-parse refs/heads/master)
80 commit3=$(git rev-parse "$commit4^")
81 commit2=$(git rev-parse "$commit4~2")
82 commit1=$(git rev-parse "$commit4~3")
85 cat >input <<INPUT_END
86 commit refs/notes/test
87 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
94 first note for first commit
99 first note for second commit
104 cat >expect <<EXPECT_END
108 first note for second commit
110 first note for first commit
113 test_expect_success 'add notes with simple M command' '
115 git fast-import <input &&
116 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
117 test_cmp expect actual
122 cat >input <<INPUT_END
124 commit refs/notes/test
125 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
130 from refs/notes/test^0
133 first note for third commit
138 first note for fourth commit
143 cat >expect <<EXPECT_END
145 first note for fourth commit
147 first note for third commit
149 first note for second commit
151 first note for first commit
154 test_expect_success 'add notes with simple N command' '
156 git fast-import <input &&
157 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
158 test_cmp expect actual
163 cat >input <<INPUT_END
164 commit refs/notes/test
165 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
170 from refs/notes/test^0
173 second note for first commit
178 second note for second commit
183 second note for third commit
188 second note for fourth commit
193 cat >expect <<EXPECT_END
195 second note for fourth commit
197 second note for third commit
199 second note for second commit
201 second note for first commit
204 test_expect_success 'update existing notes with N command' '
206 git fast-import <input &&
207 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
208 test_cmp expect actual
213 cat >input <<INPUT_END
214 commit refs/notes/test
215 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
220 from refs/notes/test^0
221 M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
223 prefix of note for third commit
226 M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
228 prefix of note for fourth commit
231 M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
233 pre-prefix of note for fourth commit
238 third note for first commit
243 third note for second commit
248 third note for third commit
253 third note for fourth commit
261 cat >expect <<EXPECT_END
263 pre-prefix of note for fourth commit
265 prefix of note for fourth commit
267 third note for fourth commit
269 prefix of note for third commit
271 third note for third commit
273 third note for second commit
275 third note for first commit
278 test_expect_success 'add concatenation notes with M command' '
280 git fast-import <input &&
281 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
282 test_cmp expect actual
287 cat >input <<INPUT_END
288 commit refs/notes/test
289 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
294 from refs/notes/test^0
299 cat >expect <<EXPECT_END
306 test_expect_success 'verify that deleteall also removes notes' '
308 git fast-import <input &&
309 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
310 test_cmp expect actual
315 cat >input <<INPUT_END
316 commit refs/notes/test
317 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
322 from refs/notes/test^0
323 M 644 inline $commit1
325 third note for first commit
328 M 644 inline $commit3
330 third note for third commit
335 fourth note for first commit
340 fourth note for third commit
345 cat >expect <<EXPECT_END
348 fourth note for third commit
351 fourth note for first commit
354 test_expect_success 'verify that later N commands override earlier M commands' '
356 git fast-import <input &&
357 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
358 test_cmp expect actual
362 # Write fast-import commands to create the given number of commits
363 fast_import_commits () {
368 while test $my_i -lt $my_num_commits
372 cat >>"$my_append_to_file" <<INPUT_END
375 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
382 file contents in commit #$my_i
389 # Write fast-import commands to create the given number of notes annotating
390 # the commits created by fast_import_commits()
391 fast_import_notes () {
397 cat >>"$my_append_to_file" <<INPUT_END
399 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
401 committing $my_num_commits notes
407 while test $my_i -lt $my_num_commits
410 cat >>"$my_append_to_file" <<INPUT_END
413 note for commit #$my_i$my_note_append
423 # Create lots of commits
424 fast_import_commits "refs/heads/many_commits" $num_commits input
425 # Create one note per above commit
426 fast_import_notes "refs/notes/many_notes" $num_commits input
427 # Add a couple of non-notes as well
429 cat >>input <<INPUT_END
430 commit refs/notes/many_notes
431 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
433 committing some non-notes to the notes tree
436 M 755 inline foobar/non-note.txt
438 This is not a note, but rather a regular file residing in a notes tree
441 M 644 inline deadbeef
446 M 644 inline de/adbeef
448 Another non-note file
452 # Finally create the expected output from all these notes and commits
456 cat >>expect <<EXPECT_END
463 test_expect_success 'add lots of commits and notes' '
465 git fast-import <input &&
466 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
467 grep "^ " > actual &&
468 test_cmp expect actual
472 test_expect_success 'verify that lots of notes trigger a fanout scheme' '
473 hexsz=$(test_oid hexsz) &&
475 # None of the entries in the top-level notes tree should be a full SHA1
476 git ls-tree --name-only refs/notes/many_notes |
479 if test $(expr length "$path") -ge $hexsz
487 # Create another notes tree from the one above
489 cat >>input <<INPUT_END
490 commit refs/heads/other_commits
491 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
493 commit #$(($num_commit + 1))
496 from refs/heads/many_commits
499 file contents in commit #$(($num_commit + 1))
502 commit refs/notes/other_notes
503 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
505 committing one more note on a tree imported from a previous notes tree
508 M 040000 $(git log --no-walk --format=%T refs/notes/many_notes)$SP
509 N inline :$(($num_commit + 1))
511 note for commit #$(($num_commit + 1))
515 test_expect_success 'verify that importing a notes tree respects the fanout scheme' '
516 git fast-import <input &&
518 # None of the entries in the top-level notes tree should be a full SHA1
519 git ls-tree --name-only refs/notes/other_notes |
522 if test $(expr length "$path") -ge $hexsz
529 cat >>expect_non-note1 << EOF
530 This is not a note, but rather a regular file residing in a notes tree
533 cat >>expect_non-note2 << EOF
537 cat >>expect_non-note3 << EOF
538 Another non-note file
541 test_expect_success 'verify that non-notes are untouched by a fanout change' '
543 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
544 test_cmp expect_non-note1 actual &&
545 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
546 test_cmp expect_non-note2 actual &&
547 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
548 test_cmp expect_non-note3 actual
552 # Change the notes for the three top commits
554 cat >input <<INPUT_END
555 commit refs/notes/many_notes
556 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
558 changing notes for the top three commits
560 from refs/notes/many_notes^0
568 cat >>input <<INPUT_END
569 N inline refs/heads/many_commits~$j
571 changed note for commit #$i
574 cat >>expect <<EXPECT_END
576 changed note for commit #$i
582 test_expect_success 'change a few existing notes' '
584 git fast-import <input &&
585 GIT_NOTES_REF=refs/notes/many_notes git log -n3 refs/heads/many_commits |
586 grep "^ " > actual &&
587 test_cmp expect actual
591 test_expect_success 'verify that changing notes respect existing fanout' '
593 # None of the entries in the top-level notes tree should be a full SHA1
594 git ls-tree --name-only refs/notes/many_notes |
597 if test $(expr length "$path") -ge $hexsz
607 cat >input <<INPUT_END
608 commit refs/notes/many_notes
609 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
611 removing all notes but $remaining_notes
613 from refs/notes/many_notes^0
616 i=$(($num_commits - $remaining_notes))
617 for sha1 in $(git rev-list -n $i refs/heads/many_commits)
619 cat >>input <<INPUT_END
628 cat >>expect <<EXPECT_END
631 if test $i -le $remaining_notes
633 cat >>expect <<EXPECT_END
640 test_expect_success 'remove lots of notes' '
642 git fast-import <input &&
643 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
644 grep "^ " > actual &&
645 test_cmp expect actual
649 test_expect_success 'verify that removing notes trigger fanout consolidation' '
650 # All entries in the top-level notes tree should be a full SHA1
651 git ls-tree --name-only -r refs/notes/many_notes |
654 # Explicitly ignore the non-note paths
655 test "$path" = "foobar/non-note.txt" && continue
656 test "$path" = "deadbeef" && continue
657 test "$path" = "de/adbeef" && continue
659 if test $(expr length "$path") -ne $hexsz
667 test_expect_success 'verify that non-notes are untouched by a fanout change' '
669 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
670 test_cmp expect_non-note1 actual &&
671 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
672 test_cmp expect_non-note2 actual &&
673 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
674 test_cmp expect_non-note3 actual
684 fast_import_commits "refs/heads/more_commits" $num_commits input
685 # Create one note per above commit per notes ref
687 while test $i -lt $num_notes_refs
690 fast_import_notes "refs/notes/more_notes_$i" $num_commits input
692 # Trigger branch reloading in git-fast-import by repeating the note creation
694 while test $i -lt $num_notes_refs
697 fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
699 # Finally create the expected output from the notes in refs/notes/more_notes_1
703 note_data="note for commit #$i"
704 if test $i -le $some_commits
706 note_data="$note_data (2)"
708 cat >>expect <<EXPECT_END
715 test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
717 git fast-import --active-branches=5 <input &&
718 GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
719 grep "^ " > actual &&
720 test_cmp expect actual