Merge branch 'rs/archive-add-file'
[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 'GIT_NOTES_DISPLAY_REF works' '
676         GIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \
677                 git log -2 >actual &&
678         test_cmp expect-both actual
679 '
680
681 test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
682         commit=$(git rev-parse HEAD) &&
683         parent=$(git rev-parse HEAD^) &&
684         cat >expect-none <<-EOF &&
685                 commit $commit
686                 Author: A U Thor <author@example.com>
687                 Date:   Thu Apr 7 15:18:13 2005 -0700
688
689                 ${indent}6th
690
691                 commit $parent
692                 Author: A U Thor <author@example.com>
693                 Date:   Thu Apr 7 15:17:13 2005 -0700
694
695                 ${indent}5th
696         EOF
697         test_config notes.displayRef "refs/notes/*" &&
698         GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 >actual &&
699         test_cmp expect-none actual
700 '
701
702 test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
703         GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 >actual &&
704         test_cmp expect-both actual
705 '
706
707 test_expect_success '--no-standard-notes' '
708         commit=$(git rev-parse HEAD) &&
709         cat >expect-commits <<-EOF &&
710                 commit $commit
711                 Author: A U Thor <author@example.com>
712                 Date:   Thu Apr 7 15:18:13 2005 -0700
713
714                 ${indent}6th
715
716                 Notes:
717                 ${indent}order test
718         EOF
719         git log --no-standard-notes --show-notes=commits -1 >actual &&
720         test_cmp expect-commits actual
721 '
722
723 test_expect_success '--standard-notes' '
724         test_config notes.displayRef "refs/notes/*" &&
725         git log --no-standard-notes --show-notes=commits \
726                 --standard-notes -2 >actual &&
727         test_cmp expect-both actual
728 '
729
730 test_expect_success '--show-notes=ref accumulates' '
731         git log --show-notes=other --show-notes=commits \
732                  --no-standard-notes -1 >actual &&
733         test_cmp expect-both-reversed actual
734 '
735
736 test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
737         test_config core.notesRef refs/notes/other &&
738         echo "Note on a tree" >expect &&
739         git notes add -m "Note on a tree" HEAD: &&
740         git notes show HEAD: >actual &&
741         test_cmp expect actual &&
742         echo "Note on a blob" >expect &&
743         git ls-tree --name-only HEAD >files &&
744         filename=$(head -n1 files) &&
745         git notes add -m "Note on a blob" HEAD:$filename &&
746         git notes show HEAD:$filename >actual &&
747         test_cmp expect actual &&
748         echo "Note on a tag" >expect &&
749         git tag -a -m "This is an annotated tag" foobar HEAD^ &&
750         git notes add -m "Note on a tag" foobar &&
751         git notes show foobar >actual &&
752         test_cmp expect actual
753 '
754
755 test_expect_success 'create note from other note with "git notes add -C"' '
756         test_commit 7th &&
757         commit=$(git rev-parse HEAD) &&
758         cat >expect <<-EOF &&
759                 commit $commit
760                 Author: A U Thor <author@example.com>
761                 Date:   Thu Apr 7 15:19:13 2005 -0700
762
763                 ${indent}7th
764
765                 Notes:
766                 ${indent}order test
767         EOF
768         note=$(git notes list HEAD^) &&
769         git notes add -C $note &&
770         git log -1 >actual &&
771         test_cmp expect actual &&
772         git notes list HEAD^ >expect &&
773         git notes list HEAD >actual &&
774         test_cmp expect actual
775 '
776
777 test_expect_success 'create note from non-existing note with "git notes add -C" fails' '
778         test_commit 8th &&
779         test_must_fail git notes add -C deadbeef &&
780         test_must_fail git notes list HEAD
781 '
782
783 test_expect_success 'create note from non-blob with "git notes add -C" fails' '
784         commit=$(git rev-parse --verify HEAD) &&
785         tree=$(git rev-parse --verify HEAD:) &&
786         test_must_fail git notes add -C $commit &&
787         test_must_fail git notes add -C $tree &&
788         test_must_fail git notes list HEAD
789 '
790
791 test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
792         commit=$(git rev-parse HEAD) &&
793         cat >expect <<-EOF &&
794                 commit $commit
795                 Author: A U Thor <author@example.com>
796                 Date:   Thu Apr 7 15:20:13 2005 -0700
797
798                 ${indent}8th
799
800                 Notes:
801                 ${indent}This is a blob object
802         EOF
803         echo "This is a blob object" | git hash-object -w --stdin >blob &&
804         git notes add -C $(cat blob) &&
805         git log -1 >actual &&
806         test_cmp expect actual &&
807         git notes list HEAD >actual &&
808         test_cmp blob actual
809 '
810
811 test_expect_success 'create note from other note with "git notes add -c"' '
812         test_commit 9th &&
813         commit=$(git rev-parse HEAD) &&
814         cat >expect <<-EOF &&
815                 commit $commit
816                 Author: A U Thor <author@example.com>
817                 Date:   Thu Apr 7 15:21:13 2005 -0700
818
819                 ${indent}9th
820
821                 Notes:
822                 ${indent}yet another note
823         EOF
824         note=$(git notes list HEAD^^) &&
825         MSG="yet another note" git notes add -c $note &&
826         git log -1 >actual &&
827         test_cmp expect actual
828 '
829
830 test_expect_success 'create note from non-existing note with "git notes add -c" fails' '
831         test_commit 10th &&
832         test_must_fail env MSG="yet another note" git notes add -c deadbeef &&
833         test_must_fail git notes list HEAD
834 '
835
836 test_expect_success 'append to note from other note with "git notes append -C"' '
837         commit=$(git rev-parse HEAD^) &&
838         cat >expect <<-EOF &&
839                 commit $commit
840                 Author: A U Thor <author@example.com>
841                 Date:   Thu Apr 7 15:21:13 2005 -0700
842
843                 ${indent}9th
844
845                 Notes:
846                 ${indent}yet another note
847                 ${indent}
848                 ${indent}yet another note
849         EOF
850         note=$(git notes list HEAD^) &&
851         git notes append -C $note HEAD^ &&
852         git log -1 HEAD^ >actual &&
853         test_cmp expect actual
854 '
855
856 test_expect_success 'create note from other note with "git notes append -c"' '
857         commit=$(git rev-parse HEAD) &&
858         cat >expect <<-EOF &&
859                 commit $commit
860                 Author: A U Thor <author@example.com>
861                 Date:   Thu Apr 7 15:22:13 2005 -0700
862
863                 ${indent}10th
864
865                 Notes:
866                 ${indent}other note
867         EOF
868         note=$(git notes list HEAD^) &&
869         MSG="other note" git notes append -c $note &&
870         git log -1 >actual &&
871         test_cmp expect actual
872 '
873
874 test_expect_success 'append to note from other note with "git notes append -c"' '
875         commit=$(git rev-parse HEAD) &&
876         cat >expect <<-EOF &&
877                 commit $commit
878                 Author: A U Thor <author@example.com>
879                 Date:   Thu Apr 7 15:22:13 2005 -0700
880
881                 ${indent}10th
882
883                 Notes:
884                 ${indent}other note
885                 ${indent}
886                 ${indent}yet another note
887         EOF
888         note=$(git notes list HEAD) &&
889         MSG="yet another note" git notes append -c $note &&
890         git log -1 >actual &&
891         test_cmp expect actual
892 '
893
894 test_expect_success 'copy note with "git notes copy"' '
895         commit=$(git rev-parse 4th) &&
896         cat >expect <<-EOF &&
897                 commit $commit
898                 Author: A U Thor <author@example.com>
899                 Date:   Thu Apr 7 15:16:13 2005 -0700
900
901                 ${indent}4th
902
903                 Notes:
904                 ${indent}This is a blob object
905         EOF
906         git notes copy 8th 4th &&
907         git log 3rd..4th >actual &&
908         test_cmp expect actual &&
909         git notes list 4th >expect &&
910         git notes list 8th >actual &&
911         test_cmp expect actual
912 '
913
914 test_expect_success 'copy note with "git notes copy" with default' '
915         test_commit 11th &&
916         commit=$(git rev-parse HEAD) &&
917         cat >expect <<-EOF &&
918                 commit $commit
919                 Author: A U Thor <author@example.com>
920                 Date:   Thu Apr 7 15:23:13 2005 -0700
921
922                 ${indent}11th
923
924                 Notes:
925                 ${indent}other note
926                 ${indent}
927                 ${indent}yet another note
928         EOF
929         git notes copy HEAD^ &&
930         git log -1 >actual &&
931         test_cmp expect actual &&
932         git notes list HEAD^ >expect &&
933         git notes list HEAD >actual &&
934         test_cmp expect actual
935 '
936
937 test_expect_success 'prevent overwrite with "git notes copy"' '
938         test_must_fail git notes copy HEAD~2 HEAD &&
939         cat >expect <<-EOF &&
940                 commit $commit
941                 Author: A U Thor <author@example.com>
942                 Date:   Thu Apr 7 15:23:13 2005 -0700
943
944                 ${indent}11th
945
946                 Notes:
947                 ${indent}other note
948                 ${indent}
949                 ${indent}yet another note
950         EOF
951         git log -1 >actual &&
952         test_cmp expect actual &&
953         git notes list HEAD^ >expect &&
954         git notes list HEAD >actual &&
955         test_cmp expect actual
956 '
957
958 test_expect_success 'allow overwrite with "git notes copy -f"' '
959         commit=$(git rev-parse HEAD) &&
960         cat >expect <<-EOF &&
961                 commit $commit
962                 Author: A U Thor <author@example.com>
963                 Date:   Thu Apr 7 15:23:13 2005 -0700
964
965                 ${indent}11th
966
967                 Notes:
968                 ${indent}This is a blob object
969         EOF
970         git notes copy -f HEAD~3 HEAD &&
971         git log -1 >actual &&
972         test_cmp expect actual &&
973         git notes list HEAD~3 >expect &&
974         git notes list HEAD >actual &&
975         test_cmp expect actual
976 '
977
978 test_expect_success 'allow overwrite with "git notes copy -f" with default' '
979         commit=$(git rev-parse HEAD) &&
980         cat >expect <<-EOF &&
981                 commit $commit
982                 Author: A U Thor <author@example.com>
983                 Date:   Thu Apr 7 15:23:13 2005 -0700
984
985                 ${indent}11th
986
987                 Notes:
988                 ${indent}yet another note
989                 ${indent}
990                 ${indent}yet another note
991         EOF
992         git notes copy -f HEAD~2 &&
993         git log -1 >actual &&
994         test_cmp expect actual &&
995         git notes list HEAD~2 >expect &&
996         git notes list HEAD >actual &&
997         test_cmp expect actual
998 '
999
1000 test_expect_success 'cannot copy note from object without notes' '
1001         test_commit 12th &&
1002         test_commit 13th &&
1003         test_must_fail git notes copy HEAD^ HEAD
1004 '
1005
1006 test_expect_success 'git notes copy --stdin' '
1007         commit=$(git rev-parse HEAD) &&
1008         parent=$(git rev-parse HEAD^) &&
1009         cat >expect <<-EOF &&
1010                 commit $commit
1011                 Author: A U Thor <author@example.com>
1012                 Date:   Thu Apr 7 15:25:13 2005 -0700
1013
1014                 ${indent}13th
1015
1016                 Notes:
1017                 ${indent}yet another note
1018                 ${indent}
1019                 ${indent}yet another note
1020
1021                 commit $parent
1022                 Author: A U Thor <author@example.com>
1023                 Date:   Thu Apr 7 15:24:13 2005 -0700
1024
1025                 ${indent}12th
1026
1027                 Notes:
1028                 ${indent}other note
1029                 ${indent}
1030                 ${indent}yet another note
1031         EOF
1032         from=$(git rev-parse HEAD~3) &&
1033         to=$(git rev-parse HEAD^) &&
1034         echo "$from" "$to" >copy &&
1035         from=$(git rev-parse HEAD~2) &&
1036         to=$(git rev-parse HEAD) &&
1037         echo "$from" "$to" >>copy &&
1038         git notes copy --stdin <copy &&
1039         git log -2 >actual &&
1040         test_cmp expect actual &&
1041         git notes list HEAD~2 >expect &&
1042         git notes list HEAD >actual &&
1043         test_cmp expect actual &&
1044         git notes list HEAD~3 >expect &&
1045         git notes list HEAD^ >actual &&
1046         test_cmp expect actual
1047 '
1048
1049 test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
1050         test_commit 14th &&
1051         test_commit 15th &&
1052         commit=$(git rev-parse HEAD) &&
1053         parent=$(git rev-parse HEAD^) &&
1054         cat >expect <<-EOF &&
1055                 commit $commit
1056                 Author: A U Thor <author@example.com>
1057                 Date:   Thu Apr 7 15:27:13 2005 -0700
1058
1059                 ${indent}15th
1060
1061                 commit $parent
1062                 Author: A U Thor <author@example.com>
1063                 Date:   Thu Apr 7 15:26:13 2005 -0700
1064
1065                 ${indent}14th
1066         EOF
1067         from=$(git rev-parse HEAD~3) &&
1068         to=$(git rev-parse HEAD^) &&
1069         echo "$from" "$to" >copy &&
1070         from=$(git rev-parse HEAD~2) &&
1071         to=$(git rev-parse HEAD) &&
1072         echo "$from" "$to" >>copy &&
1073         git notes copy --for-rewrite=foo <copy &&
1074         git log -2 >actual &&
1075         test_cmp expect actual
1076 '
1077
1078 test_expect_success 'git notes copy --for-rewrite (enabled)' '
1079         commit=$(git rev-parse HEAD) &&
1080         parent=$(git rev-parse HEAD^) &&
1081         cat >expect <<-EOF &&
1082                 commit $commit
1083                 Author: A U Thor <author@example.com>
1084                 Date:   Thu Apr 7 15:27:13 2005 -0700
1085
1086                 ${indent}15th
1087
1088                 Notes:
1089                 ${indent}yet another note
1090                 ${indent}
1091                 ${indent}yet another note
1092
1093                 commit $parent
1094                 Author: A U Thor <author@example.com>
1095                 Date:   Thu Apr 7 15:26:13 2005 -0700
1096
1097                 ${indent}14th
1098
1099                 Notes:
1100                 ${indent}other note
1101                 ${indent}
1102                 ${indent}yet another note
1103         EOF
1104         test_config notes.rewriteMode overwrite &&
1105         test_config notes.rewriteRef "refs/notes/*" &&
1106         from=$(git rev-parse HEAD~3) &&
1107         to=$(git rev-parse HEAD^) &&
1108         echo "$from" "$to" >copy &&
1109         from=$(git rev-parse HEAD~2) &&
1110         to=$(git rev-parse HEAD) &&
1111         echo "$from" "$to" >>copy &&
1112         git notes copy --for-rewrite=foo <copy &&
1113         git log -2 >actual &&
1114         test_cmp expect actual
1115 '
1116
1117 test_expect_success 'git notes copy --for-rewrite (disabled)' '
1118         test_config notes.rewrite.bar false &&
1119         from=$(git rev-parse HEAD~3) &&
1120         to=$(git rev-parse HEAD) &&
1121         echo "$from" "$to" >copy &&
1122         git notes copy --for-rewrite=bar <copy &&
1123         git log -2 >actual &&
1124         test_cmp expect actual
1125 '
1126
1127 test_expect_success 'git notes copy --for-rewrite (overwrite)' '
1128         commit=$(git rev-parse HEAD) &&
1129         cat >expect <<-EOF &&
1130                 commit $commit
1131                 Author: A U Thor <author@example.com>
1132                 Date:   Thu Apr 7 15:27:13 2005 -0700
1133
1134                 ${indent}15th
1135
1136                 Notes:
1137                 ${indent}a fresh note
1138         EOF
1139         git notes add -f -m"a fresh note" HEAD^ &&
1140         test_config notes.rewriteMode overwrite &&
1141         test_config notes.rewriteRef "refs/notes/*" &&
1142         from=$(git rev-parse HEAD^) &&
1143         to=$(git rev-parse HEAD) &&
1144         echo "$from" "$to" >copy &&
1145         git notes copy --for-rewrite=foo <copy &&
1146         git log -1 >actual &&
1147         test_cmp expect actual
1148 '
1149
1150 test_expect_success 'git notes copy --for-rewrite (ignore)' '
1151         test_config notes.rewriteMode ignore &&
1152         test_config notes.rewriteRef "refs/notes/*" &&
1153         from=$(git rev-parse HEAD^) &&
1154         to=$(git rev-parse HEAD) &&
1155         echo "$from" "$to" >copy &&
1156         git notes copy --for-rewrite=foo <copy &&
1157         git log -1 >actual &&
1158         test_cmp expect actual
1159 '
1160
1161 test_expect_success 'git notes copy --for-rewrite (append)' '
1162         commit=$(git rev-parse HEAD) &&
1163         cat >expect <<-EOF &&
1164                 commit $commit
1165                 Author: A U Thor <author@example.com>
1166                 Date:   Thu Apr 7 15:27:13 2005 -0700
1167
1168                 ${indent}15th
1169
1170                 Notes:
1171                 ${indent}a fresh note
1172                 ${indent}
1173                 ${indent}another fresh note
1174         EOF
1175         git notes add -f -m"another fresh note" HEAD^ &&
1176         test_config notes.rewriteMode concatenate &&
1177         test_config notes.rewriteRef "refs/notes/*" &&
1178         from=$(git rev-parse HEAD^) &&
1179         to=$(git rev-parse HEAD) &&
1180         echo "$from" "$to" >copy &&
1181         git notes copy --for-rewrite=foo <copy &&
1182         git log -1 >actual &&
1183         test_cmp expect actual
1184 '
1185
1186 test_expect_success 'git notes copy --for-rewrite (append two to one)' '
1187         commit=$(git rev-parse HEAD) &&
1188         cat >expect <<-EOF &&
1189                 commit $commit
1190                 Author: A U Thor <author@example.com>
1191                 Date:   Thu Apr 7 15:27:13 2005 -0700
1192
1193                 ${indent}15th
1194
1195                 Notes:
1196                 ${indent}a fresh note
1197                 ${indent}
1198                 ${indent}another fresh note
1199                 ${indent}
1200                 ${indent}append 1
1201                 ${indent}
1202                 ${indent}append 2
1203         EOF
1204         git notes add -f -m"append 1" HEAD^ &&
1205         git notes add -f -m"append 2" HEAD^^ &&
1206         test_config notes.rewriteMode concatenate &&
1207         test_config notes.rewriteRef "refs/notes/*" &&
1208         from=$(git rev-parse HEAD^) &&
1209         to=$(git rev-parse HEAD) &&
1210         echo "$from" "$to" >copy &&
1211         from=$(git rev-parse HEAD^^) &&
1212         to=$(git rev-parse HEAD) &&
1213         echo "$from" "$to" >>copy &&
1214         git notes copy --for-rewrite=foo <copy &&
1215         git log -1 >actual &&
1216         test_cmp expect actual
1217 '
1218
1219 test_expect_success 'git notes copy --for-rewrite (append empty)' '
1220         git notes remove HEAD^ &&
1221         test_config notes.rewriteMode concatenate &&
1222         test_config notes.rewriteRef "refs/notes/*" &&
1223         from=$(git rev-parse HEAD^) &&
1224         to=$(git rev-parse HEAD) &&
1225         echo "$from" "$to" >copy &&
1226         git notes copy --for-rewrite=foo <copy &&
1227         git log -1 >actual &&
1228         test_cmp expect actual
1229 '
1230
1231 test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
1232         commit=$(git rev-parse HEAD) &&
1233         cat >expect <<-EOF &&
1234                 commit $commit
1235                 Author: A U Thor <author@example.com>
1236                 Date:   Thu Apr 7 15:27:13 2005 -0700
1237
1238                 ${indent}15th
1239
1240                 Notes:
1241                 ${indent}replacement note 1
1242         EOF
1243         test_config notes.rewriteMode concatenate &&
1244         test_config notes.rewriteRef "refs/notes/*" &&
1245         git notes add -f -m"replacement note 1" HEAD^ &&
1246         from=$(git rev-parse HEAD^) &&
1247         to=$(git rev-parse HEAD) &&
1248         echo "$from" "$to" >copy &&
1249         GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo <copy &&
1250         git log -1 >actual &&
1251         test_cmp expect actual
1252 '
1253
1254 test_expect_success 'GIT_NOTES_REWRITE_REF works' '
1255         commit=$(git rev-parse HEAD) &&
1256         cat >expect <<-EOF &&
1257                 commit $commit
1258                 Author: A U Thor <author@example.com>
1259                 Date:   Thu Apr 7 15:27:13 2005 -0700
1260
1261                 ${indent}15th
1262
1263                 Notes:
1264                 ${indent}replacement note 2
1265         EOF
1266         git notes add -f -m"replacement note 2" HEAD^ &&
1267         test_config notes.rewriteMode overwrite &&
1268         test_unconfig notes.rewriteRef &&
1269         from=$(git rev-parse HEAD^) &&
1270         to=$(git rev-parse HEAD) &&
1271         echo "$from" "$to" >copy &&
1272         GIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \
1273                 git notes copy --for-rewrite=foo <copy &&
1274         git log -1 >actual &&
1275         test_cmp expect actual
1276 '
1277
1278 test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
1279         git notes add -f -m"replacement note 3" HEAD^ &&
1280         test_config notes.rewriteMode overwrite &&
1281         test_config notes.rewriteRef refs/notes/other &&
1282         from=$(git rev-parse HEAD^) &&
1283         to=$(git rev-parse HEAD) &&
1284         echo "$from" "$to" >copy &&
1285         GIT_NOTES_REWRITE_REF=refs/notes/commits \
1286                 git notes copy --for-rewrite=foo <copy &&
1287         git log -1 >actual &&
1288         grep "replacement note 3" actual
1289 '
1290
1291 test_expect_success 'git notes copy diagnoses too many or too few parameters' '
1292         test_must_fail git notes copy 2>error &&
1293         test_i18ngrep "too few parameters" error &&
1294         test_must_fail git notes copy one two three 2>error &&
1295         test_i18ngrep "too many parameters" error
1296 '
1297
1298 test_expect_success 'git notes get-ref expands refs/heads/master to refs/notes/refs/heads/master' '
1299         test_unconfig core.notesRef &&
1300         sane_unset GIT_NOTES_REF &&
1301         echo refs/notes/refs/heads/master >expect &&
1302         git notes --ref=refs/heads/master get-ref >actual &&
1303         test_cmp expect actual
1304 '
1305
1306 test_expect_success 'git notes get-ref (no overrides)' '
1307         test_unconfig core.notesRef &&
1308         sane_unset GIT_NOTES_REF &&
1309         echo refs/notes/commits >expect &&
1310         git notes get-ref >actual &&
1311         test_cmp expect actual
1312 '
1313
1314 test_expect_success 'git notes get-ref (core.notesRef)' '
1315         test_config core.notesRef refs/notes/foo &&
1316         echo refs/notes/foo >expect &&
1317         git notes get-ref >actual &&
1318         test_cmp expect actual
1319 '
1320
1321 test_expect_success 'git notes get-ref (GIT_NOTES_REF)' '
1322         echo refs/notes/bar >expect &&
1323         GIT_NOTES_REF=refs/notes/bar git notes get-ref >actual &&
1324         test_cmp expect actual
1325 '
1326
1327 test_expect_success 'git notes get-ref (--ref)' '
1328         echo refs/notes/baz >expect &&
1329         GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref >actual &&
1330         test_cmp expect actual
1331 '
1332
1333 test_expect_success 'setup testing of empty notes' '
1334         test_unconfig core.notesRef &&
1335         test_commit 16th &&
1336         empty_blob=$(git hash-object -w /dev/null) &&
1337         echo "$empty_blob" >expect_empty
1338 '
1339
1340 while read cmd
1341 do
1342         test_expect_success "'git notes $cmd' removes empty note" "
1343                 test_might_fail git notes remove HEAD &&
1344                 MSG= git notes $cmd &&
1345                 test_must_fail git notes list HEAD
1346         "
1347
1348         test_expect_success "'git notes $cmd --allow-empty' stores empty note" "
1349                 test_might_fail git notes remove HEAD &&
1350                 MSG= git notes $cmd --allow-empty &&
1351                 git notes list HEAD >actual &&
1352                 test_cmp expect_empty actual
1353         "
1354 done <<\EOF
1355 add
1356 add -F /dev/null
1357 add -m ""
1358 add -c "$empty_blob"
1359 add -C "$empty_blob"
1360 append
1361 append -F /dev/null
1362 append -m ""
1363 append -c "$empty_blob"
1364 append -C "$empty_blob"
1365 edit
1366 EOF
1367
1368 test_expect_success 'empty notes are displayed by git log' '
1369         test_commit 17th &&
1370         git log -1 >expect &&
1371         cat >>expect <<-EOF &&
1372
1373                 Notes:
1374         EOF
1375         git notes add -C "$empty_blob" --allow-empty &&
1376         git log -1 >actual &&
1377         test_cmp expect actual
1378 '
1379
1380 test_done