Merge branch 'ra/rebase-i-more-options'
[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         commit=$(git rev-parse 4th) &&
868         cat >expect <<-EOF &&
869                 commit $commit
870                 Author: A U Thor <author@example.com>
871                 Date:   Thu Apr 7 15:16:13 2005 -0700
872
873                 ${indent}4th
874
875                 Notes:
876                 ${indent}This is a blob object
877         EOF
878         git notes copy 8th 4th &&
879         git log 3rd..4th >actual &&
880         test_cmp expect actual &&
881         test "$(git note list 4th)" = "$(git note list 8th)"
882 '
883
884 test_expect_success 'copy note with "git notes copy" with default' '
885         test_commit 11th &&
886         commit=$(git rev-parse HEAD) &&
887         cat >expect <<-EOF &&
888                 commit $commit
889                 Author: A U Thor <author@example.com>
890                 Date:   Thu Apr 7 15:23:13 2005 -0700
891
892                 ${indent}11th
893
894                 Notes:
895                 ${indent}other note
896                 ${indent}
897                 ${indent}yet another note
898         EOF
899         git notes copy HEAD^ &&
900         git log -1 >actual &&
901         test_cmp expect actual &&
902         test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
903 '
904
905 test_expect_success 'prevent overwrite with "git notes copy"' '
906         test_must_fail git notes copy HEAD~2 HEAD &&
907         git log -1 >actual &&
908         test_cmp expect actual &&
909         test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
910 '
911
912 test_expect_success 'allow overwrite with "git notes copy -f"' '
913         commit=$(git rev-parse HEAD) &&
914         cat >expect <<-EOF &&
915                 commit $commit
916                 Author: A U Thor <author@example.com>
917                 Date:   Thu Apr 7 15:23:13 2005 -0700
918
919                 ${indent}11th
920
921                 Notes:
922                 ${indent}This is a blob object
923         EOF
924         git notes copy -f HEAD~3 HEAD &&
925         git log -1 >actual &&
926         test_cmp expect actual &&
927         test "$(git notes list HEAD)" = "$(git notes list HEAD~3)"
928 '
929
930 test_expect_success 'allow overwrite with "git notes copy -f" with default' '
931         commit=$(git rev-parse HEAD) &&
932         cat >expect <<-EOF &&
933                 commit $commit
934                 Author: A U Thor <author@example.com>
935                 Date:   Thu Apr 7 15:23:13 2005 -0700
936
937                 ${indent}11th
938
939                 Notes:
940                 ${indent}yet another note
941                 ${indent}
942                 ${indent}yet another note
943         EOF
944         git notes copy -f HEAD~2 &&
945         git log -1 >actual &&
946         test_cmp expect actual &&
947         test "$(git notes list HEAD)" = "$(git notes list HEAD~2)"
948 '
949
950 test_expect_success 'cannot copy note from object without notes' '
951         test_commit 12th &&
952         test_commit 13th &&
953         test_must_fail git notes copy HEAD^ HEAD
954 '
955
956 test_expect_success 'git notes copy --stdin' '
957         commit=$(git rev-parse HEAD) &&
958         parent=$(git rev-parse HEAD^) &&
959         cat >expect <<-EOF &&
960                 commit $commit
961                 Author: A U Thor <author@example.com>
962                 Date:   Thu Apr 7 15:25:13 2005 -0700
963
964                 ${indent}13th
965
966                 Notes:
967                 ${indent}yet another note
968                 ${indent}
969                 ${indent}yet another note
970
971                 commit $parent
972                 Author: A U Thor <author@example.com>
973                 Date:   Thu Apr 7 15:24:13 2005 -0700
974
975                 ${indent}12th
976
977                 Notes:
978                 ${indent}other note
979                 ${indent}
980                 ${indent}yet another note
981         EOF
982         (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
983         echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
984         git notes copy --stdin &&
985         git log -2 >actual &&
986         test_cmp expect actual &&
987         test "$(git notes list HEAD)" = "$(git notes list HEAD~2)" &&
988         test "$(git notes list HEAD^)" = "$(git notes list HEAD~3)"
989 '
990
991 test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
992         test_commit 14th &&
993         test_commit 15th &&
994         commit=$(git rev-parse HEAD) &&
995         parent=$(git rev-parse HEAD^) &&
996         cat >expect <<-EOF &&
997                 commit $commit
998                 Author: A U Thor <author@example.com>
999                 Date:   Thu Apr 7 15:27:13 2005 -0700
1000
1001                 ${indent}15th
1002
1003                 commit $parent
1004                 Author: A U Thor <author@example.com>
1005                 Date:   Thu Apr 7 15:26:13 2005 -0700
1006
1007                 ${indent}14th
1008         EOF
1009         (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
1010         echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
1011         git notes copy --for-rewrite=foo &&
1012         git log -2 >actual &&
1013         test_cmp expect actual
1014 '
1015
1016 test_expect_success 'git notes copy --for-rewrite (enabled)' '
1017         commit=$(git rev-parse HEAD) &&
1018         parent=$(git rev-parse HEAD^) &&
1019         cat >expect <<-EOF &&
1020                 commit $commit
1021                 Author: A U Thor <author@example.com>
1022                 Date:   Thu Apr 7 15:27:13 2005 -0700
1023
1024                 ${indent}15th
1025
1026                 Notes:
1027                 ${indent}yet another note
1028                 ${indent}
1029                 ${indent}yet another note
1030
1031                 commit $parent
1032                 Author: A U Thor <author@example.com>
1033                 Date:   Thu Apr 7 15:26:13 2005 -0700
1034
1035                 ${indent}14th
1036
1037                 Notes:
1038                 ${indent}other note
1039                 ${indent}
1040                 ${indent}yet another note
1041         EOF
1042         test_config notes.rewriteMode overwrite &&
1043         test_config notes.rewriteRef "refs/notes/*" &&
1044         (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
1045         echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
1046         git notes copy --for-rewrite=foo &&
1047         git log -2 >actual &&
1048         test_cmp expect actual
1049 '
1050
1051 test_expect_success 'git notes copy --for-rewrite (disabled)' '
1052         test_config notes.rewrite.bar false &&
1053         echo $(git rev-parse HEAD~3) $(git rev-parse HEAD) |
1054         git notes copy --for-rewrite=bar &&
1055         git log -2 >actual &&
1056         test_cmp expect actual
1057 '
1058
1059 test_expect_success 'git notes copy --for-rewrite (overwrite)' '
1060         commit=$(git rev-parse HEAD) &&
1061         cat >expect <<-EOF &&
1062                 commit $commit
1063                 Author: A U Thor <author@example.com>
1064                 Date:   Thu Apr 7 15:27:13 2005 -0700
1065
1066                 ${indent}15th
1067
1068                 Notes:
1069                 ${indent}a fresh note
1070         EOF
1071         git notes add -f -m"a fresh note" HEAD^ &&
1072         test_config notes.rewriteMode overwrite &&
1073         test_config notes.rewriteRef "refs/notes/*" &&
1074         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1075         git notes copy --for-rewrite=foo &&
1076         git log -1 >actual &&
1077         test_cmp expect actual
1078 '
1079
1080 test_expect_success 'git notes copy --for-rewrite (ignore)' '
1081         test_config notes.rewriteMode ignore &&
1082         test_config notes.rewriteRef "refs/notes/*" &&
1083         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1084         git notes copy --for-rewrite=foo &&
1085         git log -1 >actual &&
1086         test_cmp expect actual
1087 '
1088
1089 test_expect_success 'git notes copy --for-rewrite (append)' '
1090         commit=$(git rev-parse HEAD) &&
1091         cat >expect <<-EOF &&
1092                 commit $commit
1093                 Author: A U Thor <author@example.com>
1094                 Date:   Thu Apr 7 15:27:13 2005 -0700
1095
1096                 ${indent}15th
1097
1098                 Notes:
1099                 ${indent}a fresh note
1100                 ${indent}
1101                 ${indent}another fresh note
1102         EOF
1103         git notes add -f -m"another fresh note" HEAD^ &&
1104         test_config notes.rewriteMode concatenate &&
1105         test_config notes.rewriteRef "refs/notes/*" &&
1106         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1107         git notes copy --for-rewrite=foo &&
1108         git log -1 >actual &&
1109         test_cmp expect actual
1110 '
1111
1112 test_expect_success 'git notes copy --for-rewrite (append two to one)' '
1113         commit=$(git rev-parse HEAD) &&
1114         cat >expect <<-EOF &&
1115                 commit $commit
1116                 Author: A U Thor <author@example.com>
1117                 Date:   Thu Apr 7 15:27:13 2005 -0700
1118
1119                 ${indent}15th
1120
1121                 Notes:
1122                 ${indent}a fresh note
1123                 ${indent}
1124                 ${indent}another fresh note
1125                 ${indent}
1126                 ${indent}append 1
1127                 ${indent}
1128                 ${indent}append 2
1129         EOF
1130         git notes add -f -m"append 1" HEAD^ &&
1131         git notes add -f -m"append 2" HEAD^^ &&
1132         test_config notes.rewriteMode concatenate &&
1133         test_config notes.rewriteRef "refs/notes/*" &&
1134         (echo $(git rev-parse HEAD^) $(git rev-parse HEAD) &&
1135         echo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) |
1136         git notes copy --for-rewrite=foo &&
1137         git log -1 >actual &&
1138         test_cmp expect actual
1139 '
1140
1141 test_expect_success 'git notes copy --for-rewrite (append empty)' '
1142         git notes remove HEAD^ &&
1143         test_config notes.rewriteMode concatenate &&
1144         test_config notes.rewriteRef "refs/notes/*" &&
1145         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1146         git notes copy --for-rewrite=foo &&
1147         git log -1 >actual &&
1148         test_cmp expect actual
1149 '
1150
1151 test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
1152         commit=$(git rev-parse HEAD) &&
1153         cat >expect <<-EOF &&
1154                 commit $commit
1155                 Author: A U Thor <author@example.com>
1156                 Date:   Thu Apr 7 15:27:13 2005 -0700
1157
1158                 ${indent}15th
1159
1160                 Notes:
1161                 ${indent}replacement note 1
1162         EOF
1163         test_config notes.rewriteMode concatenate &&
1164         test_config notes.rewriteRef "refs/notes/*" &&
1165         git notes add -f -m"replacement note 1" HEAD^ &&
1166         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1167         GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo &&
1168         git log -1 >actual &&
1169         test_cmp expect actual
1170 '
1171
1172 test_expect_success 'GIT_NOTES_REWRITE_REF works' '
1173         commit=$(git rev-parse HEAD) &&
1174         cat >expect <<-EOF &&
1175                 commit $commit
1176                 Author: A U Thor <author@example.com>
1177                 Date:   Thu Apr 7 15:27:13 2005 -0700
1178
1179                 ${indent}15th
1180
1181                 Notes:
1182                 ${indent}replacement note 2
1183         EOF
1184         git notes add -f -m"replacement note 2" HEAD^ &&
1185         test_config notes.rewriteMode overwrite &&
1186         test_unconfig notes.rewriteRef &&
1187         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1188         GIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \
1189                 git notes copy --for-rewrite=foo &&
1190         git log -1 >actual &&
1191         test_cmp expect actual
1192 '
1193
1194 test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
1195         git notes add -f -m"replacement note 3" HEAD^ &&
1196         test_config notes.rewriteMode overwrite &&
1197         test_config notes.rewriteRef refs/notes/other &&
1198         echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
1199         GIT_NOTES_REWRITE_REF=refs/notes/commits \
1200                 git notes copy --for-rewrite=foo &&
1201         git log -1 >actual &&
1202         grep "replacement note 3" actual
1203 '
1204
1205 test_expect_success 'git notes copy diagnoses too many or too few parameters' '
1206         test_must_fail git notes copy 2>error &&
1207         test_i18ngrep "too few parameters" error &&
1208         test_must_fail git notes copy one two three 2>error &&
1209         test_i18ngrep "too many parameters" error
1210 '
1211
1212 test_expect_success 'git notes get-ref expands refs/heads/master to refs/notes/refs/heads/master' '
1213         test_unconfig core.notesRef &&
1214         sane_unset GIT_NOTES_REF &&
1215         test "$(git notes --ref=refs/heads/master get-ref)" = "refs/notes/refs/heads/master"
1216 '
1217
1218 test_expect_success 'git notes get-ref (no overrides)' '
1219         test_unconfig core.notesRef &&
1220         sane_unset GIT_NOTES_REF &&
1221         test "$(git notes get-ref)" = "refs/notes/commits"
1222 '
1223
1224 test_expect_success 'git notes get-ref (core.notesRef)' '
1225         test_config core.notesRef refs/notes/foo &&
1226         test "$(git notes get-ref)" = "refs/notes/foo"
1227 '
1228
1229 test_expect_success 'git notes get-ref (GIT_NOTES_REF)' '
1230         test "$(GIT_NOTES_REF=refs/notes/bar git notes get-ref)" = "refs/notes/bar"
1231 '
1232
1233 test_expect_success 'git notes get-ref (--ref)' '
1234         test "$(GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref)" = "refs/notes/baz"
1235 '
1236
1237 test_expect_success 'setup testing of empty notes' '
1238         test_unconfig core.notesRef &&
1239         test_commit 16th &&
1240         empty_blob=$(git hash-object -w /dev/null) &&
1241         echo "$empty_blob" >expect_empty
1242 '
1243
1244 while read cmd
1245 do
1246         test_expect_success "'git notes $cmd' removes empty note" "
1247                 test_might_fail git notes remove HEAD &&
1248                 MSG= git notes $cmd &&
1249                 test_must_fail git notes list HEAD
1250         "
1251
1252         test_expect_success "'git notes $cmd --allow-empty' stores empty note" "
1253                 test_might_fail git notes remove HEAD &&
1254                 MSG= git notes $cmd --allow-empty &&
1255                 git notes list HEAD >actual &&
1256                 test_cmp expect_empty actual
1257         "
1258 done <<\EOF
1259 add
1260 add -F /dev/null
1261 add -m ""
1262 add -c "$empty_blob"
1263 add -C "$empty_blob"
1264 append
1265 append -F /dev/null
1266 append -m ""
1267 append -c "$empty_blob"
1268 append -C "$empty_blob"
1269 edit
1270 EOF
1271
1272 test_expect_success 'empty notes are displayed by git log' '
1273         test_commit 17th &&
1274         git log -1 >expect &&
1275         cat >>expect <<-EOF &&
1276
1277                 Notes:
1278         EOF
1279         git notes add -C "$empty_blob" --allow-empty &&
1280         git log -1 >actual &&
1281         test_cmp expect actual
1282 '
1283
1284 test_done