]> git.ipfire.org Git - thirdparty/git.git/blame - t/t9301-fast-import-notes.sh
Merge branch 'jk/clone-allow-bare-and-o-together'
[thirdparty/git.git] / t / t9301-fast-import-notes.sh
CommitLineData
a8b59ef5
JH
1#!/bin/sh
2#
3# Copyright (c) 2009 Johan Herland
4#
5
6test_description='test git fast-import of notes objects'
a881baa2 7GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
8export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
9
27472b51 10TEST_PASSES_SANITIZE_LEAK=true
a8b59ef5
JH
11. ./test-lib.sh
12
13
14test_tick
15cat >input <<INPUT_END
a881baa2 16commit refs/heads/main
a8b59ef5
JH
17committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
18data <<COMMIT
19first commit
20COMMIT
21
22M 644 inline foo
23data <<EOF
24file foo in first commit
25EOF
26
27M 755 inline bar
28data <<EOF
29file bar in first commit
30EOF
31
32M 644 inline baz/xyzzy
33data <<EOF
34file baz/xyzzy in first commit
35EOF
36
a881baa2 37commit refs/heads/main
a8b59ef5
JH
38committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
39data <<COMMIT
40second commit
41COMMIT
42
43M 644 inline foo
44data <<EOF
45file foo in second commit
46EOF
47
48M 755 inline baz/xyzzy
49data <<EOF
50file baz/xyzzy in second commit
51EOF
52
a881baa2 53commit refs/heads/main
a8b59ef5
JH
54committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
55data <<COMMIT
56third commit
57COMMIT
58
59M 644 inline foo
60data <<EOF
61file foo in third commit
62EOF
63
a881baa2 64commit refs/heads/main
a8b59ef5
JH
65committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
66data <<COMMIT
67fourth commit
68COMMIT
69
70M 755 inline bar
71data <<EOF
72file bar in fourth commit
73EOF
74
75INPUT_END
76
a881baa2 77test_expect_success 'set up main branch' '
a8b59ef5
JH
78
79 git fast-import <input &&
a881baa2 80 git whatchanged main
a8b59ef5
JH
81'
82
a881baa2 83commit4=$(git rev-parse refs/heads/main)
a8b59ef5
JH
84commit3=$(git rev-parse "$commit4^")
85commit2=$(git rev-parse "$commit4~2")
86commit1=$(git rev-parse "$commit4~3")
87
88test_tick
89cat >input <<INPUT_END
90commit refs/notes/test
91committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
92data <<COMMIT
93first notes commit
94COMMIT
95
96M 644 inline $commit1
97data <<EOF
98first note for first commit
99EOF
100
101M 755 inline $commit2
102data <<EOF
103first note for second commit
104EOF
105
106INPUT_END
107
108cat >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
115EXPECT_END
116
117test_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
125test_tick
126cat >input <<INPUT_END
547e8b92 127feature notes
a8b59ef5
JH
128commit refs/notes/test
129committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
130data <<COMMIT
131second notes commit
132COMMIT
133
134from refs/notes/test^0
135N inline $commit3
136data <<EOF
137first note for third commit
138EOF
139
140N inline $commit4
141data <<EOF
142first note for fourth commit
143EOF
144
145INPUT_END
146
147cat >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
156EXPECT_END
157
158test_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
166test_tick
167cat >input <<INPUT_END
168commit refs/notes/test
169committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
170data <<COMMIT
171third notes commit
172COMMIT
173
174from refs/notes/test^0
175N inline $commit1
176data <<EOF
177second note for first commit
178EOF
179
180N inline $commit2
181data <<EOF
182second note for second commit
183EOF
184
185N inline $commit3
186data <<EOF
187second note for third commit
188EOF
189
190N inline $commit4
191data <<EOF
192second note for fourth commit
193EOF
194
195INPUT_END
196
197cat >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
206EXPECT_END
207
208test_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
216test_tick
217cat >input <<INPUT_END
218commit refs/notes/test
219committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
220data <<COMMIT
221fourth notes commit
222COMMIT
223
224from refs/notes/test^0
225M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
226data <<EOF
227prefix of note for third commit
228EOF
229
230M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
231data <<EOF
232prefix of note for fourth commit
233EOF
234
235M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
236data <<EOF
237pre-prefix of note for fourth commit
238EOF
239
240N inline $commit1
241data <<EOF
242third note for first commit
243EOF
244
245N inline $commit2
246data <<EOF
247third note for second commit
248EOF
249
250N inline $commit3
251data <<EOF
252third note for third commit
253EOF
254
255N inline $commit4
256data <<EOF
257third note for fourth commit
258EOF
259
260
261INPUT_END
262
d4990c4b
JH
263whitespace=" "
264
a8b59ef5
JH
265cat >expect <<EXPECT_END
266 fourth commit
267 pre-prefix of note for fourth commit
d4990c4b 268$whitespace
a8b59ef5 269 prefix of note for fourth commit
d4990c4b 270$whitespace
a8b59ef5
JH
271 third note for fourth commit
272 third commit
273 prefix of note for third commit
d4990c4b 274$whitespace
a8b59ef5
JH
275 third note for third commit
276 second commit
277 third note for second commit
278 first commit
279 third note for first commit
280EXPECT_END
281
4dc8b1c1 282test_expect_success 'add concatenation notes with M command' '
a8b59ef5
JH
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
290test_tick
291cat >input <<INPUT_END
292commit refs/notes/test
293committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
294data <<COMMIT
295fifth notes commit
296COMMIT
297
298from refs/notes/test^0
299deleteall
300
301INPUT_END
302
303cat >expect <<EXPECT_END
304 fourth commit
305 third commit
306 second commit
307 first commit
308EXPECT_END
309
310test_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
318test_tick
319cat >input <<INPUT_END
320commit refs/notes/test
321committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
322data <<COMMIT
323sixth notes commit
324COMMIT
325
326from refs/notes/test^0
327M 644 inline $commit1
328data <<EOF
329third note for first commit
330EOF
331
332M 644 inline $commit3
333data <<EOF
334third note for third commit
335EOF
336
337N inline $commit1
338data <<EOF
339fourth note for first commit
340EOF
341
342N inline $commit3
343data <<EOF
344fourth note for third commit
345EOF
346
347INPUT_END
348
349cat >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
356EXPECT_END
357
358test_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
367fast_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
377commit $my_ref
378mark :$my_i
379committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
380data <<COMMIT
381commit #$my_i
382COMMIT
383
384M 644 inline file
385data <<EOF
386file contents in commit #$my_i
387EOF
388
389INPUT_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()
395fast_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
402commit $my_notes_ref
403committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
404data <<COMMIT
405committing $my_num_commits notes
406COMMIT
407
408INPUT_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
415N inline :$my_i
416data <<EOF
417note for commit #$my_i$my_note_append
418EOF
419
420INPUT_END
421 done
422}
423
424
425rm input expect
426num_commits=400
427# Create lots of commits
428fast_import_commits "refs/heads/many_commits" $num_commits input
429# Create one note per above commit
430fast_import_notes "refs/notes/many_notes" $num_commits input
431# Add a couple of non-notes as well
432test_tick
433cat >>input <<INPUT_END
434commit refs/notes/many_notes
435committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
436data <<COMMIT
437committing some non-notes to the notes tree
438COMMIT
439
440M 755 inline foobar/non-note.txt
441data <<EOF
442This is not a note, but rather a regular file residing in a notes tree
443EOF
444
445M 644 inline deadbeef
446data <<EOF
447Non-note file
448EOF
449
450M 644 inline de/adbeef
451data <<EOF
452Another non-note file
453EOF
454
455INPUT_END
456# Finally create the expected output from all these notes and commits
457i=$num_commits
458while test $i -gt 0
459do
460 cat >>expect <<EXPECT_END
461 commit #$i
462 note for commit #$i
463EXPECT_END
464 i=$(($i - 1))
465done
466
467test_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
476test_expect_success 'verify that lots of notes trigger a fanout scheme' '
b6e50052 477 hexsz=$(test_oid hexsz) &&
a8b59ef5
JH
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
b6e50052 483 if test $(expr length "$path") -ge $hexsz
a8b59ef5
JH
484 then
485 return 1
486 fi
487 done
488
489'
490
405d7f4a
MH
491# Create another notes tree from the one above
492SP=" "
493cat >>input <<INPUT_END
494commit refs/heads/other_commits
495committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
496data <<COMMIT
497commit #$(($num_commit + 1))
498COMMIT
499
500from refs/heads/many_commits
501M 644 inline file
502data <<EOF
503file contents in commit #$(($num_commit + 1))
504EOF
505
506commit refs/notes/other_notes
507committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
508data <<COMMIT
509committing one more note on a tree imported from a previous notes tree
510COMMIT
511
512M 040000 $(git log --no-walk --format=%T refs/notes/many_notes)$SP
513N inline :$(($num_commit + 1))
514data <<EOF
515note for commit #$(($num_commit + 1))
516EOF
517INPUT_END
518
519test_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
b6e50052 526 if test $(expr length "$path") -ge $hexsz
405d7f4a
MH
527 then
528 return 1
529 fi
530 done
531'
532
a8b59ef5
JH
533cat >>expect_non-note1 << EOF
534This is not a note, but rather a regular file residing in a notes tree
535EOF
536
537cat >>expect_non-note2 << EOF
538Non-note file
539EOF
540
541cat >>expect_non-note3 << EOF
542Another non-note file
543EOF
544
545test_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'
9ff5e21f
JH
555
556# Change the notes for the three top commits
557test_tick
558cat >input <<INPUT_END
559commit refs/notes/many_notes
560committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
561data <<COMMIT
562changing notes for the top three commits
563COMMIT
564from refs/notes/many_notes^0
565INPUT_END
566
567rm expect
568i=$num_commits
569j=0
570while test $j -lt 3
571do
572 cat >>input <<INPUT_END
573N inline refs/heads/many_commits~$j
574data <<EOF
575changed note for commit #$i
576EOF
577INPUT_END
578 cat >>expect <<EXPECT_END
579 commit #$i
580 changed note for commit #$i
581EXPECT_END
582 i=$(($i - 1))
583 j=$(($j + 1))
584done
585
18386857 586test_expect_success 'change a few existing notes' '
9ff5e21f
JH
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
18386857 595test_expect_success 'verify that changing notes respect existing fanout' '
9ff5e21f
JH
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
b6e50052 601 if test $(expr length "$path") -ge $hexsz
9ff5e21f
JH
602 then
603 return 1
604 fi
605 done
606
607'
608
a8b59ef5
JH
609remaining_notes=10
610test_tick
d1075414 611cat >input <<INPUT_END
a8b59ef5
JH
612commit refs/notes/many_notes
613committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
614data <<COMMIT
615removing all notes but $remaining_notes
616COMMIT
617from refs/notes/many_notes^0
618INPUT_END
619
d1075414
JH
620i=$(($num_commits - $remaining_notes))
621for sha1 in $(git rev-list -n $i refs/heads/many_commits)
a8b59ef5 622do
a8b59ef5 623 cat >>input <<INPUT_END
b6e50052 624N $ZERO_OID $sha1
a8b59ef5
JH
625INPUT_END
626done
627
628i=$num_commits
629rm expect
630while test $i -gt 0
631do
632 cat >>expect <<EXPECT_END
633 commit #$i
634EXPECT_END
635 if test $i -le $remaining_notes
636 then
637 cat >>expect <<EXPECT_END
638 note for commit #$i
639EXPECT_END
640 fi
641 i=$(($i - 1))
642done
643
18386857 644test_expect_success 'remove lots of notes' '
a8b59ef5
JH
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
18386857 653test_expect_success 'verify that removing notes trigger fanout consolidation' '
a8b59ef5
JH
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
b6e50052 663 if test $(expr length "$path") -ne $hexsz
a8b59ef5
JH
664 then
665 return 1
666 fi
667 done
668
669'
670
671test_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
683rm input expect
684num_notes_refs=10
685num_commits=16
686some_commits=8
687# Create commits
688fast_import_commits "refs/heads/more_commits" $num_commits input
689# Create one note per above commit per notes ref
690i=0
691while test $i -lt $num_notes_refs
692do
693 i=$(($i + 1))
694 fast_import_notes "refs/notes/more_notes_$i" $num_commits input
695done
696# Trigger branch reloading in git-fast-import by repeating the note creation
697i=0
698while test $i -lt $num_notes_refs
699do
700 i=$(($i + 1))
701 fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
702done
703# Finally create the expected output from the notes in refs/notes/more_notes_1
704i=$num_commits
705while test $i -gt 0
706do
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
715EXPECT_END
716 i=$(($i - 1))
717done
718
719test_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
728test_done