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