Merge branch 'ss/get-time-cleanup'
[git] / t / t3301-notes.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Johannes E. Schindelin
4 #
5
6 test_description='Test commit notes'
7
8 . ./test-lib.sh
9
10 write_script fake_editor <<\EOF
11 echo "$MSG" >"$1"
12 echo "$MSG" >&2
13 EOF
14 GIT_EDITOR=./fake_editor
15 export GIT_EDITOR
16
17 indent="    "
18
19 test_expect_success 'cannot annotate non-existing HEAD' '
20         test_must_fail env MSG=3 git notes add
21 '
22
23 test_expect_success 'setup' '
24         test_commit 1st &&
25         test_commit 2nd
26 '
27
28 test_expect_success 'need valid notes ref' '
29         test_must_fail env MSG=1 GIT_NOTES_REF=/ git notes show &&
30         test_must_fail env MSG=2 GIT_NOTES_REF=/ git notes show
31 '
32
33 test_expect_success 'refusing to add notes in refs/heads/' '
34         test_must_fail env MSG=1 GIT_NOTES_REF=refs/heads/bogus git notes add
35 '
36
37 test_expect_success 'refusing to edit notes in refs/remotes/' '
38         test_must_fail env MSG=1 GIT_NOTES_REF=refs/heads/bogus git notes edit
39 '
40
41 # 1 indicates caught gracefully by die, 128 means git-show barked
42 test_expect_success 'handle empty notes gracefully' '
43         test_expect_code 1 git notes show
44 '
45
46 test_expect_success 'show non-existent notes entry with %N' '
47         test_write_lines A B >expect &&
48         git show -s --format="A%n%NB" >actual &&
49         test_cmp expect actual
50 '
51
52 test_expect_success 'create notes' '
53         MSG=b4 git notes add &&
54         test_path_is_missing .git/NOTES_EDITMSG &&
55         git ls-tree -r refs/notes/commits >actual &&
56         test_line_count = 1 actual &&
57         test "b4" = "$(git notes show)" &&
58         git show HEAD^ &&
59         test_must_fail git notes show HEAD^
60 '
61
62 test_expect_success 'show notes entry with %N' '
63         test_write_lines A b4 B >expect &&
64         git show -s --format="A%n%NB" >actual &&
65         test_cmp expect actual
66 '
67
68 test_expect_success 'create reflog entry' '
69         ref=$(git rev-parse --short refs/notes/commits) &&
70         cat <<-EOF >expect &&
71                 $ref refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
72         EOF
73         git reflog show refs/notes/commits >actual &&
74         test_cmp expect actual
75 '
76
77 test_expect_success 'edit existing notes' '
78         MSG=b3 git notes edit &&
79         test_path_is_missing .git/NOTES_EDITMSG &&
80         git ls-tree -r refs/notes/commits >actual &&
81         test_line_count = 1 actual &&
82         test "b3" = "$(git notes show)" &&
83         git show HEAD^ &&
84         test_must_fail git notes show HEAD^
85 '
86
87 test_expect_success 'show notes from treeish' '
88         test "b3" = "$(git notes --ref commits^{tree} show)" &&
89         test "b4" = "$(git notes --ref commits@{1} show)"
90 '
91
92 test_expect_success 'cannot edit notes from non-ref' '
93         test_must_fail git notes --ref commits^{tree} edit &&
94         test_must_fail git notes --ref commits@{1} edit
95 '
96
97 test_expect_success 'cannot "git notes add -m" where notes already exists' '
98         test_must_fail git notes add -m "b2" &&
99         test_path_is_missing .git/NOTES_EDITMSG &&
100         git ls-tree -r refs/notes/commits >actual &&
101         test_line_count = 1 actual &&
102         test "b3" = "$(git notes show)" &&
103         git show HEAD^ &&
104         test_must_fail git notes show HEAD^
105 '
106
107 test_expect_success 'can overwrite existing note with "git notes add -f -m"' '
108         git notes add -f -m "b1" &&
109         test_path_is_missing .git/NOTES_EDITMSG &&
110         git ls-tree -r refs/notes/commits >actual &&
111         test_line_count = 1 actual &&
112         test "b1" = "$(git notes show)" &&
113         git show HEAD^ &&
114         test_must_fail git notes show HEAD^
115 '
116
117 test_expect_success 'add w/no options on existing note morphs into edit' '
118         MSG=b2 git notes add &&
119         test_path_is_missing .git/NOTES_EDITMSG &&
120         git ls-tree -r refs/notes/commits >actual &&
121         test_line_count = 1 actual &&
122         test "b2" = "$(git notes show)" &&
123         git show HEAD^ &&
124         test_must_fail git notes show HEAD^
125 '
126
127 test_expect_success 'can overwrite existing note with "git notes add -f"' '
128         MSG=b1 git notes add -f &&
129         test_path_is_missing .git/NOTES_EDITMSG &&
130         git ls-tree -r refs/notes/commits >actual &&
131         test_line_count = 1 actual &&
132         test "b1" = "$(git notes show)" &&
133         git show HEAD^ &&
134         test_must_fail git notes show HEAD^
135 '
136
137 test_expect_success 'show notes' '
138         commit=$(git rev-parse HEAD) &&
139         cat >expect <<-EOF &&
140                 commit $commit
141                 Author: A U Thor <author@example.com>
142                 Date:   Thu Apr 7 15:14:13 2005 -0700
143
144                 ${indent}2nd
145
146                 Notes:
147                 ${indent}b1
148         EOF
149         ! (git cat-file commit HEAD | grep b1) &&
150         git log -1 >actual &&
151         test_cmp expect actual
152 '
153
154 test_expect_success 'show multi-line notes' '
155         test_commit 3rd &&
156         MSG="b3${LF}c3c3c3c3${LF}d3d3d3" git notes add &&
157         commit=$(git rev-parse HEAD) &&
158         cat >expect-multiline <<-EOF &&
159                 commit $commit
160                 Author: A U Thor <author@example.com>
161                 Date:   Thu Apr 7 15:15:13 2005 -0700
162
163                 ${indent}3rd
164
165                 Notes:
166                 ${indent}b3
167                 ${indent}c3c3c3c3
168                 ${indent}d3d3d3
169
170         EOF
171         cat expect >>expect-multiline &&
172         git log -2 >actual &&
173         test_cmp expect-multiline actual
174 '
175
176 test_expect_success 'show -F notes' '
177         test_commit 4th &&
178         echo "xyzzy" >note5 &&
179         git notes add -F note5 &&
180         commit=$(git rev-parse HEAD) &&
181         cat >expect-F <<-EOF &&
182                 commit $commit
183                 Author: A U Thor <author@example.com>
184                 Date:   Thu Apr 7 15:16:13 2005 -0700
185
186                 ${indent}4th
187
188                 Notes:
189                 ${indent}xyzzy
190
191         EOF
192         cat expect-multiline >>expect-F &&
193         git log -3 >actual &&
194         test_cmp expect-F actual
195 '
196
197 test_expect_success 'Re-adding -F notes without -f fails' '
198         echo "zyxxy" >note5 &&
199         test_must_fail git notes add -F note5 &&
200         git log -3 >actual &&
201         test_cmp expect-F actual
202 '
203
204 test_expect_success 'git log --pretty=raw does not show notes' '
205         commit=$(git rev-parse HEAD) &&
206         tree=$(git rev-parse HEAD^{tree}) &&
207         parent=$(git rev-parse HEAD^) &&
208         cat >expect <<-EOF &&
209                 commit $commit
210                 tree $tree
211                 parent $parent
212                 author A U Thor <author@example.com> 1112912173 -0700
213                 committer C O Mitter <committer@example.com> 1112912173 -0700
214
215                 ${indent}4th
216         EOF
217         git log -1 --pretty=raw >actual &&
218         test_cmp expect actual
219 '
220
221 test_expect_success 'git log --show-notes' '
222         cat >>expect <<-EOF &&
223
224         Notes:
225         ${indent}xyzzy
226         EOF
227         git log -1 --pretty=raw --show-notes >actual &&
228         test_cmp expect actual
229 '
230
231 test_expect_success 'git log --no-notes' '
232         git log -1 --no-notes >actual &&
233         ! grep xyzzy actual
234 '
235
236 test_expect_success 'git format-patch does not show notes' '
237         git format-patch -1 --stdout >actual &&
238         ! grep xyzzy actual
239 '
240
241 test_expect_success 'git format-patch --show-notes does show notes' '
242         git format-patch --show-notes -1 --stdout >actual &&
243         grep xyzzy actual
244 '
245
246 for pretty in \
247         "" --pretty --pretty=raw --pretty=short --pretty=medium \
248         --pretty=full --pretty=fuller --pretty=format:%s --oneline
249 do
250         case "$pretty" in
251         "") p= not= negate="" ;;
252         ?*) p="$pretty" not=" not" negate="!" ;;
253         esac
254         test_expect_success "git show $pretty does$not show notes" '
255                 git show $p >actual &&
256                 eval "$negate grep xyzzy actual"
257         '
258 done
259
260 test_expect_success 'setup alternate notes ref' '
261         git notes --ref=alternate add -m alternate
262 '
263
264 test_expect_success 'git log --notes shows default notes' '
265         git log -1 --notes >actual &&
266         grep xyzzy actual &&
267         ! grep alternate actual
268 '
269
270 test_expect_success 'git log --notes=X shows only X' '
271         git log -1 --notes=alternate >actual &&
272         ! grep xyzzy actual &&
273         grep alternate actual
274 '
275
276 test_expect_success 'git log --notes --notes=X shows both' '
277         git log -1 --notes --notes=alternate >actual &&
278         grep xyzzy actual &&
279         grep alternate actual
280 '
281
282 test_expect_success 'git log --no-notes resets default state' '
283         git log -1 --notes --notes=alternate \
284                 --no-notes --notes=alternate \
285                 >actual &&
286         ! grep xyzzy actual &&
287         grep alternate actual
288 '
289
290 test_expect_success 'git log --no-notes resets ref list' '
291         git log -1 --notes --notes=alternate \
292                 --no-notes --notes \
293                 >actual &&
294         grep xyzzy actual &&
295         ! grep alternate actual
296 '
297
298 test_expect_success 'show -m notes' '
299         test_commit 5th &&
300         git notes add -m spam -m "foo${LF}bar${LF}baz" &&
301         commit=$(git rev-parse HEAD) &&
302         cat >expect-m <<-EOF &&
303                 commit $commit
304                 Author: A U Thor <author@example.com>
305                 Date:   Thu Apr 7 15:17:13 2005 -0700
306
307                 ${indent}5th
308
309                 Notes:
310                 ${indent}spam
311                 ${indent}
312                 ${indent}foo
313                 ${indent}bar
314                 ${indent}baz
315
316         EOF
317         cat expect-F >>expect-m &&
318         git log -4 >actual &&
319         test_cmp expect-m actual
320 '
321
322 test_expect_success 'remove note with add -f -F /dev/null' '
323         git notes add -f -F /dev/null &&
324         commit=$(git rev-parse HEAD) &&
325         cat >expect-rm-F <<-EOF &&
326                 commit $commit
327                 Author: A U Thor <author@example.com>
328                 Date:   Thu Apr 7 15:17:13 2005 -0700
329
330                 ${indent}5th
331
332         EOF
333         cat expect-F >>expect-rm-F &&
334         git log -4 >actual &&
335         test_cmp expect-rm-F actual &&
336         test_must_fail git notes show
337 '
338
339 test_expect_success 'do not create empty note with -m ""' '
340         git notes add -m "" &&
341         git log -4 >actual &&
342         test_cmp expect-rm-F actual &&
343         test_must_fail git notes show
344 '
345
346 test_expect_success 'create note with combination of -m and -F' '
347         cat >expect-combine_m_and_F <<-EOF &&
348                 foo
349
350                 xyzzy
351
352                 bar
353
354                 zyxxy
355
356                 baz
357         EOF
358         echo "xyzzy" >note_a &&
359         echo "zyxxy" >note_b &&
360         git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" &&
361         git notes show >actual &&
362         test_cmp expect-combine_m_and_F actual
363 '
364
365 test_expect_success 'remove note with "git notes remove"' '
366         git notes remove HEAD^ &&
367         git notes remove &&
368         commit=$(git rev-parse HEAD) &&
369         parent=$(git rev-parse HEAD^) &&
370         cat >expect-rm-remove <<-EOF &&
371                 commit $commit
372                 Author: A U Thor <author@example.com>
373                 Date:   Thu Apr 7 15:17:13 2005 -0700
374
375                 ${indent}5th
376
377                 commit $parent
378                 Author: A U Thor <author@example.com>
379                 Date:   Thu Apr 7 15:16:13 2005 -0700
380
381                 ${indent}4th
382
383         EOF
384         cat expect-multiline >>expect-rm-remove &&
385         git log -4 >actual &&
386         test_cmp expect-rm-remove actual &&
387         test_must_fail git notes show HEAD^
388 '
389
390 test_expect_success 'removing non-existing note should not create new commit' '
391         git rev-parse --verify refs/notes/commits >before_commit &&
392         test_must_fail git notes remove HEAD^ &&
393         git rev-parse --verify refs/notes/commits >after_commit &&
394         test_cmp before_commit after_commit
395 '
396
397 test_expect_success 'removing more than one' '
398         before=$(git rev-parse --verify refs/notes/commits) &&
399         test_when_finished "git update-ref refs/notes/commits $before" &&
400
401         # We have only two -- add another and make sure it stays
402         git notes add -m "extra" &&
403         git notes list HEAD >after-removal-expect &&
404         git notes remove HEAD^^ HEAD^^^ &&
405         git notes list | sed -e "s/ .*//" >actual &&
406         test_cmp after-removal-expect actual
407 '
408
409 test_expect_success 'removing is atomic' '
410         before=$(git rev-parse --verify refs/notes/commits) &&
411         test_when_finished "git update-ref refs/notes/commits $before" &&
412         test_must_fail git notes remove HEAD^^ HEAD^^^ HEAD^ &&
413         after=$(git rev-parse --verify refs/notes/commits) &&
414         test "$before" = "$after"
415 '
416
417 test_expect_success 'removing with --ignore-missing' '
418         before=$(git rev-parse --verify refs/notes/commits) &&
419         test_when_finished "git update-ref refs/notes/commits $before" &&
420
421         # We have only two -- add another and make sure it stays
422         git notes add -m "extra" &&
423         git notes list HEAD >after-removal-expect &&
424         git notes remove --ignore-missing HEAD^^ HEAD^^^ HEAD^ &&
425         git notes list | sed -e "s/ .*//" >actual &&
426         test_cmp after-removal-expect actual
427 '
428
429 test_expect_success 'removing with --ignore-missing but bogus ref' '
430         before=$(git rev-parse --verify refs/notes/commits) &&
431         test_when_finished "git update-ref refs/notes/commits $before" &&
432         test_must_fail git notes remove --ignore-missing HEAD^^ HEAD^^^ NO-SUCH-COMMIT &&
433         after=$(git rev-parse --verify refs/notes/commits) &&
434         test "$before" = "$after"
435 '
436
437 test_expect_success 'remove reads from --stdin' '
438         before=$(git rev-parse --verify refs/notes/commits) &&
439         test_when_finished "git update-ref refs/notes/commits $before" &&
440
441         # We have only two -- add another and make sure it stays
442         git notes add -m "extra" &&
443         git notes list HEAD >after-removal-expect &&
444         git rev-parse HEAD^^ HEAD^^^ >input &&
445         git notes remove --stdin <input &&
446         git notes list | sed -e "s/ .*//" >actual &&
447         test_cmp after-removal-expect actual
448 '
449
450 test_expect_success 'remove --stdin is also atomic' '
451         before=$(git rev-parse --verify refs/notes/commits) &&
452         test_when_finished "git update-ref refs/notes/commits $before" &&
453         git rev-parse HEAD^^ HEAD^^^ HEAD^ >input &&
454         test_must_fail git notes remove --stdin <input &&
455         after=$(git rev-parse --verify refs/notes/commits) &&
456         test "$before" = "$after"
457 '
458
459 test_expect_success 'removing with --stdin --ignore-missing' '
460         before=$(git rev-parse --verify refs/notes/commits) &&
461         test_when_finished "git update-ref refs/notes/commits $before" &&
462
463         # We have only two -- add another and make sure it stays
464         git notes add -m "extra" &&
465         git notes list HEAD >after-removal-expect &&
466         git rev-parse HEAD^^ HEAD^^^ HEAD^ >input &&
467         git notes remove --ignore-missing --stdin <input &&
468         git notes list | sed -e "s/ .*//" >actual &&
469         test_cmp after-removal-expect actual
470 '
471
472 test_expect_success 'list notes with "git notes list"' '
473         commit_2=$(git rev-parse 2nd) &&
474         commit_3=$(git rev-parse 3rd) &&
475         sort -t" " -k2 >expect <<-EOF &&
476                 $(git rev-parse refs/notes/commits:$commit_2) $commit_2
477                 $(git rev-parse refs/notes/commits:$commit_3) $commit_3
478         EOF
479         git notes list >actual &&
480         test_cmp expect actual
481 '
482
483 test_expect_success 'list notes with "git notes"' '
484         git notes >actual &&
485         test_cmp expect actual
486 '
487
488 test_expect_success 'list specific note with "git notes list <object>"' '
489         cat >expect <<-EOF &&
490                 $(git rev-parse refs/notes/commits:$commit_3)
491         EOF
492         git notes list HEAD^^ >actual &&
493         test_cmp expect actual
494 '
495
496 test_expect_success 'listing non-existing notes fails' '
497         test_must_fail git notes list HEAD >actual &&
498         test_must_be_empty actual
499 '
500
501 test_expect_success 'append to existing note with "git notes append"' '
502         cat >expect <<-EOF &&
503                 Initial set of notes
504
505                 More notes appended with git notes append
506         EOF
507         git notes add -m "Initial set of notes" &&
508         git notes append -m "More notes appended with git notes append" &&
509         git notes show >actual &&
510         test_cmp expect actual
511 '
512
513 test_expect_success '"git notes list" does not expand to "git notes list HEAD"' '
514         commit_5=$(git rev-parse 5th) &&
515         sort -t" " -k2 >expect_list <<-EOF &&
516                 $(git rev-parse refs/notes/commits:$commit_2) $commit_2
517                 $(git rev-parse refs/notes/commits:$commit_3) $commit_3
518                 $(git rev-parse refs/notes/commits:$commit_5) $commit_5
519         EOF
520         git notes list >actual &&
521         test_cmp expect_list actual
522 '
523
524 test_expect_success 'appending empty string does not change existing note' '
525         git notes append -m "" &&
526         git notes show >actual &&
527         test_cmp expect actual
528 '
529
530 test_expect_success 'git notes append == add when there is no existing note' '
531         git notes remove HEAD &&
532         test_must_fail git notes list HEAD &&
533         git notes append -m "Initial set of notes${LF}${LF}More notes appended with git notes append" &&
534         git notes show >actual &&
535         test_cmp expect actual
536 '
537
538 test_expect_success 'appending empty string to non-existing note does not create note' '
539         git notes remove HEAD &&
540         test_must_fail git notes list HEAD &&
541         git notes append -m "" &&
542         test_must_fail git notes list HEAD
543 '
544
545 test_expect_success 'create other note on a different notes ref (setup)' '
546         test_commit 6th &&
547         GIT_NOTES_REF="refs/notes/other" git notes add -m "other note" &&
548         commit=$(git rev-parse HEAD) &&
549         cat >expect-not-other <<-EOF &&
550                 commit $commit
551                 Author: A U Thor <author@example.com>
552                 Date:   Thu Apr 7 15:18:13 2005 -0700
553
554                 ${indent}6th
555         EOF
556         cp expect-not-other expect-other &&
557         cat >>expect-other <<-EOF
558
559                 Notes (other):
560                 ${indent}other note
561         EOF
562 '
563
564 test_expect_success 'Do not show note on other ref by default' '
565         git log -1 >actual &&
566         test_cmp expect-not-other actual
567 '
568
569 test_expect_success 'Do show note when ref is given in GIT_NOTES_REF' '
570         GIT_NOTES_REF="refs/notes/other" git log -1 >actual &&
571         test_cmp expect-other actual
572 '
573
574 test_expect_success 'Do show note when ref is given in core.notesRef config' '
575         test_config core.notesRef "refs/notes/other" &&
576         git log -1 >actual &&
577         test_cmp expect-other actual
578 '
579
580 test_expect_success 'Do not show note when core.notesRef is overridden' '
581         test_config core.notesRef "refs/notes/other" &&
582         GIT_NOTES_REF="refs/notes/wrong" git log -1 >actual &&
583         test_cmp expect-not-other actual
584 '
585
586 test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
587         commit=$(git rev-parse HEAD) &&
588         parent=$(git rev-parse HEAD^) &&
589         cat >expect-both <<-EOF &&
590                 commit $commit
591                 Author: A U Thor <author@example.com>
592                 Date:   Thu Apr 7 15:18:13 2005 -0700
593
594                 ${indent}6th
595
596                 Notes:
597                 ${indent}order test
598
599                 Notes (other):
600                 ${indent}other note
601
602                 commit $parent
603                 Author: A U Thor <author@example.com>
604                 Date:   Thu Apr 7 15:17:13 2005 -0700
605
606                 ${indent}5th
607
608                 Notes:
609                 ${indent}replacement for deleted note
610         EOF
611         GIT_NOTES_REF=refs/notes/commits git notes add \
612                 -m"replacement for deleted note" HEAD^ &&
613         GIT_NOTES_REF=refs/notes/commits git notes add -m"order test" &&
614         test_unconfig core.notesRef &&
615         test_config notes.displayRef "refs/notes/*" &&
616         git log -2 >actual &&
617         test_cmp expect-both actual
618 '
619
620 test_expect_success 'core.notesRef is implicitly in notes.displayRef' '
621         test_config core.notesRef refs/notes/commits &&
622         test_config notes.displayRef refs/notes/other &&
623         git log -2 >actual &&
624         test_cmp expect-both actual
625 '
626
627 test_expect_success 'notes.displayRef can be given more than once' '
628         test_unconfig core.notesRef &&
629         test_config notes.displayRef refs/notes/commits &&
630         git config --add notes.displayRef refs/notes/other &&
631         git log -2 >actual &&
632         test_cmp expect-both actual
633 '
634
635 test_expect_success 'notes.displayRef respects order' '
636         commit=$(git rev-parse HEAD) &&
637         cat >expect-both-reversed <<-EOF &&
638                 commit $commit
639                 Author: A U Thor <author@example.com>
640                 Date:   Thu Apr 7 15:18:13 2005 -0700
641
642                 ${indent}6th
643
644                 Notes (other):
645                 ${indent}other note
646
647                 Notes:
648                 ${indent}order test
649         EOF
650         test_config core.notesRef refs/notes/other &&
651         test_config notes.displayRef refs/notes/commits &&
652         git log -1 >actual &&
653         test_cmp expect-both-reversed actual
654 '
655
656 test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
657         GIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \
658                 git log -2 >actual &&
659         test_cmp expect-both actual
660 '
661
662 test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
663         commit=$(git rev-parse HEAD) &&
664         parent=$(git rev-parse HEAD^) &&
665         cat >expect-none <<-EOF &&
666                 commit $commit
667                 Author: A U Thor <author@example.com>
668                 Date:   Thu Apr 7 15:18:13 2005 -0700
669
670                 ${indent}6th
671
672                 commit $parent
673                 Author: A U Thor <author@example.com>
674                 Date:   Thu Apr 7 15:17:13 2005 -0700
675
676                 ${indent}5th
677         EOF
678         test_config notes.displayRef "refs/notes/*" &&
679         GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 >actual &&
680         test_cmp expect-none actual
681 '
682
683 test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
684         GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 >actual &&
685         test_cmp expect-both actual
686 '
687
688 test_expect_success '--no-standard-notes' '
689         commit=$(git rev-parse HEAD) &&
690         cat >expect-commits <<-EOF &&
691                 commit $commit
692                 Author: A U Thor <author@example.com>
693                 Date:   Thu Apr 7 15:18:13 2005 -0700
694
695                 ${indent}6th
696
697                 Notes:
698                 ${indent}order test
699         EOF
700         git log --no-standard-notes --show-notes=commits -1 >actual &&
701         test_cmp expect-commits actual
702 '
703
704 test_expect_success '--standard-notes' '
705         test_config notes.displayRef "refs/notes/*" &&
706         git log --no-standard-notes --show-notes=commits \
707                 --standard-notes -2 >actual &&
708         test_cmp expect-both actual
709 '
710
711 test_expect_success '--show-notes=ref accumulates' '
712         git log --show-notes=other --show-notes=commits \
713                  --no-standard-notes -1 >actual &&
714         test_cmp expect-both-reversed actual
715 '
716
717 test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
718         test_config core.notesRef refs/notes/other &&
719         echo "Note on a tree" >expect &&
720         git notes add -m "Note on a tree" HEAD: &&
721         git notes show HEAD: >actual &&
722         test_cmp expect actual &&
723         echo "Note on a blob" >expect &&
724         filename=$(git ls-tree --name-only HEAD | head -n1) &&
725         git notes add -m "Note on a blob" HEAD:$filename &&
726         git notes show HEAD:$filename >actual &&
727         test_cmp expect actual &&
728         echo "Note on a tag" >expect &&
729         git tag -a -m "This is an annotated tag" foobar HEAD^ &&
730         git notes add -m "Note on a tag" foobar &&
731         git notes show foobar >actual &&
732         test_cmp expect actual
733 '
734
735 test_expect_success 'create note from other note with "git notes add -C"' '
736         test_commit 7th &&
737         commit=$(git rev-parse HEAD) &&
738         cat >expect <<-EOF &&
739                 commit $commit
740                 Author: A U Thor <author@example.com>
741                 Date:   Thu Apr 7 15:19:13 2005 -0700
742
743                 ${indent}7th
744
745                 Notes:
746                 ${indent}order test
747         EOF
748         git notes add -C $(git notes list HEAD^) &&
749         git log -1 >actual &&
750         test_cmp expect actual &&
751         test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
752 '
753
754 test_expect_success 'create note from non-existing note with "git notes add -C" fails' '
755         test_commit 8th &&
756         test_must_fail git notes add -C deadbeef &&
757         test_must_fail git notes list HEAD
758 '
759
760 test_expect_success 'create note from non-blob with "git notes add -C" fails' '
761         commit=$(git rev-parse --verify HEAD) &&
762         tree=$(git rev-parse --verify HEAD:) &&
763         test_must_fail git notes add -C $commit &&
764         test_must_fail git notes add -C $tree &&
765         test_must_fail git notes list HEAD
766 '
767
768 test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
769         commit=$(git rev-parse HEAD) &&
770         cat >expect <<-EOF &&
771                 commit $commit
772                 Author: A U Thor <author@example.com>
773                 Date:   Thu Apr 7 15:20:13 2005 -0700
774
775                 ${indent}8th
776
777                 Notes:
778                 ${indent}This is a blob object
779         EOF
780         blob=$(echo "This is a blob object" | git hash-object -w --stdin) &&
781         git notes add -C $blob &&
782         git log -1 >actual &&
783         test_cmp expect actual &&
784         test "$(git notes list HEAD)" = "$blob"
785 '
786
787 test_expect_success 'create note from other note with "git notes add -c"' '
788         test_commit 9th &&
789         commit=$(git rev-parse HEAD) &&
790         cat >expect <<-EOF &&
791                 commit $commit
792                 Author: A U Thor <author@example.com>
793                 Date:   Thu Apr 7 15:21:13 2005 -0700
794
795                 ${indent}9th
796
797                 Notes:
798                 ${indent}yet another note
799         EOF
800         MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
801         git log -1 >actual &&
802         test_cmp expect actual
803 '
804
805 test_expect_success 'create note from non-existing note with "git notes add -c" fails' '
806         test_commit 10th &&
807         test_must_fail env MSG="yet another note" git notes add -c deadbeef &&
808         test_must_fail git notes list HEAD
809 '
810
811 test_expect_success 'append to note from other note with "git notes append -C"' '
812         commit=$(git rev-parse HEAD^) &&
813         cat >expect <<-EOF &&
814                 commit $commit
815                 Author: A U Thor <author@example.com>
816                 Date:   Thu Apr 7 15:21:13 2005 -0700
817
818                 ${indent}9th
819
820                 Notes:
821                 ${indent}yet another note
822                 ${indent}
823                 ${indent}yet another note
824         EOF
825         git notes append -C $(git notes list HEAD^) HEAD^ &&
826         git log -1 HEAD^ >actual &&
827         test_cmp expect actual
828 '
829
830 test_expect_success 'create note from other note with "git notes append -c"' '
831         commit=$(git rev-parse HEAD) &&
832         cat >expect <<-EOF &&
833                 commit $commit
834                 Author: A U Thor <author@example.com>
835                 Date:   Thu Apr 7 15:22:13 2005 -0700
836
837                 ${indent}10th
838
839                 Notes:
840                 ${indent}other note
841         EOF
842         MSG="other note" git notes append -c $(git notes list HEAD^) &&
843         git log -1 >actual &&
844         test_cmp expect actual
845 '
846
847 test_expect_success 'append to note from other note with "git notes append -c"' '
848         commit=$(git rev-parse HEAD) &&
849         cat >expect <<-EOF &&
850                 commit $commit
851                 Author: A U Thor <author@example.com>
852                 Date:   Thu Apr 7 15:22:13 2005 -0700
853
854                 ${indent}10th
855
856                 Notes:
857                 ${indent}other note
858                 ${indent}
859                 ${indent}yet another note
860         EOF
861         MSG="yet another note" git notes append -c $(git notes list HEAD) &&
862         git log -1 >actual &&
863         test_cmp expect actual
864 '
865
866 test_expect_success 'copy note with "git notes copy"' '
867         test_commit 11th &&
868         commit=$(git rev-parse HEAD) &&
869         cat >expect <<-EOF &&
870                 commit $commit
871                 Author: A U Thor <author@example.com>
872                 Date:   Thu Apr 7 15:23:13 2005 -0700
873
874                 ${indent}11th
875
876                 Notes:
877                 ${indent}other note
878                 ${indent}
879                 ${indent}yet another note
880         EOF
881         git notes copy HEAD^ HEAD &&
882         git log -1 >actual &&
883         test_cmp expect actual &&
884         test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
885 '
886
887 test_expect_success 'prevent overwrite with "git notes copy"' '
888         test_must_fail git notes copy HEAD~2 HEAD &&
889         git log -1 >actual &&
890         test_cmp expect actual &&
891         test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
892 '
893
894 test_expect_success 'allow overwrite with "git notes copy -f"' '
895         commit=$(git rev-parse HEAD) &&
896         cat >expect <<-EOF &&
897                 commit $commit
898                 Author: A U Thor <author@example.com>
899                 Date:   Thu Apr 7 15:23:13 2005 -0700
900
901                 ${indent}11th
902
903                 Notes:
904                 ${indent}yet another note
905                 ${indent}
906                 ${indent}yet another note
907         EOF
908         git notes copy -f HEAD~2 HEAD &&
909         git log -1 >actual &&
910         test_cmp expect actual &&
911         test "$(git notes list HEAD)" = "$(git notes list HEAD~2)"
912 '
913
914 test_expect_success 'cannot copy note from object without notes' '
915         test_commit 12th &&
916         test_commit 13th &&
917         test_must_fail git notes copy HEAD^ HEAD
918 '
919
920 test_expect_success 'git notes copy --stdin' '
921         commit=$(git rev-parse HEAD) &&
922         parent=$(git rev-parse HEAD^) &&
923         cat >expect <<-EOF &&
924                 commit $commit
925                 Author: A U Thor <author@example.com>
926                 Date:   Thu Apr 7 15:25:13 2005 -0700
927
928                 ${indent}13th
929
930                 Notes:
931                 ${indent}yet another note
932                 ${indent}
933                 ${indent}yet another note
934
935                 commit $parent
936                 Author: A U Thor <author@example.com>
937                 Date:   Thu Apr 7 15:24:13 2005 -0700
938
939                 ${indent}12th
940
941                 Notes:
942                 ${indent}other note
943                 ${indent}
944                 ${indent}yet another note
945         EOF
946         (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
947         echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
948         git notes copy --stdin &&
949         git log -2 >actual &&
950         test_cmp expect actual &&
951         test "$(git notes list HEAD)" = "$(git notes list HEAD~2)" &&
952         test "$(git notes list HEAD^)" = "$(git notes list HEAD~3)"
953 '
954
955 test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
956         test_commit 14th &&
957         test_commit 15th &&
958         commit=$(git rev-parse HEAD) &&
959         parent=$(git rev-parse HEAD^) &&
960         cat >expect <<-EOF &&
961                 commit $commit
962                 Author: A U Thor <author@example.com>
963                 Date:   Thu Apr 7 15:27:13 2005 -0700
964
965                 ${indent}15th
966
967                 commit $parent
968                 Author: A U Thor <author@example.com>
969                 Date:   Thu Apr 7 15:26:13 2005 -0700
970
971                 ${indent}14th
972         EOF
973         (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
974         echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
975         git notes copy --for-rewrite=foo &&
976         git log -2 >actual &&
977         test_cmp expect actual
978 '
979
980 test_expect_success 'git notes copy --for-rewrite (enabled)' '
981         commit=$(git rev-parse HEAD) &&
982         parent=$(git rev-parse HEAD^) &&
983         cat >expect <<-EOF &&
984                 commit $commit
985                 Author: A U Thor <author@example.com>
986                 Date:   Thu Apr 7 15:27:13 2005 -0700
987
988                 ${indent}15th
989
990                 Notes:
991                 ${indent}yet another note
992                 ${indent}
993                 ${indent}yet another note
994
995                 commit $parent
996                 Author: A U Thor <author@example.com>
997                 Date:   Thu Apr 7 15:26:13 2005 -0700
998
999                 ${indent}14th
1000
1001                 Notes:
1002                 ${indent}other note
1003                 ${indent}
1004                 ${indent}yet another note
1005         EOF
1006         test_config notes.rewriteMode overwrite &&
1007         test_config notes.rewriteRef "refs/notes/*" &&
1008         (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
1009         echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
1010         git notes copy --for-rewrite=foo &&
1011         git log -2 >actual &&
1012         test_cmp expect actual
1013 '
1014
1015 test_expect_success 'git notes copy --for-rewrite (disabled)' '
1016         test_config notes.rewrite.bar false &&
1017         echo $(git rev-parse HEAD~3) $(git rev-parse HEAD) |
1018         git notes copy --for-rewrite=bar &&
1019         git log -2 >actual &&
1020         test_cmp expect actual
1021 '
1022
1023 test_expect_success 'git notes copy --for-rewrite (overwrite)' '
1024         commit=$(git rev-parse HEAD) &&
1025         cat >expect <<-EOF &&
1026                 commit $commit
1027                 Author: A U Thor <author@example.com>
1028                 Date:   Thu Apr 7 15:27:13 2005 -0700
1029
1030                 ${indent}15th
1031
1032                 Notes:
1033                 ${indent}a fresh note
1034         EOF
1035         git notes add -f -m"a fresh note" HEAD^ &&
1036         test_config notes.rewriteMode overwrite &&
1037         test_config notes.rewriteRef "refs/notes/*" &&
1038         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1039         git notes copy --for-rewrite=foo &&
1040         git log -1 >actual &&
1041         test_cmp expect actual
1042 '
1043
1044 test_expect_success 'git notes copy --for-rewrite (ignore)' '
1045         test_config notes.rewriteMode ignore &&
1046         test_config notes.rewriteRef "refs/notes/*" &&
1047         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1048         git notes copy --for-rewrite=foo &&
1049         git log -1 >actual &&
1050         test_cmp expect actual
1051 '
1052
1053 test_expect_success 'git notes copy --for-rewrite (append)' '
1054         commit=$(git rev-parse HEAD) &&
1055         cat >expect <<-EOF &&
1056                 commit $commit
1057                 Author: A U Thor <author@example.com>
1058                 Date:   Thu Apr 7 15:27:13 2005 -0700
1059
1060                 ${indent}15th
1061
1062                 Notes:
1063                 ${indent}a fresh note
1064                 ${indent}
1065                 ${indent}another fresh note
1066         EOF
1067         git notes add -f -m"another fresh note" HEAD^ &&
1068         test_config notes.rewriteMode concatenate &&
1069         test_config notes.rewriteRef "refs/notes/*" &&
1070         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1071         git notes copy --for-rewrite=foo &&
1072         git log -1 >actual &&
1073         test_cmp expect actual
1074 '
1075
1076 test_expect_success 'git notes copy --for-rewrite (append two to one)' '
1077         commit=$(git rev-parse HEAD) &&
1078         cat >expect <<-EOF &&
1079                 commit $commit
1080                 Author: A U Thor <author@example.com>
1081                 Date:   Thu Apr 7 15:27:13 2005 -0700
1082
1083                 ${indent}15th
1084
1085                 Notes:
1086                 ${indent}a fresh note
1087                 ${indent}
1088                 ${indent}another fresh note
1089                 ${indent}
1090                 ${indent}append 1
1091                 ${indent}
1092                 ${indent}append 2
1093         EOF
1094         git notes add -f -m"append 1" HEAD^ &&
1095         git notes add -f -m"append 2" HEAD^^ &&
1096         test_config notes.rewriteMode concatenate &&
1097         test_config notes.rewriteRef "refs/notes/*" &&
1098         (echo $(git rev-parse HEAD^) $(git rev-parse HEAD) &&
1099         echo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) |
1100         git notes copy --for-rewrite=foo &&
1101         git log -1 >actual &&
1102         test_cmp expect actual
1103 '
1104
1105 test_expect_success 'git notes copy --for-rewrite (append empty)' '
1106         git notes remove HEAD^ &&
1107         test_config notes.rewriteMode concatenate &&
1108         test_config notes.rewriteRef "refs/notes/*" &&
1109         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1110         git notes copy --for-rewrite=foo &&
1111         git log -1 >actual &&
1112         test_cmp expect actual
1113 '
1114
1115 test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
1116         commit=$(git rev-parse HEAD) &&
1117         cat >expect <<-EOF &&
1118                 commit $commit
1119                 Author: A U Thor <author@example.com>
1120                 Date:   Thu Apr 7 15:27:13 2005 -0700
1121
1122                 ${indent}15th
1123
1124                 Notes:
1125                 ${indent}replacement note 1
1126         EOF
1127         test_config notes.rewriteMode concatenate &&
1128         test_config notes.rewriteRef "refs/notes/*" &&
1129         git notes add -f -m"replacement note 1" HEAD^ &&
1130         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1131         GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo &&
1132         git log -1 >actual &&
1133         test_cmp expect actual
1134 '
1135
1136 test_expect_success 'GIT_NOTES_REWRITE_REF works' '
1137         commit=$(git rev-parse HEAD) &&
1138         cat >expect <<-EOF &&
1139                 commit $commit
1140                 Author: A U Thor <author@example.com>
1141                 Date:   Thu Apr 7 15:27:13 2005 -0700
1142
1143                 ${indent}15th
1144
1145                 Notes:
1146                 ${indent}replacement note 2
1147         EOF
1148         git notes add -f -m"replacement note 2" HEAD^ &&
1149         test_config notes.rewriteMode overwrite &&
1150         test_unconfig notes.rewriteRef &&
1151         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1152         GIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \
1153                 git notes copy --for-rewrite=foo &&
1154         git log -1 >actual &&
1155         test_cmp expect actual
1156 '
1157
1158 test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
1159         git notes add -f -m"replacement note 3" HEAD^ &&
1160         test_config notes.rewriteMode overwrite &&
1161         test_config notes.rewriteRef refs/notes/other &&
1162         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1163         GIT_NOTES_REWRITE_REF=refs/notes/commits \
1164                 git notes copy --for-rewrite=foo &&
1165         git log -1 >actual &&
1166         grep "replacement note 3" actual
1167 '
1168
1169 test_expect_success 'git notes copy diagnoses too many or too few parameters' '
1170         test_must_fail git notes copy &&
1171         test_must_fail git notes copy one two three
1172 '
1173
1174 test_expect_success 'git notes get-ref expands refs/heads/master to refs/notes/refs/heads/master' '
1175         test_unconfig core.notesRef &&
1176         sane_unset GIT_NOTES_REF &&
1177         test "$(git notes --ref=refs/heads/master get-ref)" = "refs/notes/refs/heads/master"
1178 '
1179
1180 test_expect_success 'git notes get-ref (no overrides)' '
1181         test_unconfig core.notesRef &&
1182         sane_unset GIT_NOTES_REF &&
1183         test "$(git notes get-ref)" = "refs/notes/commits"
1184 '
1185
1186 test_expect_success 'git notes get-ref (core.notesRef)' '
1187         test_config core.notesRef refs/notes/foo &&
1188         test "$(git notes get-ref)" = "refs/notes/foo"
1189 '
1190
1191 test_expect_success 'git notes get-ref (GIT_NOTES_REF)' '
1192         test "$(GIT_NOTES_REF=refs/notes/bar git notes get-ref)" = "refs/notes/bar"
1193 '
1194
1195 test_expect_success 'git notes get-ref (--ref)' '
1196         test "$(GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref)" = "refs/notes/baz"
1197 '
1198
1199 test_expect_success 'setup testing of empty notes' '
1200         test_unconfig core.notesRef &&
1201         test_commit 16th &&
1202         empty_blob=$(git hash-object -w /dev/null) &&
1203         echo "$empty_blob" >expect_empty
1204 '
1205
1206 while read cmd
1207 do
1208         test_expect_success "'git notes $cmd' removes empty note" "
1209                 test_might_fail git notes remove HEAD &&
1210                 MSG= git notes $cmd &&
1211                 test_must_fail git notes list HEAD
1212         "
1213
1214         test_expect_success "'git notes $cmd --allow-empty' stores empty note" "
1215                 test_might_fail git notes remove HEAD &&
1216                 MSG= git notes $cmd --allow-empty &&
1217                 git notes list HEAD >actual &&
1218                 test_cmp expect_empty actual
1219         "
1220 done <<\EOF
1221 add
1222 add -F /dev/null
1223 add -m ""
1224 add -c "$empty_blob"
1225 add -C "$empty_blob"
1226 append
1227 append -F /dev/null
1228 append -m ""
1229 append -c "$empty_blob"
1230 append -C "$empty_blob"
1231 edit
1232 EOF
1233
1234 test_expect_success 'empty notes are displayed by git log' '
1235         test_commit 17th &&
1236         git log -1 >expect &&
1237         cat >>expect <<-EOF &&
1238
1239                 Notes:
1240         EOF
1241         git notes add -C "$empty_blob" --allow-empty &&
1242         git log -1 >actual &&
1243         test_cmp expect actual
1244 '
1245
1246 test_done