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