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