t5004: avoid using tar for checking emptiness of archive
[git/mjg.git] / t / t9301-fast-import-notes.sh
blob83acf68bc3c19770eb690ece139892ca75329216
1 #!/bin/sh
3 # Copyright (c) 2009 Johan Herland
6 test_description='test git fast-import of notes objects'
7 . ./test-lib.sh
10 test_tick
11 cat >input <<INPUT_END
12 commit refs/heads/master
13 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
14 data <<COMMIT
15 first commit
16 COMMIT
18 M 644 inline foo
19 data <<EOF
20 file foo in first commit
21 EOF
23 M 755 inline bar
24 data <<EOF
25 file bar in first commit
26 EOF
28 M 644 inline baz/xyzzy
29 data <<EOF
30 file baz/xyzzy in first commit
31 EOF
33 commit refs/heads/master
34 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
35 data <<COMMIT
36 second commit
37 COMMIT
39 M 644 inline foo
40 data <<EOF
41 file foo in second commit
42 EOF
44 M 755 inline baz/xyzzy
45 data <<EOF
46 file baz/xyzzy in second commit
47 EOF
49 commit refs/heads/master
50 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
51 data <<COMMIT
52 third commit
53 COMMIT
55 M 644 inline foo
56 data <<EOF
57 file foo in third commit
58 EOF
60 commit refs/heads/master
61 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
62 data <<COMMIT
63 fourth commit
64 COMMIT
66 M 755 inline bar
67 data <<EOF
68 file bar in fourth commit
69 EOF
71 INPUT_END
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")
84 test_tick
85 cat >input <<INPUT_END
86 commit refs/notes/test
87 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
88 data <<COMMIT
89 first notes commit
90 COMMIT
92 M 644 inline $commit1
93 data <<EOF
94 first note for first commit
95 EOF
97 M 755 inline $commit2
98 data <<EOF
99 first note for second commit
102 INPUT_END
104 cat >expect <<EXPECT_END
105 fourth commit
106 third commit
107 second commit
108 first note for second commit
109 first commit
110 first note for first commit
111 EXPECT_END
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
121 test_tick
122 cat >input <<INPUT_END
123 feature notes
124 commit refs/notes/test
125 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
126 data <<COMMIT
127 second notes commit
128 COMMIT
130 from refs/notes/test^0
131 N inline $commit3
132 data <<EOF
133 first note for third commit
136 N inline $commit4
137 data <<EOF
138 first note for fourth commit
141 INPUT_END
143 cat >expect <<EXPECT_END
144 fourth commit
145 first note for fourth commit
146 third commit
147 first note for third commit
148 second commit
149 first note for second commit
150 first commit
151 first note for first commit
152 EXPECT_END
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
162 test_tick
163 cat >input <<INPUT_END
164 commit refs/notes/test
165 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
166 data <<COMMIT
167 third notes commit
168 COMMIT
170 from refs/notes/test^0
171 N inline $commit1
172 data <<EOF
173 second note for first commit
176 N inline $commit2
177 data <<EOF
178 second note for second commit
181 N inline $commit3
182 data <<EOF
183 second note for third commit
186 N inline $commit4
187 data <<EOF
188 second note for fourth commit
191 INPUT_END
193 cat >expect <<EXPECT_END
194 fourth commit
195 second note for fourth commit
196 third commit
197 second note for third commit
198 second commit
199 second note for second commit
200 first commit
201 second note for first commit
202 EXPECT_END
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
212 test_tick
213 cat >input <<INPUT_END
214 commit refs/notes/test
215 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
216 data <<COMMIT
217 fourth notes commit
218 COMMIT
220 from refs/notes/test^0
221 M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
222 data <<EOF
223 prefix of note for third commit
226 M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
227 data <<EOF
228 prefix of note for fourth commit
231 M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
232 data <<EOF
233 pre-prefix of note for fourth commit
236 N inline $commit1
237 data <<EOF
238 third note for first commit
241 N inline $commit2
242 data <<EOF
243 third note for second commit
246 N inline $commit3
247 data <<EOF
248 third note for third commit
251 N inline $commit4
252 data <<EOF
253 third note for fourth commit
257 INPUT_END
259 whitespace=" "
261 cat >expect <<EXPECT_END
262 fourth commit
263 pre-prefix of note for fourth commit
264 $whitespace
265 prefix of note for fourth commit
266 $whitespace
267 third note for fourth commit
268 third commit
269 prefix of note for third commit
270 $whitespace
271 third note for third commit
272 second commit
273 third note for second commit
274 first commit
275 third note for first commit
276 EXPECT_END
278 test_expect_success 'add concatentation 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
286 test_tick
287 cat >input <<INPUT_END
288 commit refs/notes/test
289 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
290 data <<COMMIT
291 fifth notes commit
292 COMMIT
294 from refs/notes/test^0
295 deleteall
297 INPUT_END
299 cat >expect <<EXPECT_END
300 fourth commit
301 third commit
302 second commit
303 first commit
304 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
314 test_tick
315 cat >input <<INPUT_END
316 commit refs/notes/test
317 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
318 data <<COMMIT
319 sixth notes commit
320 COMMIT
322 from refs/notes/test^0
323 M 644 inline $commit1
324 data <<EOF
325 third note for first commit
328 M 644 inline $commit3
329 data <<EOF
330 third note for third commit
333 N inline $commit1
334 data <<EOF
335 fourth note for first commit
338 N inline $commit3
339 data <<EOF
340 fourth note for third commit
343 INPUT_END
345 cat >expect <<EXPECT_END
346 fourth commit
347 third commit
348 fourth note for third commit
349 second commit
350 first commit
351 fourth note for first commit
352 EXPECT_END
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 () {
364 my_ref=$1
365 my_num_commits=$2
366 my_append_to_file=$3
367 my_i=0
368 while test $my_i -lt $my_num_commits
370 my_i=$(($my_i + 1))
371 test_tick
372 cat >>"$my_append_to_file" <<INPUT_END
373 commit $my_ref
374 mark :$my_i
375 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
376 data <<COMMIT
377 commit #$my_i
378 COMMIT
380 M 644 inline file
381 data <<EOF
382 file contents in commit #$my_i
385 INPUT_END
386 done
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 () {
392 my_notes_ref=$1
393 my_num_commits=$2
394 my_append_to_file=$3
395 my_note_append=$4
396 test_tick
397 cat >>"$my_append_to_file" <<INPUT_END
398 commit $my_notes_ref
399 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
400 data <<COMMIT
401 committing $my_num_commits notes
402 COMMIT
404 INPUT_END
406 my_i=0
407 while test $my_i -lt $my_num_commits
409 my_i=$(($my_i + 1))
410 cat >>"$my_append_to_file" <<INPUT_END
411 N inline :$my_i
412 data <<EOF
413 note for commit #$my_i$my_note_append
416 INPUT_END
417 done
421 rm input expect
422 num_commits=400
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
428 test_tick
429 cat >>input <<INPUT_END
430 commit refs/notes/many_notes
431 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
432 data <<COMMIT
433 committing some non-notes to the notes tree
434 COMMIT
436 M 755 inline foobar/non-note.txt
437 data <<EOF
438 This is not a note, but rather a regular file residing in a notes tree
441 M 644 inline deadbeef
442 data <<EOF
443 Non-note file
446 M 644 inline de/adbeef
447 data <<EOF
448 Another non-note file
451 INPUT_END
452 # Finally create the expected output from all these notes and commits
453 i=$num_commits
454 while test $i -gt 0
456 cat >>expect <<EXPECT_END
457 commit #$i
458 note for commit #$i
459 EXPECT_END
460 i=$(($i - 1))
461 done
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' '
474 # None of the entries in the top-level notes tree should be a full SHA1
475 git ls-tree --name-only refs/notes/many_notes |
476 while read path
478 if test $(expr length "$path") -ge 40
479 then
480 return 1
482 done
486 cat >>expect_non-note1 << EOF
487 This is not a note, but rather a regular file residing in a notes tree
490 cat >>expect_non-note2 << EOF
491 Non-note file
494 cat >>expect_non-note3 << EOF
495 Another non-note file
498 test_expect_success 'verify that non-notes are untouched by a fanout change' '
500 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
501 test_cmp expect_non-note1 actual &&
502 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
503 test_cmp expect_non-note2 actual &&
504 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
505 test_cmp expect_non-note3 actual
509 # Change the notes for the three top commits
510 test_tick
511 cat >input <<INPUT_END
512 commit refs/notes/many_notes
513 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
514 data <<COMMIT
515 changing notes for the top three commits
516 COMMIT
517 from refs/notes/many_notes^0
518 INPUT_END
520 rm expect
521 i=$num_commits
523 while test $j -lt 3
525 cat >>input <<INPUT_END
526 N inline refs/heads/many_commits~$j
527 data <<EOF
528 changed note for commit #$i
530 INPUT_END
531 cat >>expect <<EXPECT_END
532 commit #$i
533 changed note for commit #$i
534 EXPECT_END
535 i=$(($i - 1))
536 j=$(($j + 1))
537 done
539 test_expect_success 'change a few existing notes' '
541 git fast-import <input &&
542 GIT_NOTES_REF=refs/notes/many_notes git log -n3 refs/heads/many_commits |
543 grep "^ " > actual &&
544 test_cmp expect actual
548 test_expect_success 'verify that changing notes respect existing fanout' '
550 # None of the entries in the top-level notes tree should be a full SHA1
551 git ls-tree --name-only refs/notes/many_notes |
552 while read path
554 if test $(expr length "$path") -ge 40
555 then
556 return 1
558 done
562 remaining_notes=10
563 test_tick
564 cat >input <<INPUT_END
565 commit refs/notes/many_notes
566 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
567 data <<COMMIT
568 removing all notes but $remaining_notes
569 COMMIT
570 from refs/notes/many_notes^0
571 INPUT_END
573 i=$(($num_commits - $remaining_notes))
574 for sha1 in $(git rev-list -n $i refs/heads/many_commits)
576 cat >>input <<INPUT_END
577 N 0000000000000000000000000000000000000000 $sha1
578 INPUT_END
579 done
581 i=$num_commits
582 rm expect
583 while test $i -gt 0
585 cat >>expect <<EXPECT_END
586 commit #$i
587 EXPECT_END
588 if test $i -le $remaining_notes
589 then
590 cat >>expect <<EXPECT_END
591 note for commit #$i
592 EXPECT_END
594 i=$(($i - 1))
595 done
597 test_expect_success 'remove lots of notes' '
599 git fast-import <input &&
600 GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
601 grep "^ " > actual &&
602 test_cmp expect actual
606 test_expect_success 'verify that removing notes trigger fanout consolidation' '
608 # All entries in the top-level notes tree should be a full SHA1
609 git ls-tree --name-only -r refs/notes/many_notes |
610 while read path
612 # Explicitly ignore the non-note paths
613 test "$path" = "foobar/non-note.txt" && continue
614 test "$path" = "deadbeef" && continue
615 test "$path" = "de/adbeef" && continue
617 if test $(expr length "$path") -ne 40
618 then
619 return 1
621 done
625 test_expect_success 'verify that non-notes are untouched by a fanout change' '
627 git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
628 test_cmp expect_non-note1 actual &&
629 git cat-file -p refs/notes/many_notes:deadbeef > actual &&
630 test_cmp expect_non-note2 actual &&
631 git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
632 test_cmp expect_non-note3 actual
637 rm input expect
638 num_notes_refs=10
639 num_commits=16
640 some_commits=8
641 # Create commits
642 fast_import_commits "refs/heads/more_commits" $num_commits input
643 # Create one note per above commit per notes ref
645 while test $i -lt $num_notes_refs
647 i=$(($i + 1))
648 fast_import_notes "refs/notes/more_notes_$i" $num_commits input
649 done
650 # Trigger branch reloading in git-fast-import by repeating the note creation
652 while test $i -lt $num_notes_refs
654 i=$(($i + 1))
655 fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
656 done
657 # Finally create the expected output from the notes in refs/notes/more_notes_1
658 i=$num_commits
659 while test $i -gt 0
661 note_data="note for commit #$i"
662 if test $i -le $some_commits
663 then
664 note_data="$note_data (2)"
666 cat >>expect <<EXPECT_END
667 commit #$i
668 $note_data
669 EXPECT_END
670 i=$(($i - 1))
671 done
673 test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
675 git fast-import --active-branches=5 <input &&
676 GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
677 grep "^ " > actual &&
678 test_cmp expect actual
682 test_done