]> git.ipfire.org Git - thirdparty/git.git/blob - t/t9301-fast-import-notes.sh
The third batch
[thirdparty/git.git] / t / t9301-fast-import-notes.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2009 Johan Herland
4 #
5
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
9
10 TEST_PASSES_SANITIZE_LEAK=true
11 . ./test-lib.sh
12
13
14 test_tick
15 cat >input <<INPUT_END
16 commit refs/heads/main
17 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
18 data <<COMMIT
19 first commit
20 COMMIT
21
22 M 644 inline foo
23 data <<EOF
24 file foo in first commit
25 EOF
26
27 M 755 inline bar
28 data <<EOF
29 file bar in first commit
30 EOF
31
32 M 644 inline baz/xyzzy
33 data <<EOF
34 file baz/xyzzy in first commit
35 EOF
36
37 commit refs/heads/main
38 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
39 data <<COMMIT
40 second commit
41 COMMIT
42
43 M 644 inline foo
44 data <<EOF
45 file foo in second commit
46 EOF
47
48 M 755 inline baz/xyzzy
49 data <<EOF
50 file baz/xyzzy in second commit
51 EOF
52
53 commit refs/heads/main
54 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
55 data <<COMMIT
56 third commit
57 COMMIT
58
59 M 644 inline foo
60 data <<EOF
61 file foo in third commit
62 EOF
63
64 commit refs/heads/main
65 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
66 data <<COMMIT
67 fourth commit
68 COMMIT
69
70 M 755 inline bar
71 data <<EOF
72 file bar in fourth commit
73 EOF
74
75 INPUT_END
76
77 test_expect_success 'set up main branch' '
78
79 git fast-import <input &&
80 git whatchanged main
81 '
82
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")
87
88 test_tick
89 cat >input <<INPUT_END
90 commit refs/notes/test
91 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
92 data <<COMMIT
93 first notes commit
94 COMMIT
95
96 M 644 inline $commit1
97 data <<EOF
98 first note for first commit
99 EOF
100
101 M 755 inline $commit2
102 data <<EOF
103 first note for second commit
104 EOF
105
106 INPUT_END
107
108 cat >expect <<EXPECT_END
109 fourth commit
110 third commit
111 second commit
112 first note for second commit
113 first commit
114 first note for first commit
115 EXPECT_END
116
117 test_expect_success 'add notes with simple M command' '
118
119 git fast-import <input &&
120 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
121 test_cmp expect actual
122
123 '
124
125 test_tick
126 cat >input <<INPUT_END
127 feature notes
128 commit refs/notes/test
129 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
130 data <<COMMIT
131 second notes commit
132 COMMIT
133
134 from refs/notes/test^0
135 N inline $commit3
136 data <<EOF
137 first note for third commit
138 EOF
139
140 N inline $commit4
141 data <<EOF
142 first note for fourth commit
143 EOF
144
145 INPUT_END
146
147 cat >expect <<EXPECT_END
148 fourth commit
149 first note for fourth commit
150 third commit
151 first note for third commit
152 second commit
153 first note for second commit
154 first commit
155 first note for first commit
156 EXPECT_END
157
158 test_expect_success 'add notes with simple N command' '
159
160 git fast-import <input &&
161 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
162 test_cmp expect actual
163
164 '
165
166 test_tick
167 cat >input <<INPUT_END
168 commit refs/notes/test
169 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
170 data <<COMMIT
171 third notes commit
172 COMMIT
173
174 from refs/notes/test^0
175 N inline $commit1
176 data <<EOF
177 second note for first commit
178 EOF
179
180 N inline $commit2
181 data <<EOF
182 second note for second commit
183 EOF
184
185 N inline $commit3
186 data <<EOF
187 second note for third commit
188 EOF
189
190 N inline $commit4
191 data <<EOF
192 second note for fourth commit
193 EOF
194
195 INPUT_END
196
197 cat >expect <<EXPECT_END
198 fourth commit
199 second note for fourth commit
200 third commit
201 second note for third commit
202 second commit
203 second note for second commit
204 first commit
205 second note for first commit
206 EXPECT_END
207
208 test_expect_success 'update existing notes with N command' '
209
210 git fast-import <input &&
211 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
212 test_cmp expect actual
213
214 '
215
216 test_tick
217 cat >input <<INPUT_END
218 commit refs/notes/test
219 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
220 data <<COMMIT
221 fourth notes commit
222 COMMIT
223
224 from refs/notes/test^0
225 M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
226 data <<EOF
227 prefix of note for third commit
228 EOF
229
230 M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
231 data <<EOF
232 prefix of note for fourth commit
233 EOF
234
235 M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
236 data <<EOF
237 pre-prefix of note for fourth commit
238 EOF
239
240 N inline $commit1
241 data <<EOF
242 third note for first commit
243 EOF
244
245 N inline $commit2
246 data <<EOF
247 third note for second commit
248 EOF
249
250 N inline $commit3
251 data <<EOF
252 third note for third commit
253 EOF
254
255 N inline $commit4
256 data <<EOF
257 third note for fourth commit
258 EOF
259
260
261 INPUT_END
262
263 whitespace=" "
264
265 cat >expect <<EXPECT_END
266 fourth commit
267 pre-prefix of note for fourth commit
268 $whitespace
269 prefix of note for fourth commit
270 $whitespace
271 third note for fourth commit
272 third commit
273 prefix of note for third commit
274 $whitespace
275 third note for third commit
276 second commit
277 third note for second commit
278 first commit
279 third note for first commit
280 EXPECT_END
281
282 test_expect_success 'add concatenation notes with M command' '
283
284 git fast-import <input &&
285 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
286 test_cmp expect actual
287
288 '
289
290 test_tick
291 cat >input <<INPUT_END
292 commit refs/notes/test
293 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
294 data <<COMMIT
295 fifth notes commit
296 COMMIT
297
298 from refs/notes/test^0
299 deleteall
300
301 INPUT_END
302
303 cat >expect <<EXPECT_END
304 fourth commit
305 third commit
306 second commit
307 first commit
308 EXPECT_END
309
310 test_expect_success 'verify that deleteall also removes notes' '
311
312 git fast-import <input &&
313 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
314 test_cmp expect actual
315
316 '
317
318 test_tick
319 cat >input <<INPUT_END
320 commit refs/notes/test
321 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
322 data <<COMMIT
323 sixth notes commit
324 COMMIT
325
326 from refs/notes/test^0
327 M 644 inline $commit1
328 data <<EOF
329 third note for first commit
330 EOF
331
332 M 644 inline $commit3
333 data <<EOF
334 third note for third commit
335 EOF
336
337 N inline $commit1
338 data <<EOF
339 fourth note for first commit
340 EOF
341
342 N inline $commit3
343 data <<EOF
344 fourth note for third commit
345 EOF
346
347 INPUT_END
348
349 cat >expect <<EXPECT_END
350 fourth commit
351 third commit
352 fourth note for third commit
353 second commit
354 first commit
355 fourth note for first commit
356 EXPECT_END
357
358 test_expect_success 'verify that later N commands override earlier M commands' '
359
360 git fast-import <input &&
361 GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual &&
362 test_cmp expect actual
363
364 '
365
366 # Write fast-import commands to create the given number of commits
367 fast_import_commits () {
368 my_ref=$1
369 my_num_commits=$2
370 my_append_to_file=$3
371 my_i=0
372 while test $my_i -lt $my_num_commits
373 do
374 my_i=$(($my_i + 1))
375 test_tick
376 cat >>"$my_append_to_file" <<INPUT_END
377 commit $my_ref
378 mark :$my_i
379 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
380 data <<COMMIT
381 commit #$my_i
382 COMMIT
383
384 M 644 inline file
385 data <<EOF
386 file contents in commit #$my_i
387 EOF
388
389 INPUT_END
390 done
391 }
392
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 () {
396 my_notes_ref=$1
397 my_num_commits=$2
398 my_append_to_file=$3
399 my_note_append=$4
400 test_tick
401 cat >>"$my_append_to_file" <<INPUT_END
402 commit $my_notes_ref
403 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
404 data <<COMMIT
405 committing $my_num_commits notes
406 COMMIT
407
408 INPUT_END
409
410 my_i=0
411 while test $my_i -lt $my_num_commits
412 do
413 my_i=$(($my_i + 1))
414 cat >>"$my_append_to_file" <<INPUT_END
415 N inline :$my_i
416 data <<EOF
417 note for commit #$my_i$my_note_append
418 EOF
419
420 INPUT_END
421 done
422 }
423
424
425 rm input expect
426 num_commits=400
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
432 test_tick
433 cat >>input <<INPUT_END
434 commit refs/notes/many_notes
435 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
436 data <<COMMIT
437 committing some non-notes to the notes tree
438 COMMIT
439
440 M 755 inline foobar/non-note.txt
441 data <<EOF
442 This is not a note, but rather a regular file residing in a notes tree
443 EOF
444
445 M 644 inline deadbeef
446 data <<EOF
447 Non-note file
448 EOF
449
450 M 644 inline de/adbeef
451 data <<EOF
452 Another non-note file
453 EOF
454
455 INPUT_END
456 # Finally create the expected output from all these notes and commits
457 i=$num_commits
458 while test $i -gt 0
459 do
460 cat >>expect <<EXPECT_END
461 commit #$i
462 note for commit #$i
463 EXPECT_END
464 i=$(($i - 1))
465 done
466
467 test_expect_success 'add lots of commits and notes' '
468
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
473
474 '
475
476 test_expect_success 'verify that lots of notes trigger a fanout scheme' '
477 hexsz=$(test_oid hexsz) &&
478
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 |
481 while read path
482 do
483 if test $(expr length "$path") -ge $hexsz
484 then
485 return 1
486 fi
487 done
488
489 '
490
491 # Create another notes tree from the one above
492 SP=" "
493 cat >>input <<INPUT_END
494 commit refs/heads/other_commits
495 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
496 data <<COMMIT
497 commit #$(($num_commit + 1))
498 COMMIT
499
500 from refs/heads/many_commits
501 M 644 inline file
502 data <<EOF
503 file contents in commit #$(($num_commit + 1))
504 EOF
505
506 commit refs/notes/other_notes
507 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
508 data <<COMMIT
509 committing one more note on a tree imported from a previous notes tree
510 COMMIT
511
512 M 040000 $(git log --no-walk --format=%T refs/notes/many_notes)$SP
513 N inline :$(($num_commit + 1))
514 data <<EOF
515 note for commit #$(($num_commit + 1))
516 EOF
517 INPUT_END
518
519 test_expect_success 'verify that importing a notes tree respects the fanout scheme' '
520 git fast-import <input &&
521
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 |
524 while read path
525 do
526 if test $(expr length "$path") -ge $hexsz
527 then
528 return 1
529 fi
530 done
531 '
532
533 cat >>expect_non-note1 << EOF
534 This is not a note, but rather a regular file residing in a notes tree
535 EOF
536
537 cat >>expect_non-note2 << EOF
538 Non-note file
539 EOF
540
541 cat >>expect_non-note3 << EOF
542 Another non-note file
543 EOF
544
545 test_expect_success 'verify that non-notes are untouched by a fanout change' '
546
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
553
554 '
555
556 # Change the notes for the three top commits
557 test_tick
558 cat >input <<INPUT_END
559 commit refs/notes/many_notes
560 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
561 data <<COMMIT
562 changing notes for the top three commits
563 COMMIT
564 from refs/notes/many_notes^0
565 INPUT_END
566
567 rm expect
568 i=$num_commits
569 j=0
570 while test $j -lt 3
571 do
572 cat >>input <<INPUT_END
573 N inline refs/heads/many_commits~$j
574 data <<EOF
575 changed note for commit #$i
576 EOF
577 INPUT_END
578 cat >>expect <<EXPECT_END
579 commit #$i
580 changed note for commit #$i
581 EXPECT_END
582 i=$(($i - 1))
583 j=$(($j + 1))
584 done
585
586 test_expect_success 'change a few existing notes' '
587
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
592
593 '
594
595 test_expect_success 'verify that changing notes respect existing fanout' '
596
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 |
599 while read path
600 do
601 if test $(expr length "$path") -ge $hexsz
602 then
603 return 1
604 fi
605 done
606
607 '
608
609 remaining_notes=10
610 test_tick
611 cat >input <<INPUT_END
612 commit refs/notes/many_notes
613 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
614 data <<COMMIT
615 removing all notes but $remaining_notes
616 COMMIT
617 from refs/notes/many_notes^0
618 INPUT_END
619
620 i=$(($num_commits - $remaining_notes))
621 for sha1 in $(git rev-list -n $i refs/heads/many_commits)
622 do
623 cat >>input <<INPUT_END
624 N $ZERO_OID $sha1
625 INPUT_END
626 done
627
628 i=$num_commits
629 rm expect
630 while test $i -gt 0
631 do
632 cat >>expect <<EXPECT_END
633 commit #$i
634 EXPECT_END
635 if test $i -le $remaining_notes
636 then
637 cat >>expect <<EXPECT_END
638 note for commit #$i
639 EXPECT_END
640 fi
641 i=$(($i - 1))
642 done
643
644 test_expect_success 'remove lots of notes' '
645
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
650
651 '
652
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 |
656 while read path
657 do
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
662
663 if test $(expr length "$path") -ne $hexsz
664 then
665 return 1
666 fi
667 done
668
669 '
670
671 test_expect_success 'verify that non-notes are untouched by a fanout change' '
672
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
679
680 '
681
682
683 rm input expect
684 num_notes_refs=10
685 num_commits=16
686 some_commits=8
687 # Create commits
688 fast_import_commits "refs/heads/more_commits" $num_commits input
689 # Create one note per above commit per notes ref
690 i=0
691 while test $i -lt $num_notes_refs
692 do
693 i=$(($i + 1))
694 fast_import_notes "refs/notes/more_notes_$i" $num_commits input
695 done
696 # Trigger branch reloading in git-fast-import by repeating the note creation
697 i=0
698 while test $i -lt $num_notes_refs
699 do
700 i=$(($i + 1))
701 fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
702 done
703 # Finally create the expected output from the notes in refs/notes/more_notes_1
704 i=$num_commits
705 while test $i -gt 0
706 do
707 note_data="note for commit #$i"
708 if test $i -le $some_commits
709 then
710 note_data="$note_data (2)"
711 fi
712 cat >>expect <<EXPECT_END
713 commit #$i
714 $note_data
715 EXPECT_END
716 i=$(($i - 1))
717 done
718
719 test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
720
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
725
726 '
727
728 test_done