Code

diff -c/--cc: do not mistake "resolved as deletion" as "use working tree"
[git.git] / t / t9301-fast-import-notes.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2009 Johan Herland
4 #
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
77 '
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
100 EOF
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
134 EOF
136 N inline $commit4
137 data <<EOF
138 first note for fourth commit
139 EOF
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
174 EOF
176 N inline $commit2
177 data <<EOF
178 second note for second commit
179 EOF
181 N inline $commit3
182 data <<EOF
183 second note for third commit
184 EOF
186 N inline $commit4
187 data <<EOF
188 second note for fourth commit
189 EOF
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
224 EOF
226 M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
227 data <<EOF
228 prefix of note for fourth commit
229 EOF
231 M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
232 data <<EOF
233 pre-prefix of note for fourth commit
234 EOF
236 N inline $commit1
237 data <<EOF
238 third note for first commit
239 EOF
241 N inline $commit2
242 data <<EOF
243 third note for second commit
244 EOF
246 N inline $commit3
247 data <<EOF
248 third note for third commit
249 EOF
251 N inline $commit4
252 data <<EOF
253 third note for fourth commit
254 EOF
257 INPUT_END
259 cat >expect <<EXPECT_END
260     fourth commit
261     pre-prefix of note for fourth commit
262     prefix of note for fourth commit
263     third note for fourth commit
264     third commit
265     prefix of note for third commit
266     third note for third commit
267     second commit
268     third note for second commit
269     first commit
270     third note for first commit
271 EXPECT_END
273 test_expect_success 'add concatentation notes with M command' '
275         git fast-import <input &&
276         GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
277         test_cmp expect actual
281 test_tick
282 cat >input <<INPUT_END
283 commit refs/notes/test
284 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
285 data <<COMMIT
286 fifth notes commit
287 COMMIT
289 from refs/notes/test^0
290 deleteall
292 INPUT_END
294 cat >expect <<EXPECT_END
295     fourth commit
296     third commit
297     second commit
298     first commit
299 EXPECT_END
301 test_expect_success 'verify that deleteall also removes notes' '
303         git fast-import <input &&
304         GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
305         test_cmp expect actual
309 test_tick
310 cat >input <<INPUT_END
311 commit refs/notes/test
312 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
313 data <<COMMIT
314 sixth notes commit
315 COMMIT
317 from refs/notes/test^0
318 M 644 inline $commit1
319 data <<EOF
320 third note for first commit
321 EOF
323 M 644 inline $commit3
324 data <<EOF
325 third note for third commit
326 EOF
328 N inline $commit1
329 data <<EOF
330 fourth note for first commit
331 EOF
333 N inline $commit3
334 data <<EOF
335 fourth note for third commit
336 EOF
338 INPUT_END
340 cat >expect <<EXPECT_END
341     fourth commit
342     third commit
343     fourth note for third commit
344     second commit
345     first commit
346     fourth note for first commit
347 EXPECT_END
349 test_expect_success 'verify that later N commands override earlier M commands' '
351         git fast-import <input &&
352         GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
353         test_cmp expect actual
357 # Write fast-import commands to create the given number of commits
358 fast_import_commits () {
359         my_ref=$1
360         my_num_commits=$2
361         my_append_to_file=$3
362         my_i=0
363         while test $my_i -lt $my_num_commits
364         do
365                 my_i=$(($my_i + 1))
366                 test_tick
367                 cat >>"$my_append_to_file" <<INPUT_END
368 commit $my_ref
369 mark :$my_i
370 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
371 data <<COMMIT
372 commit #$my_i
373 COMMIT
375 M 644 inline file
376 data <<EOF
377 file contents in commit #$my_i
378 EOF
380 INPUT_END
381         done
384 # Write fast-import commands to create the given number of notes annotating
385 # the commits created by fast_import_commits()
386 fast_import_notes () {
387         my_notes_ref=$1
388         my_num_commits=$2
389         my_append_to_file=$3
390         my_note_append=$4
391         test_tick
392         cat >>"$my_append_to_file" <<INPUT_END
393 commit $my_notes_ref
394 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
395 data <<COMMIT
396 committing $my_num_commits notes
397 COMMIT
399 INPUT_END
401         my_i=0
402         while test $my_i -lt $my_num_commits
403         do
404                 my_i=$(($my_i + 1))
405                 cat >>"$my_append_to_file" <<INPUT_END
406 N inline :$my_i
407 data <<EOF
408 note for commit #$my_i$my_note_append
409 EOF
411 INPUT_END
412         done
416 rm input expect
417 num_commits=400
418 # Create lots of commits
419 fast_import_commits "refs/heads/many_commits" $num_commits input
420 # Create one note per above commit
421 fast_import_notes "refs/notes/many_notes" $num_commits input
422 # Add a couple of non-notes as well
423 test_tick
424 cat >>input <<INPUT_END
425 commit refs/notes/many_notes
426 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
427 data <<COMMIT
428 committing some non-notes to the notes tree
429 COMMIT
431 M 755 inline foobar/non-note.txt
432 data <<EOF
433 This is not a note, but rather a regular file residing in a notes tree
434 EOF
436 M 644 inline deadbeef
437 data <<EOF
438 Non-note file
439 EOF
441 M 644 inline de/adbeef
442 data <<EOF
443 Another non-note file
444 EOF
446 INPUT_END
447 # Finally create the expected output from all these notes and commits
448 i=$num_commits
449 while test $i -gt 0
450 do
451         cat >>expect <<EXPECT_END
452     commit #$i
453     note for commit #$i
454 EXPECT_END
455         i=$(($i - 1))
456 done
458 test_expect_success 'add lots of commits and notes' '
460         git fast-import <input &&
461         GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
462             grep "^    " > actual &&
463         test_cmp expect actual
467 test_expect_success 'verify that lots of notes trigger a fanout scheme' '
469         # None of the entries in the top-level notes tree should be a full SHA1
470         git ls-tree --name-only refs/notes/many_notes |
471         while read path
472         do
473                 if test $(expr length "$path") -ge 40
474                 then
475                         return 1
476                 fi
477         done
481 cat >>expect_non-note1 << EOF
482 This is not a note, but rather a regular file residing in a notes tree
483 EOF
485 cat >>expect_non-note2 << EOF
486 Non-note file
487 EOF
489 cat >>expect_non-note3 << EOF
490 Another non-note file
491 EOF
493 test_expect_success 'verify that non-notes are untouched by a fanout change' '
495         git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
496         test_cmp expect_non-note1 actual &&
497         git cat-file -p refs/notes/many_notes:deadbeef > actual &&
498         test_cmp expect_non-note2 actual &&
499         git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
500         test_cmp expect_non-note3 actual
503 remaining_notes=10
504 test_tick
505 cat >>input <<INPUT_END
506 commit refs/notes/many_notes
507 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
508 data <<COMMIT
509 removing all notes but $remaining_notes
510 COMMIT
511 from refs/notes/many_notes^0
512 INPUT_END
514 i=$remaining_notes
515 while test $i -lt $num_commits
516 do
517         i=$(($i + 1))
518         cat >>input <<INPUT_END
519 N 0000000000000000000000000000000000000000 :$i
520 INPUT_END
521 done
523 i=$num_commits
524 rm expect
525 while test $i -gt 0
526 do
527         cat >>expect <<EXPECT_END
528     commit #$i
529 EXPECT_END
530         if test $i -le $remaining_notes
531         then
532                 cat >>expect <<EXPECT_END
533     note for commit #$i
534 EXPECT_END
535         fi
536         i=$(($i - 1))
537 done
539 test_expect_success 'remove lots of notes' '
541         git fast-import <input &&
542         GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
543             grep "^    " > actual &&
544         test_cmp expect actual
548 test_expect_success 'verify that removing notes trigger fanout consolidation' '
550         # All entries in the top-level notes tree should be a full SHA1
551         git ls-tree --name-only -r refs/notes/many_notes |
552         while read path
553         do
554                 # Explicitly ignore the non-note paths
555                 test "$path" = "foobar/non-note.txt" && continue
556                 test "$path" = "deadbeef" && continue
557                 test "$path" = "de/adbeef" && continue
559                 if test $(expr length "$path") -ne 40
560                 then
561                         return 1
562                 fi
563         done
567 test_expect_success 'verify that non-notes are untouched by a fanout change' '
569         git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
570         test_cmp expect_non-note1 actual &&
571         git cat-file -p refs/notes/many_notes:deadbeef > actual &&
572         test_cmp expect_non-note2 actual &&
573         git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
574         test_cmp expect_non-note3 actual
579 rm input expect
580 num_notes_refs=10
581 num_commits=16
582 some_commits=8
583 # Create commits
584 fast_import_commits "refs/heads/more_commits" $num_commits input
585 # Create one note per above commit per notes ref
586 i=0
587 while test $i -lt $num_notes_refs
588 do
589         i=$(($i + 1))
590         fast_import_notes "refs/notes/more_notes_$i" $num_commits input
591 done
592 # Trigger branch reloading in git-fast-import by repeating the note creation
593 i=0
594 while test $i -lt $num_notes_refs
595 do
596         i=$(($i + 1))
597         fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
598 done
599 # Finally create the expected output from the notes in refs/notes/more_notes_1
600 i=$num_commits
601 while test $i -gt 0
602 do
603         note_data="note for commit #$i"
604         if test $i -le $some_commits
605         then
606                 note_data="$note_data (2)"
607         fi
608         cat >>expect <<EXPECT_END
609     commit #$i
610     $note_data
611 EXPECT_END
612         i=$(($i - 1))
613 done
615 test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
617         git fast-import --active-branches=5 <input &&
618         GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
619             grep "^    " > actual &&
620         test_cmp expect actual
624 test_done