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
10 TEST_PASSES_SANITIZE_LEAK
=true
15 cat >input
<<INPUT_END
16 commit refs/heads/main
17 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
24 file foo in first commit
29 file bar in first commit
32 M 644 inline baz/xyzzy
34 file baz/xyzzy in first commit
37 commit refs/heads/main
38 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
45 file foo in second commit
48 M 755 inline baz/xyzzy
50 file baz/xyzzy in second commit
53 commit refs/heads/main
54 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
61 file foo in third commit
64 commit refs/heads/main
65 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
72 file bar in fourth commit
77 test_expect_success
'set up main branch' '
79 git fast-import <input &&
83 commit4
=$
(git rev-parse refs
/heads
/main
)
84 commit3
=$
(git rev-parse
"$commit4^")
85 commit2
=$
(git rev-parse
"$commit4~2")
86 commit1
=$
(git rev-parse
"$commit4~3")
89 cat >input
<<INPUT_END
90 commit refs/notes/test
91 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
98 first note for first commit
101 M 755 inline $commit2
103 first note for second commit
108 cat >expect
<<EXPECT_END
112 first note for second commit
114 first note for first commit
117 test_expect_success
'add notes with simple M command' '
119 git fast-import <input &&
120 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
121 test_cmp expect actual
126 cat >input
<<INPUT_END
128 commit refs/notes/test
129 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
134 from refs/notes/test^0
137 first note for third commit
142 first note for fourth commit
147 cat >expect
<<EXPECT_END
149 first note for fourth commit
151 first note for third commit
153 first note for second commit
155 first note for first commit
158 test_expect_success
'add notes with simple N command' '
160 git fast-import <input &&
161 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
162 test_cmp expect actual
167 cat >input
<<INPUT_END
168 commit refs/notes/test
169 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
174 from refs/notes/test^0
177 second note for first commit
182 second note for second commit
187 second note for third commit
192 second note for fourth commit
197 cat >expect
<<EXPECT_END
199 second note for fourth commit
201 second note for third commit
203 second note for second commit
205 second note for first commit
208 test_expect_success
'update existing notes with N command' '
210 git fast-import <input &&
211 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
212 test_cmp expect actual
217 cat >input
<<INPUT_END
218 commit refs/notes/test
219 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
224 from refs/notes/test^0
225 M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
227 prefix of note for third commit
230 M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
232 prefix of note for fourth commit
235 M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
237 pre-prefix of note for fourth commit
242 third note for first commit
247 third note for second commit
252 third note for third commit
257 third note for fourth commit
265 cat >expect
<<EXPECT_END
267 pre-prefix of note for fourth commit
269 prefix of note for fourth commit
271 third note for fourth commit
273 prefix of note for third commit
275 third note for third commit
277 third note for second commit
279 third note for first commit
282 test_expect_success
'add concatenation notes with M command' '
284 git fast-import <input &&
285 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
286 test_cmp expect actual
291 cat >input
<<INPUT_END
292 commit refs/notes/test
293 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
298 from refs/notes/test^0
303 cat >expect
<<EXPECT_END
310 test_expect_success
'verify that deleteall also removes notes' '
312 git fast-import <input &&
313 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
314 test_cmp expect actual
319 cat >input
<<INPUT_END
320 commit refs/notes/test
321 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
326 from refs/notes/test^0
327 M 644 inline $commit1
329 third note for first commit
332 M 644 inline $commit3
334 third note for third commit
339 fourth note for first commit
344 fourth note for third commit
349 cat >expect
<<EXPECT_END
352 fourth note for third commit
355 fourth note for first commit
358 test_expect_success
'verify that later N commands override earlier M commands' '
360 git fast-import <input &&
361 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
362 test_cmp expect actual
366 # Write fast-import commands to create the given number of commits
367 fast_import_commits
() {
372 while test $my_i -lt $my_num_commits
376 cat >>"$my_append_to_file" <<INPUT_END
379 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
386 file contents in commit #$my_i
393 # Write fast-import commands to create the given number of notes annotating
394 # the commits created by fast_import_commits()
395 fast_import_notes
() {
401 cat >>"$my_append_to_file" <<INPUT_END
403 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
405 committing $my_num_commits notes
411 while test $my_i -lt $my_num_commits
414 cat >>"$my_append_to_file" <<INPUT_END
417 note for commit #$my_i$my_note_append
427 # Create lots of commits
428 fast_import_commits
"refs/heads/many_commits" $num_commits input
429 # Create one note per above commit
430 fast_import_notes
"refs/notes/many_notes" $num_commits input
431 # Add a couple of non-notes as well
433 cat >>input
<<INPUT_END
434 commit refs/notes/many_notes
435 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
437 committing some non-notes to the notes tree
440 M 755 inline foobar/non-note.txt
442 This is not a note, but rather a regular file residing in a notes tree
445 M 644 inline deadbeef
450 M 644 inline de/adbeef
452 Another non-note file
456 # Finally create the expected output from all these notes and commits
460 cat >>expect
<<EXPECT_END
467 test_expect_success
'add lots of commits and notes' '
469 git fast-import <input &&
470 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
471 grep "^ " > actual &&
472 test_cmp expect actual
476 test_expect_success
'verify that lots of notes trigger a fanout scheme' '
477 hexsz=$(test_oid hexsz) &&
479 # None of the entries in the top-level notes tree should be a full SHA1
480 git ls-tree --name-only refs/notes/many_notes |
483 if test $(expr length "$path") -ge $hexsz
491 # Create another notes tree from the one above
493 cat >>input
<<INPUT_END
494 commit refs/heads/other_commits
495 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
497 commit #$(($num_commit + 1))
500 from refs/heads/many_commits
503 file contents in commit #$(($num_commit + 1))
506 commit refs/notes/other_notes
507 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
509 committing one more note on a tree imported from a previous notes tree
512 M 040000 $(git log --no-walk --format=%T refs/notes/many_notes)$SP
513 N inline :$(($num_commit + 1))
515 note for commit #$(($num_commit + 1))
519 test_expect_success
'verify that importing a notes tree respects the fanout scheme' '
520 git fast-import <input &&
522 # None of the entries in the top-level notes tree should be a full SHA1
523 git ls-tree --name-only refs/notes/other_notes |
526 if test $(expr length "$path") -ge $hexsz
533 cat >>expect_non-note1
<< EOF
534 This is not a note, but rather a regular file residing in a notes tree
537 cat >>expect_non-note2
<< EOF
541 cat >>expect_non-note3
<< EOF
542 Another non-note file
545 test_expect_success
'verify that non-notes are untouched by a fanout change' '
547 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
548 test_cmp expect_non-note1 actual &&
549 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
550 test_cmp expect_non-note2 actual &&
551 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
552 test_cmp expect_non-note3 actual
556 # Change the notes for the three top commits
558 cat >input
<<INPUT_END
559 commit refs/notes/many_notes
560 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
562 changing notes for the top three commits
564 from refs/notes/many_notes^0
572 cat >>input
<<INPUT_END
573 N inline refs/heads/many_commits~$j
575 changed note for commit #$i
578 cat >>expect
<<EXPECT_END
580 changed note for commit #$i
586 test_expect_success
'change a few existing notes' '
588 git fast-import <input &&
589 GIT_NOTES_REF=refs/notes/many_notes git log -n3 refs/heads/many_commits |
590 grep "^ " > actual &&
591 test_cmp expect actual
595 test_expect_success
'verify that changing notes respect existing fanout' '
597 # None of the entries in the top-level notes tree should be a full SHA1
598 git ls-tree --name-only refs/notes/many_notes |
601 if test $(expr length "$path") -ge $hexsz
611 cat >input
<<INPUT_END
612 commit refs/notes/many_notes
613 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
615 removing all notes but $remaining_notes
617 from refs/notes/many_notes^0
620 i
=$
(($num_commits - $remaining_notes))
621 for sha1
in $
(git rev-list
-n $i refs
/heads
/many_commits
)
623 cat >>input
<<INPUT_END
632 cat >>expect
<<EXPECT_END
635 if test $i -le $remaining_notes
637 cat >>expect
<<EXPECT_END
644 test_expect_success
'remove lots of notes' '
646 git fast-import <input &&
647 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
648 grep "^ " > actual &&
649 test_cmp expect actual
653 test_expect_success
'verify that removing notes trigger fanout consolidation' '
654 # All entries in the top-level notes tree should be a full SHA1
655 git ls-tree --name-only -r refs/notes/many_notes |
658 # Explicitly ignore the non-note paths
659 test "$path" = "foobar/non-note.txt" && continue
660 test "$path" = "deadbeef" && continue
661 test "$path" = "de/adbeef" && continue
663 if test $(expr length "$path") -ne $hexsz
671 test_expect_success
'verify that non-notes are untouched by a fanout change' '
673 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
674 test_cmp expect_non-note1 actual &&
675 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
676 test_cmp expect_non-note2 actual &&
677 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
678 test_cmp expect_non-note3 actual
688 fast_import_commits
"refs/heads/more_commits" $num_commits input
689 # Create one note per above commit per notes ref
691 while test $i -lt $num_notes_refs
694 fast_import_notes
"refs/notes/more_notes_$i" $num_commits input
696 # Trigger branch reloading in git-fast-import by repeating the note creation
698 while test $i -lt $num_notes_refs
701 fast_import_notes
"refs/notes/more_notes_$i" $some_commits input
" (2)"
703 # Finally create the expected output from the notes in refs/notes/more_notes_1
707 note_data
="note for commit #$i"
708 if test $i -le $some_commits
710 note_data
="$note_data (2)"
712 cat >>expect
<<EXPECT_END
719 test_expect_success
"add notes to $num_commits commits in each of $num_notes_refs refs" '
721 git fast-import --active-branches=5 <input &&
722 GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
723 grep "^ " > actual &&
724 test_cmp expect actual