{"thread":{"id":"37914","subject":"[PATCHv4 0/9] Handling empty notes","startedAt":"2014-11-09T12:30:46Z","lastAt":"2014-11-11T15:53:02Z","messageCount":17,"participants":["Johan Herland","Junio C Hamano","Eric Sunshine"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"251595","messageId":"1415536255-19961-1-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":null,"subject":"[PATCHv4 0/9] Handling empty notes","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:46Z","receivedAt":"2014-11-09T12:30:46Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Changes v3 -> v4:\n - Incorporate more feedback from Junio:\n    - Patch #1: s/git config --unset/test_unconfig/\n - Add patches #3 - #6 to refactor add()/append_edit()/create_note()\n   for supporting the direction suggested by Junio\n - Revamp the last patch to more fully modernize t3301\n\n\nHave fun! :)\n\n...Johan\n\nJohan Herland (9):\n  builtin/notes: Fix premature failure when trying to add the empty blob\n  t3301: Verify that 'git notes' removes empty notes by default\n  builtin/notes: Improve naming\n  builtin/notes: Refactor note file path into struct note_data\n  builtin/notes: Simplify early exit code in add()\n  builtin/notes: Split create_note() to clarify add vs. remove logic\n  builtin/notes: Add --allow-empty, to allow storing empty notes\n  notes: Empty notes should be shown by 'git log'\n  t3301: Modernize\n\n Documentation/git-notes.txt |   12 +-\n builtin/notes.c             |  235 +++++----\n notes.c                     |    3 +-\n t/t3301-notes.sh            | 1189 ++++++++++++++++++++-----------------------\n 4 files changed, 698 insertions(+), 741 deletions(-)\n\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251597","messageId":"1415536255-19961-2-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 1/9] builtin/notes: Fix premature failure when trying to add the empty blob","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:47Z","receivedAt":"2014-11-09T12:30:47Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"This fixes a small buglet when trying to explicitly add the empty blob\nas a note object using the -c or -C option to git notes add/append.\nInstead of failing with a nonsensical error message indicating that the\nempty blob does not exist, we should rather behave as if an empty notes\nmessage was given (e.g. using -m \"\" or -F /dev/null).\n\nThe next patch contains a test that verifies the fixed behavior.\n\nFound-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n builtin/notes.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 68b6cd8..9ee6816 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -266,7 +266,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)\n \n \tif (get_sha1(arg, object))\n \t\tdie(_(\"Failed to resolve '%s' as a valid ref.\"), arg);\n-\tif (!(buf = read_sha1_file(object, &type, &len)) || !len) {\n+\tif (!(buf = read_sha1_file(object, &type, &len))) {\n \t\tfree(buf);\n \t\tdie(_(\"Failed to read object '%s'.\"), arg);\n \t}\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251598","messageId":"1415536255-19961-3-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 2/9] t3301: Verify that 'git notes' removes empty notes by default","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:48Z","receivedAt":"2014-11-09T12:30:48Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Add test cases documenting the current behavior when trying to\nadd/append/edit empty notes. This is in preparation for adding\n--allow-empty; to allow empty notes to be stored.\n\nImproved-by: Eric Sunshine <sunshine@sunshineco.com>\nImproved-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n t/t3301-notes.sh | 27 +++++++++++++++++++++++++++\n 1 file changed, 27 insertions(+)\n\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex cfd67ff..f74b3fa 100755\n--- a/t/t3301-notes.sh\n+++ b/t/t3301-notes.sh\n@@ -1239,4 +1239,31 @@ test_expect_success 'git notes get-ref (--ref)' '\n \ttest \"$(GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref)\" = \"refs/notes/baz\"\n '\n \n+test_expect_success 'setup testing of empty notes' '\n+\ttest_unconfig core.notesRef &&\n+\ttest_commit 16th &&\n+\tempty_blob=$(git hash-object -w /dev/null)\n+'\n+\n+while read cmd\n+do\n+\ttest_expect_success \"'git notes $cmd' removes empty note\" \"\n+\t\ttest_might_fail git notes remove HEAD &&\n+\t\tMSG= git notes $cmd &&\n+\t\ttest_must_fail git notes list HEAD\n+\t\"\n+done <<\\EOF\n+add\n+add -F /dev/null\n+add -m \"\"\n+add -c \"$empty_blob\"\n+add -C \"$empty_blob\"\n+append\n+append -F /dev/null\n+append -m \"\"\n+append -c \"$empty_blob\"\n+append -C \"$empty_blob\"\n+edit\n+EOF\n+\n test_done\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251596","messageId":"1415536255-19961-4-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 3/9] builtin/notes: Improve naming","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:49Z","receivedAt":"2014-11-09T12:30:49Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"In preparation for some needed refactoring, rename struct msg_arg to\nstruct note_data, and rename its instances from \"msg\" to \"d\" (also\nremoving some unnecessary parentheses). The 'msg_arg' name was\ninherited from tag.c, but is not really a good name for the contents\nof a note.\n\nAlso rename write_note_data() to copy_obj_to_fd(), which more aptly\ndescribes what it actually does: Copying the contents of a git object\n(given by its SHA1) into a given file descriptor.\n\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n builtin/notes.c | 109 ++++++++++++++++++++++++++++----------------------------\n 1 file changed, 54 insertions(+), 55 deletions(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 9ee6816..3cf22cb 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -92,7 +92,7 @@ static const char * const git_notes_get_ref_usage[] = {\n static const char note_template[] =\n \t\"\\nWrite/edit the notes for the following object:\\n\";\n \n-struct msg_arg {\n+struct note_data {\n \tint given;\n \tint use_editor;\n \tstruct strbuf buf;\n@@ -106,7 +106,7 @@ static int list_each_note(const unsigned char *object_sha1,\n \treturn 0;\n }\n \n-static void write_note_data(int fd, const unsigned char *sha1)\n+static void copy_obj_to_fd(int fd, const unsigned char *sha1)\n {\n \tunsigned long size;\n \tenum object_type type;\n@@ -149,13 +149,13 @@ static void write_commented_object(int fd, const unsigned char *object)\n \t\t    sha1_to_hex(object));\n }\n \n-static void create_note(const unsigned char *object, struct msg_arg *msg,\n+static void create_note(const unsigned char *object, struct note_data *d,\n \t\t\tint append_only, const unsigned char *prev,\n \t\t\tunsigned char *result)\n {\n \tchar *path = NULL;\n \n-\tif (msg->use_editor || !msg->given) {\n+\tif (d->use_editor || !d->given) {\n \t\tint fd;\n \t\tstruct strbuf buf = STRBUF_INIT;\n \n@@ -165,10 +165,10 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,\n \t\tif (fd < 0)\n \t\t\tdie_errno(_(\"could not create file '%s'\"), path);\n \n-\t\tif (msg->given)\n-\t\t\twrite_or_die(fd, msg->buf.buf, msg->buf.len);\n+\t\tif (d->given)\n+\t\t\twrite_or_die(fd, d->buf.buf, d->buf.len);\n \t\telse if (prev && !append_only)\n-\t\t\twrite_note_data(fd, prev);\n+\t\t\tcopy_obj_to_fd(fd, prev);\n \n \t\tstrbuf_addch(&buf, '\\n');\n \t\tstrbuf_add_commented_lines(&buf, note_template, strlen(note_template));\n@@ -179,13 +179,12 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,\n \n \t\tclose(fd);\n \t\tstrbuf_release(&buf);\n-\t\tstrbuf_reset(&(msg->buf));\n+\t\tstrbuf_reset(&d->buf);\n \n-\t\tif (launch_editor(path, &(msg->buf), NULL)) {\n-\t\t\tdie(_(\"Please supply the note contents using either -m\" \\\n-\t\t\t    \" or -F option\"));\n+\t\tif (launch_editor(path, &d->buf, NULL)) {\n+\t\t\tdie(_(\"Please supply the note contents using either -m or -F option\"));\n \t\t}\n-\t\tstripspace(&(msg->buf), 1);\n+\t\tstripspace(&d->buf, 1);\n \t}\n \n \tif (prev && append_only) {\n@@ -194,20 +193,20 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,\n \t\tenum object_type type;\n \t\tchar *prev_buf = read_sha1_file(prev, &type, &size);\n \n-\t\tstrbuf_grow(&(msg->buf), size + 1);\n-\t\tif (msg->buf.len && prev_buf && size)\n-\t\t\tstrbuf_insert(&(msg->buf), 0, \"\\n\", 1);\n+\t\tstrbuf_grow(&d->buf, size + 1);\n+\t\tif (d->buf.len && prev_buf && size)\n+\t\t\tstrbuf_insert(&d->buf, 0, \"\\n\", 1);\n \t\tif (prev_buf && size)\n-\t\t\tstrbuf_insert(&(msg->buf), 0, prev_buf, size);\n+\t\t\tstrbuf_insert(&d->buf, 0, prev_buf, size);\n \t\tfree(prev_buf);\n \t}\n \n-\tif (!msg->buf.len) {\n+\tif (!d->buf.len) {\n \t\tfprintf(stderr, _(\"Removing note for object %s\\n\"),\n \t\t\tsha1_to_hex(object));\n \t\thashclr(result);\n \t} else {\n-\t\tif (write_sha1_file(msg->buf.buf, msg->buf.len, blob_type, result)) {\n+\t\tif (write_sha1_file(d->buf.buf, d->buf.len, blob_type, result)) {\n \t\t\terror(_(\"unable to write note object\"));\n \t\t\tif (path)\n \t\t\t\terror(_(\"The note contents have been left in %s\"),\n@@ -224,45 +223,45 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,\n \n static int parse_msg_arg(const struct option *opt, const char *arg, int unset)\n {\n-\tstruct msg_arg *msg = opt->value;\n+\tstruct note_data *d = opt->value;\n \n-\tstrbuf_grow(&(msg->buf), strlen(arg) + 2);\n-\tif (msg->buf.len)\n-\t\tstrbuf_addch(&(msg->buf), '\\n');\n-\tstrbuf_addstr(&(msg->buf), arg);\n-\tstripspace(&(msg->buf), 0);\n+\tstrbuf_grow(&d->buf, strlen(arg) + 2);\n+\tif (d->buf.len)\n+\t\tstrbuf_addch(&d->buf, '\\n');\n+\tstrbuf_addstr(&d->buf, arg);\n+\tstripspace(&d->buf, 0);\n \n-\tmsg->given = 1;\n+\td->given = 1;\n \treturn 0;\n }\n \n static int parse_file_arg(const struct option *opt, const char *arg, int unset)\n {\n-\tstruct msg_arg *msg = opt->value;\n+\tstruct note_data *d = opt->value;\n \n-\tif (msg->buf.len)\n-\t\tstrbuf_addch(&(msg->buf), '\\n');\n+\tif (d->buf.len)\n+\t\tstrbuf_addch(&d->buf, '\\n');\n \tif (!strcmp(arg, \"-\")) {\n-\t\tif (strbuf_read(&(msg->buf), 0, 1024) < 0)\n+\t\tif (strbuf_read(&d->buf, 0, 1024) < 0)\n \t\t\tdie_errno(_(\"cannot read '%s'\"), arg);\n-\t} else if (strbuf_read_file(&(msg->buf), arg, 1024) < 0)\n+\t} else if (strbuf_read_file(&d->buf, arg, 1024) < 0)\n \t\tdie_errno(_(\"could not open or read '%s'\"), arg);\n-\tstripspace(&(msg->buf), 0);\n+\tstripspace(&d->buf, 0);\n \n-\tmsg->given = 1;\n+\td->given = 1;\n \treturn 0;\n }\n \n static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)\n {\n-\tstruct msg_arg *msg = opt->value;\n+\tstruct note_data *d = opt->value;\n \tchar *buf;\n \tunsigned char object[20];\n \tenum object_type type;\n \tunsigned long len;\n \n-\tif (msg->buf.len)\n-\t\tstrbuf_addch(&(msg->buf), '\\n');\n+\tif (d->buf.len)\n+\t\tstrbuf_addch(&d->buf, '\\n');\n \n \tif (get_sha1(arg, object))\n \t\tdie(_(\"Failed to resolve '%s' as a valid ref.\"), arg);\n@@ -274,17 +273,17 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)\n \t\tfree(buf);\n \t\tdie(_(\"Cannot read note data from non-blob object '%s'.\"), arg);\n \t}\n-\tstrbuf_add(&(msg->buf), buf, len);\n+\tstrbuf_add(&d->buf, buf, len);\n \tfree(buf);\n \n-\tmsg->given = 1;\n+\td->given = 1;\n \treturn 0;\n }\n \n static int parse_reedit_arg(const struct option *opt, const char *arg, int unset)\n {\n-\tstruct msg_arg *msg = opt->value;\n-\tmsg->use_editor = 1;\n+\tstruct note_data *d = opt->value;\n+\td->use_editor = 1;\n \treturn parse_reuse_arg(opt, arg, unset);\n }\n \n@@ -403,18 +402,18 @@ static int add(int argc, const char **argv, const char *prefix)\n \tunsigned char object[20], new_note[20];\n \tchar logmsg[100];\n \tconst unsigned char *note;\n-\tstruct msg_arg msg = { 0, 0, STRBUF_INIT };\n+\tstruct note_data d = { 0, 0, STRBUF_INIT };\n \tstruct option options[] = {\n-\t\t{ OPTION_CALLBACK, 'm', \"message\", &msg, N_(\"message\"),\n+\t\t{ OPTION_CALLBACK, 'm', \"message\", &d, N_(\"message\"),\n \t\t\tN_(\"note contents as a string\"), PARSE_OPT_NONEG,\n \t\t\tparse_msg_arg},\n-\t\t{ OPTION_CALLBACK, 'F', \"file\", &msg, N_(\"file\"),\n+\t\t{ OPTION_CALLBACK, 'F', \"file\", &d, N_(\"file\"),\n \t\t\tN_(\"note contents in a file\"), PARSE_OPT_NONEG,\n \t\t\tparse_file_arg},\n-\t\t{ OPTION_CALLBACK, 'c', \"reedit-message\", &msg, N_(\"object\"),\n+\t\t{ OPTION_CALLBACK, 'c', \"reedit-message\", &d, N_(\"object\"),\n \t\t\tN_(\"reuse and edit specified note object\"), PARSE_OPT_NONEG,\n \t\t\tparse_reedit_arg},\n-\t\t{ OPTION_CALLBACK, 'C', \"reuse-message\", &msg, N_(\"object\"),\n+\t\t{ OPTION_CALLBACK, 'C', \"reuse-message\", &d, N_(\"object\"),\n \t\t\tN_(\"reuse specified note object\"), PARSE_OPT_NONEG,\n \t\t\tparse_reuse_arg},\n \t\tOPT__FORCE(&force, N_(\"replace existing notes\")),\n@@ -439,7 +438,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \n \tif (note) {\n \t\tif (!force) {\n-\t\t\tif (!msg.given) {\n+\t\t\tif (!d.given) {\n \t\t\t\t/*\n \t\t\t\t * Redirect to \"edit\" subcommand.\n \t\t\t\t *\n@@ -460,7 +459,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t\tsha1_to_hex(object));\n \t}\n \n-\tcreate_note(object, &msg, 0, note, new_note);\n+\tcreate_note(object, &d, 0, note, new_note);\n \n \tif (is_null_sha1(new_note))\n \t\tremove_note(t, object);\n@@ -472,7 +471,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \tcommit_notes(t, logmsg);\n out:\n \tfree_notes(t);\n-\tstrbuf_release(&(msg.buf));\n+\tstrbuf_release(&d.buf);\n \treturn retval;\n }\n \n@@ -560,18 +559,18 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \tconst unsigned char *note;\n \tchar logmsg[100];\n \tconst char * const *usage;\n-\tstruct msg_arg msg = { 0, 0, STRBUF_INIT };\n+\tstruct note_data d = { 0, 0, STRBUF_INIT };\n \tstruct option options[] = {\n-\t\t{ OPTION_CALLBACK, 'm', \"message\", &msg, N_(\"message\"),\n+\t\t{ OPTION_CALLBACK, 'm', \"message\", &d, N_(\"message\"),\n \t\t\tN_(\"note contents as a string\"), PARSE_OPT_NONEG,\n \t\t\tparse_msg_arg},\n-\t\t{ OPTION_CALLBACK, 'F', \"file\", &msg, N_(\"file\"),\n+\t\t{ OPTION_CALLBACK, 'F', \"file\", &d, N_(\"file\"),\n \t\t\tN_(\"note contents in a file\"), PARSE_OPT_NONEG,\n \t\t\tparse_file_arg},\n-\t\t{ OPTION_CALLBACK, 'c', \"reedit-message\", &msg, N_(\"object\"),\n+\t\t{ OPTION_CALLBACK, 'c', \"reedit-message\", &d, N_(\"object\"),\n \t\t\tN_(\"reuse and edit specified note object\"), PARSE_OPT_NONEG,\n \t\t\tparse_reedit_arg},\n-\t\t{ OPTION_CALLBACK, 'C', \"reuse-message\", &msg, N_(\"object\"),\n+\t\t{ OPTION_CALLBACK, 'C', \"reuse-message\", &d, N_(\"object\"),\n \t\t\tN_(\"reuse specified note object\"), PARSE_OPT_NONEG,\n \t\t\tparse_reuse_arg},\n \t\tOPT_END()\n@@ -587,7 +586,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(usage, options);\n \t}\n \n-\tif (msg.given && edit)\n+\tif (d.given && edit)\n \t\tfprintf(stderr, _(\"The -m/-F/-c/-C options have been deprecated \"\n \t\t\t\"for the 'edit' subcommand.\\n\"\n \t\t\t\"Please use 'git notes add -f -m/-F/-c/-C' instead.\\n\"));\n@@ -600,7 +599,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \tt = init_notes_check(argv[0]);\n \tnote = get_note(t, object);\n \n-\tcreate_note(object, &msg, !edit, note, new_note);\n+\tcreate_note(object, &d, !edit, note, new_note);\n \n \tif (is_null_sha1(new_note))\n \t\tremove_note(t, object);\n@@ -611,7 +610,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \t\t is_null_sha1(new_note) ? \"removed\" : \"added\", argv[0]);\n \tcommit_notes(t, logmsg);\n \tfree_notes(t);\n-\tstrbuf_release(&(msg.buf));\n+\tstrbuf_release(&d.buf);\n \treturn 0;\n }\n \n-- \n2.1.1.392.g062cc5d\n"},{"id":"251604","messageId":"1415536255-19961-5-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 4/9] builtin/notes: Refactor note file path into struct note_data","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:50Z","receivedAt":"2014-11-09T12:30:50Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Move the 'path' variable from create_note() and into the\nnote_data struct. Unify cleanup of note_data objects with\na free_note_data() function.\n\nThis might not make too much sense on its own, but it makes the\nfuture refactoring of create_note() considerably cleaner.\n\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n builtin/notes.c | 38 +++++++++++++++++++++-----------------\n 1 file changed, 21 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 3cf22cb..1017472 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -95,9 +95,19 @@ static const char note_template[] =\n struct note_data {\n \tint given;\n \tint use_editor;\n+\tchar *edit_path;\n \tstruct strbuf buf;\n };\n \n+static void free_note_data(struct note_data *d)\n+{\n+\tif (d->edit_path) {\n+\t\tunlink_or_warn(d->edit_path);\n+\t\tfree(d->edit_path);\n+\t}\n+\tstrbuf_release(&d->buf);\n+}\n+\n static int list_each_note(const unsigned char *object_sha1,\n \t\tconst unsigned char *note_sha1, char *note_path,\n \t\tvoid *cb_data)\n@@ -153,17 +163,15 @@ static void create_note(const unsigned char *object, struct note_data *d,\n \t\t\tint append_only, const unsigned char *prev,\n \t\t\tunsigned char *result)\n {\n-\tchar *path = NULL;\n-\n \tif (d->use_editor || !d->given) {\n \t\tint fd;\n \t\tstruct strbuf buf = STRBUF_INIT;\n \n \t\t/* write the template message before editing: */\n-\t\tpath = git_pathdup(\"NOTES_EDITMSG\");\n-\t\tfd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);\n+\t\td->edit_path = git_pathdup(\"NOTES_EDITMSG\");\n+\t\tfd = open(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);\n \t\tif (fd < 0)\n-\t\t\tdie_errno(_(\"could not create file '%s'\"), path);\n+\t\t\tdie_errno(_(\"could not create file '%s'\"), d->edit_path);\n \n \t\tif (d->given)\n \t\t\twrite_or_die(fd, d->buf.buf, d->buf.len);\n@@ -181,7 +189,7 @@ static void create_note(const unsigned char *object, struct note_data *d,\n \t\tstrbuf_release(&buf);\n \t\tstrbuf_reset(&d->buf);\n \n-\t\tif (launch_editor(path, &d->buf, NULL)) {\n+\t\tif (launch_editor(d->edit_path, &d->buf, NULL)) {\n \t\t\tdie(_(\"Please supply the note contents using either -m or -F option\"));\n \t\t}\n \t\tstripspace(&d->buf, 1);\n@@ -208,17 +216,12 @@ static void create_note(const unsigned char *object, struct note_data *d,\n \t} else {\n \t\tif (write_sha1_file(d->buf.buf, d->buf.len, blob_type, result)) {\n \t\t\terror(_(\"unable to write note object\"));\n-\t\t\tif (path)\n+\t\t\tif (d->edit_path)\n \t\t\t\terror(_(\"The note contents have been left in %s\"),\n-\t\t\t\t      path);\n+\t\t\t\t      d->edit_path);\n \t\t\texit(128);\n \t\t}\n \t}\n-\n-\tif (path) {\n-\t\tunlink_or_warn(path);\n-\t\tfree(path);\n-\t}\n }\n \n static int parse_msg_arg(const struct option *opt, const char *arg, int unset)\n@@ -402,7 +405,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \tunsigned char object[20], new_note[20];\n \tchar logmsg[100];\n \tconst unsigned char *note;\n-\tstruct note_data d = { 0, 0, STRBUF_INIT };\n+\tstruct note_data d = { 0, 0, NULL, STRBUF_INIT };\n \tstruct option options[] = {\n \t\t{ OPTION_CALLBACK, 'm', \"message\", &d, N_(\"message\"),\n \t\t\tN_(\"note contents as a string\"), PARSE_OPT_NONEG,\n@@ -447,6 +450,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t\t\t * therefore still in argv[0-1].\n \t\t\t\t */\n \t\t\t\targv[0] = \"edit\";\n+\t\t\t\tfree_note_data(&d);\n \t\t\t\tfree_notes(t);\n \t\t\t\treturn append_edit(argc, argv, prefix);\n \t\t\t}\n@@ -460,6 +464,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tcreate_note(object, &d, 0, note, new_note);\n+\tfree_note_data(&d);\n \n \tif (is_null_sha1(new_note))\n \t\tremove_note(t, object);\n@@ -471,7 +476,6 @@ static int add(int argc, const char **argv, const char *prefix)\n \tcommit_notes(t, logmsg);\n out:\n \tfree_notes(t);\n-\tstrbuf_release(&d.buf);\n \treturn retval;\n }\n \n@@ -559,7 +563,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \tconst unsigned char *note;\n \tchar logmsg[100];\n \tconst char * const *usage;\n-\tstruct note_data d = { 0, 0, STRBUF_INIT };\n+\tstruct note_data d = { 0, 0, NULL, STRBUF_INIT };\n \tstruct option options[] = {\n \t\t{ OPTION_CALLBACK, 'm', \"message\", &d, N_(\"message\"),\n \t\t\tN_(\"note contents as a string\"), PARSE_OPT_NONEG,\n@@ -600,6 +604,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \tnote = get_note(t, object);\n \n \tcreate_note(object, &d, !edit, note, new_note);\n+\tfree_note_data(&d);\n \n \tif (is_null_sha1(new_note))\n \t\tremove_note(t, object);\n@@ -610,7 +615,6 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \t\t is_null_sha1(new_note) ? \"removed\" : \"added\", argv[0]);\n \tcommit_notes(t, logmsg);\n \tfree_notes(t);\n-\tstrbuf_release(&d.buf);\n \treturn 0;\n }\n \n-- \n2.1.1.392.g062cc5d\n"},{"id":"251600","messageId":"1415536255-19961-6-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 5/9] builtin/notes: Simplify early exit code in add()","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:51Z","receivedAt":"2014-11-09T12:30:51Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Signed-off-by: Johan Herland <johan@herland.net>\n---\n builtin/notes.c | 12 +++++-------\n 1 file changed, 5 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 1017472..f1480cf 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -399,7 +399,7 @@ static int append_edit(int argc, const char **argv, const char *prefix);\n \n static int add(int argc, const char **argv, const char *prefix)\n {\n-\tint retval = 0, force = 0;\n+\tint force = 0;\n \tconst char *object_ref;\n \tstruct notes_tree *t;\n \tunsigned char object[20], new_note[20];\n@@ -441,6 +441,8 @@ static int add(int argc, const char **argv, const char *prefix)\n \n \tif (note) {\n \t\tif (!force) {\n+\t\t\tfree_note_data(&d);\n+\t\t\tfree_notes(t);\n \t\t\tif (!d.given) {\n \t\t\t\t/*\n \t\t\t\t * Redirect to \"edit\" subcommand.\n@@ -450,14 +452,11 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t\t\t * therefore still in argv[0-1].\n \t\t\t\t */\n \t\t\t\targv[0] = \"edit\";\n-\t\t\t\tfree_note_data(&d);\n-\t\t\t\tfree_notes(t);\n \t\t\t\treturn append_edit(argc, argv, prefix);\n \t\t\t}\n-\t\t\tretval = error(_(\"Cannot add notes. Found existing notes \"\n+\t\t\treturn error(_(\"Cannot add notes. Found existing notes \"\n \t\t\t\t       \"for object %s. Use '-f' to overwrite \"\n \t\t\t\t       \"existing notes\"), sha1_to_hex(object));\n-\t\t\tgoto out;\n \t\t}\n \t\tfprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n \t\t\tsha1_to_hex(object));\n@@ -474,9 +473,8 @@ static int add(int argc, const char **argv, const char *prefix)\n \tsnprintf(logmsg, sizeof(logmsg), \"Notes %s by 'git notes %s'\",\n \t\t is_null_sha1(new_note) ? \"removed\" : \"added\", \"add\");\n \tcommit_notes(t, logmsg);\n-out:\n \tfree_notes(t);\n-\treturn retval;\n+\treturn 0;\n }\n \n static int copy(int argc, const char **argv, const char *prefix)\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251601","messageId":"1415536255-19961-7-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 6/9] builtin/notes: Split create_note() to clarify add vs. remove logic","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:52Z","receivedAt":"2014-11-09T12:30:52Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"create_note() has a non-trivial interface, and comprises three loosely\nrelated parts:\n\n 1. launching the editor with the note contents, if needed\n 2. appending to an existing note, if append_only was given\n 3. adding or removing the resulting note, based on whether it's non-empty\n\nSplit it along those lines to make the logic clearer: The first part\ngoes into a new function - prepare_note_data(), with a simpler interface.\nThe second part is moved into append_edit(), which is the only user of\nthis code. Finally, the add vs. remove decision is moved into the callers\n(add() and append_edit()), keeping the logic for writing the actual note\nobject in a separate function: write_note_data().\n\nSuggested-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n builtin/notes.c | 103 +++++++++++++++++++++++++++++---------------------------\n 1 file changed, 54 insertions(+), 49 deletions(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex f1480cf..7017434 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -159,9 +159,8 @@ static void write_commented_object(int fd, const unsigned char *object)\n \t\t    sha1_to_hex(object));\n }\n \n-static void create_note(const unsigned char *object, struct note_data *d,\n-\t\t\tint append_only, const unsigned char *prev,\n-\t\t\tunsigned char *result)\n+static void prepare_note_data(const unsigned char *object, struct note_data *d,\n+\t\tconst unsigned char *old_note)\n {\n \tif (d->use_editor || !d->given) {\n \t\tint fd;\n@@ -175,8 +174,8 @@ static void create_note(const unsigned char *object, struct note_data *d,\n \n \t\tif (d->given)\n \t\t\twrite_or_die(fd, d->buf.buf, d->buf.len);\n-\t\telse if (prev && !append_only)\n-\t\t\tcopy_obj_to_fd(fd, prev);\n+\t\telse if (old_note)\n+\t\t\tcopy_obj_to_fd(fd, old_note);\n \n \t\tstrbuf_addch(&buf, '\\n');\n \t\tstrbuf_add_commented_lines(&buf, note_template, strlen(note_template));\n@@ -194,33 +193,16 @@ static void create_note(const unsigned char *object, struct note_data *d,\n \t\t}\n \t\tstripspace(&d->buf, 1);\n \t}\n+}\n \n-\tif (prev && append_only) {\n-\t\t/* Append buf to previous note contents */\n-\t\tunsigned long size;\n-\t\tenum object_type type;\n-\t\tchar *prev_buf = read_sha1_file(prev, &type, &size);\n-\n-\t\tstrbuf_grow(&d->buf, size + 1);\n-\t\tif (d->buf.len && prev_buf && size)\n-\t\t\tstrbuf_insert(&d->buf, 0, \"\\n\", 1);\n-\t\tif (prev_buf && size)\n-\t\t\tstrbuf_insert(&d->buf, 0, prev_buf, size);\n-\t\tfree(prev_buf);\n-\t}\n-\n-\tif (!d->buf.len) {\n-\t\tfprintf(stderr, _(\"Removing note for object %s\\n\"),\n-\t\t\tsha1_to_hex(object));\n-\t\thashclr(result);\n-\t} else {\n-\t\tif (write_sha1_file(d->buf.buf, d->buf.len, blob_type, result)) {\n-\t\t\terror(_(\"unable to write note object\"));\n-\t\t\tif (d->edit_path)\n-\t\t\t\terror(_(\"The note contents have been left in %s\"),\n-\t\t\t\t      d->edit_path);\n-\t\t\texit(128);\n-\t\t}\n+static void write_note_data(struct note_data *d, unsigned char *sha1)\n+{\n+\tif (write_sha1_file(d->buf.buf, d->buf.len, blob_type, sha1)) {\n+\t\terror(_(\"unable to write note object\"));\n+\t\tif (d->edit_path)\n+\t\t\terror(_(\"The note contents have been left in %s\"),\n+\t\t\t\td->edit_path);\n+\t\texit(128);\n \t}\n }\n \n@@ -403,7 +385,6 @@ static int add(int argc, const char **argv, const char *prefix)\n \tconst char *object_ref;\n \tstruct notes_tree *t;\n \tunsigned char object[20], new_note[20];\n-\tchar logmsg[100];\n \tconst unsigned char *note;\n \tstruct note_data d = { 0, 0, NULL, STRBUF_INIT };\n \tstruct option options[] = {\n@@ -462,17 +443,20 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t\tsha1_to_hex(object));\n \t}\n \n-\tcreate_note(object, &d, 0, note, new_note);\n-\tfree_note_data(&d);\n-\n-\tif (is_null_sha1(new_note))\n+\tprepare_note_data(object, &d, note);\n+\tif (d.buf.len) {\n+\t\twrite_note_data(&d, new_note);\n+\t\tif (add_note(t, object, new_note, combine_notes_overwrite))\n+\t\t\tdie(\"BUG: combine_notes_overwrite failed\");\n+\t\tcommit_notes(t, \"Notes added by 'git notes add'\");\n+\t} else {\n+\t\tfprintf(stderr, _(\"Removing note for object %s\\n\"),\n+\t\t\tsha1_to_hex(object));\n \t\tremove_note(t, object);\n-\telse if (add_note(t, object, new_note, combine_notes_overwrite))\n-\t\tdie(\"BUG: combine_notes_overwrite failed\");\n+\t\tcommit_notes(t, \"Notes removed by 'git notes add'\");\n+\t}\n \n-\tsnprintf(logmsg, sizeof(logmsg), \"Notes %s by 'git notes %s'\",\n-\t\t is_null_sha1(new_note) ? \"removed\" : \"added\", \"add\");\n-\tcommit_notes(t, logmsg);\n+\tfree_note_data(&d);\n \tfree_notes(t);\n \treturn 0;\n }\n@@ -601,17 +585,38 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \tt = init_notes_check(argv[0]);\n \tnote = get_note(t, object);\n \n-\tcreate_note(object, &d, !edit, note, new_note);\n-\tfree_note_data(&d);\n+\tprepare_note_data(object, &d, edit ? note : NULL);\n \n-\tif (is_null_sha1(new_note))\n-\t\tremove_note(t, object);\n-\telse if (add_note(t, object, new_note, combine_notes_overwrite))\n-\t\tdie(\"BUG: combine_notes_overwrite failed\");\n+\tif (note && !edit) {\n+\t\t/* Append buf to previous note contents */\n+\t\tunsigned long size;\n+\t\tenum object_type type;\n+\t\tchar *prev_buf = read_sha1_file(note, &type, &size);\n+\n+\t\tstrbuf_grow(&d.buf, size + 1);\n+\t\tif (d.buf.len && prev_buf && size)\n+\t\t\tstrbuf_insert(&d.buf, 0, \"\\n\", 1);\n+\t\tif (prev_buf && size)\n+\t\t\tstrbuf_insert(&d.buf, 0, prev_buf, size);\n+\t\tfree(prev_buf);\n+\t}\n \n-\tsnprintf(logmsg, sizeof(logmsg), \"Notes %s by 'git notes %s'\",\n-\t\t is_null_sha1(new_note) ? \"removed\" : \"added\", argv[0]);\n+\tif (d.buf.len) {\n+\t\twrite_note_data(&d, new_note);\n+\t\tif (add_note(t, object, new_note, combine_notes_overwrite))\n+\t\t\tdie(\"BUG: combine_notes_overwrite failed\");\n+\t\tsnprintf(logmsg, sizeof(logmsg), \"Notes added by 'git notes %s'\",\n+\t\t\targv[0]);\n+\t} else {\n+\t\tfprintf(stderr, _(\"Removing note for object %s\\n\"),\n+\t\t\tsha1_to_hex(object));\n+\t\tremove_note(t, object);\n+\t\tsnprintf(logmsg, sizeof(logmsg), \"Notes removed by 'git notes %s'\",\n+\t\t\targv[0]);\n+\t}\n \tcommit_notes(t, logmsg);\n+\n+\tfree_note_data(&d);\n \tfree_notes(t);\n \treturn 0;\n }\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251599","messageId":"1415536255-19961-8-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 7/9] builtin/notes: Add --allow-empty, to allow storing empty notes","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:53Z","receivedAt":"2014-11-09T12:30:53Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Although the \"git notes\" man page advertises that we support binary-safe\nnotes addition (using the -C option), we currently do not support adding\nthe empty note (i.e. using the empty blob to annotate an object). Instead,\nan empty note is always treated as an intent to remove the note\naltogether.\n\nIntroduce the --allow-empty option to the add/append/edit subcommands,\nto explicitly allow an empty note to be stored into the notes tree.\n\nAlso update the documentation, and add test cases for the new option.\n\nReported-by: James H. Fisher <jhf@trifork.com>\nImproved-by: Kyle J. McKay <mackyle@gmail.com>\nImproved-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n Documentation/git-notes.txt | 12 ++++++++----\n builtin/notes.c             | 17 +++++++++++------\n t/t3301-notes.sh            | 10 +++++++++-\n 3 files changed, 28 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt\nindex 310f0a5..851518d 100644\n--- a/Documentation/git-notes.txt\n+++ b/Documentation/git-notes.txt\n@@ -9,10 +9,10 @@ SYNOPSIS\n --------\n [verse]\n 'git notes' [list [<object>]]\n-'git notes' add [-f] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]\n+'git notes' add [-f] [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]\n 'git notes' copy [-f] ( --stdin | <from-object> <to-object> )\n-'git notes' append [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]\n-'git notes' edit [<object>]\n+'git notes' append [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]\n+'git notes' edit [--allow-empty] [<object>]\n 'git notes' show [<object>]\n 'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref>\n 'git notes' merge --commit [-v | -q]\n@@ -155,6 +155,10 @@ OPTIONS\n \tLike '-C', but with '-c' the editor is invoked, so that\n \tthe user can further edit the note message.\n \n+--allow-empty::\n+\tAllow an empty note object to be stored. The default behavior is\n+\tto automatically remove empty notes.\n+\n --ref <ref>::\n \tManipulate the notes tree in <ref>.  This overrides\n \t'GIT_NOTES_REF' and the \"core.notesRef\" configuration.  The ref\n@@ -287,7 +291,7 @@ arbitrary files using 'git hash-object':\n ------------\n $ cc *.c\n $ blob=$(git hash-object -w a.out)\n-$ git notes --ref=built add -C \"$blob\" HEAD\n+$ git notes --ref=built add --allow-empty -C \"$blob\" HEAD\n ------------\n \n (You cannot simply use `git notes --ref=built add -F a.out HEAD`\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 7017434..4605210 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -22,10 +22,10 @@\n \n static const char * const git_notes_usage[] = {\n \tN_(\"git notes [--ref <notes_ref>] [list [<object>]]\"),\n-\tN_(\"git notes [--ref <notes_ref>] add [-f] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]\"),\n+\tN_(\"git notes [--ref <notes_ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]\"),\n \tN_(\"git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>\"),\n-\tN_(\"git notes [--ref <notes_ref>] append [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]\"),\n-\tN_(\"git notes [--ref <notes_ref>] edit [<object>]\"),\n+\tN_(\"git notes [--ref <notes_ref>] append [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]\"),\n+\tN_(\"git notes [--ref <notes_ref>] edit [--allow-empty] [<object>]\"),\n \tN_(\"git notes [--ref <notes_ref>] show [<object>]\"),\n \tN_(\"git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>\"),\n \tN_(\"git notes merge --commit [-v | -q]\"),\n@@ -381,7 +381,7 @@ static int append_edit(int argc, const char **argv, const char *prefix);\n \n static int add(int argc, const char **argv, const char *prefix)\n {\n-\tint force = 0;\n+\tint force = 0, allow_empty = 0;\n \tconst char *object_ref;\n \tstruct notes_tree *t;\n \tunsigned char object[20], new_note[20];\n@@ -400,6 +400,8 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t{ OPTION_CALLBACK, 'C', \"reuse-message\", &d, N_(\"object\"),\n \t\t\tN_(\"reuse specified note object\"), PARSE_OPT_NONEG,\n \t\t\tparse_reuse_arg},\n+\t\tOPT_BOOL(0, \"allow-empty\", &allow_empty,\n+\t\t\tN_(\"allow storing empty note\")),\n \t\tOPT__FORCE(&force, N_(\"replace existing notes\")),\n \t\tOPT_END()\n \t};\n@@ -444,7 +446,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tprepare_note_data(object, &d, note);\n-\tif (d.buf.len) {\n+\tif (d.buf.len || allow_empty) {\n \t\twrite_note_data(&d, new_note);\n \t\tif (add_note(t, object, new_note, combine_notes_overwrite))\n \t\t\tdie(\"BUG: combine_notes_overwrite failed\");\n@@ -539,6 +541,7 @@ out:\n \n static int append_edit(int argc, const char **argv, const char *prefix)\n {\n+\tint allow_empty = 0;\n \tconst char *object_ref;\n \tstruct notes_tree *t;\n \tunsigned char object[20], new_note[20];\n@@ -559,6 +562,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \t\t{ OPTION_CALLBACK, 'C', \"reuse-message\", &d, N_(\"object\"),\n \t\t\tN_(\"reuse specified note object\"), PARSE_OPT_NONEG,\n \t\t\tparse_reuse_arg},\n+\t\tOPT_BOOL(0, \"allow-empty\", &allow_empty,\n+\t\t\tN_(\"allow storing empty note\")),\n \t\tOPT_END()\n \t};\n \tint edit = !strcmp(argv[0], \"edit\");\n@@ -601,7 +606,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \t\tfree(prev_buf);\n \t}\n \n-\tif (d.buf.len) {\n+\tif (d.buf.len || allow_empty) {\n \t\twrite_note_data(&d, new_note);\n \t\tif (add_note(t, object, new_note, combine_notes_overwrite))\n \t\t\tdie(\"BUG: combine_notes_overwrite failed\");\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex f74b3fa..70ec5c3 100755\n--- a/t/t3301-notes.sh\n+++ b/t/t3301-notes.sh\n@@ -1242,7 +1242,8 @@ test_expect_success 'git notes get-ref (--ref)' '\n test_expect_success 'setup testing of empty notes' '\n \ttest_unconfig core.notesRef &&\n \ttest_commit 16th &&\n-\tempty_blob=$(git hash-object -w /dev/null)\n+\tempty_blob=$(git hash-object -w /dev/null) &&\n+\techo \"$empty_blob\" >expect_empty\n '\n \n while read cmd\n@@ -1252,6 +1253,13 @@ do\n \t\tMSG= git notes $cmd &&\n \t\ttest_must_fail git notes list HEAD\n \t\"\n+\n+\ttest_expect_success \"'git notes $cmd --allow-empty' stores empty note\" \"\n+\t\ttest_might_fail git notes remove HEAD &&\n+\t\tMSG= git notes $cmd --allow-empty &&\n+\t\tgit notes list HEAD >actual &&\n+\t\ttest_cmp expect_empty actual\n+\t\"\n done <<\\EOF\n add\n add -F /dev/null\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251603","messageId":"1415536255-19961-9-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 8/9] notes: Empty notes should be shown by 'git log'","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:54Z","receivedAt":"2014-11-09T12:30:54Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"If the user has gone through the trouble of explicitly adding an empty\nnote, then \"git log\" should not silently skip it (as if it didn't exist).\n\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n notes.c          |  3 +--\n t/t3301-notes.sh | 12 ++++++++++++\n 2 files changed, 13 insertions(+), 2 deletions(-)\n\ndiff --git a/notes.c b/notes.c\nindex 5fe691d..62bc6e1 100644\n--- a/notes.c\n+++ b/notes.c\n@@ -1218,8 +1218,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,\n \tif (!sha1)\n \t\treturn;\n \n-\tif (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||\n-\t\t\ttype != OBJ_BLOB) {\n+\tif (!(msg = read_sha1_file(sha1, &type, &msglen)) || type != OBJ_BLOB) {\n \t\tfree(msg);\n \t\treturn;\n \t}\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex 70ec5c3..416ed9e 100755\n--- a/t/t3301-notes.sh\n+++ b/t/t3301-notes.sh\n@@ -1274,4 +1274,16 @@ append -C \"$empty_blob\"\n edit\n EOF\n \n+test_expect_success 'empty notes are displayed by git log' '\n+\ttest_commit 17th &&\n+\tgit log -1 >expect &&\n+\tcat >>expect <<\\EOF &&\n+\n+Notes:\n+EOF\n+\tgit notes add -C \"$empty_blob\" --allow-empty &&\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251602","messageId":"1415536255-19961-10-git-send-email-johan@herland.net","threadId":"37914","inReplyTo":"1415536255-19961-1-git-send-email-johan@herland.net","subject":"[PATCHv4 9/9] t3301: Modernize","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-09T12:30:55Z","receivedAt":"2014-11-09T12:30:55Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Make this test script appear somewhat less old-fashioned:\n - Use test helper functions:\n    - write_script\n    - test_commit\n    - test_write_lines\n    - test_config\n    - test_unconfig\n    - test_path_is_missing\n - Remove whitespace between redirection operators and their targets.\n - Move preparation of \"except\" files into tests.\n - More consistent quoting, especially around commands that might\n   expand to nothing.\n - More visibility of important whitespace with ${indent}.\n - Combine pairs of tests that unnecessarily split setup and verification.\n\nImproved-by: Eric Sunshine <sunshine@sunshineco.com>\nImproved-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n t/t3301-notes.sh | 1148 +++++++++++++++++++++++++-----------------------------\n 1 file changed, 522 insertions(+), 626 deletions(-)\n\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex 416ed9e..cd756ec 100755\n--- a/t/t3301-notes.sh\n+++ b/t/t3301-notes.sh\n@@ -7,28 +7,22 @@ test_description='Test commit notes'\n \n . ./test-lib.sh\n \n-cat > fake_editor.sh << \\EOF\n-#!/bin/sh\n-echo \"$MSG\" > \"$1\"\n-echo \"$MSG\" >& 2\n+write_script fake_editor <<\\EOF\n+echo \"$MSG\" >\"$1\"\n+echo \"$MSG\" >&2\n EOF\n-chmod a+x fake_editor.sh\n-GIT_EDITOR=./fake_editor.sh\n+GIT_EDITOR=./fake_editor\n export GIT_EDITOR\n \n+indent=\"    \"\n+\n test_expect_success 'cannot annotate non-existing HEAD' '\n \ttest_must_fail env MSG=3 git notes add\n '\n \n-test_expect_success setup '\n-\t: > a1 &&\n-\tgit add a1 &&\n-\ttest_tick &&\n-\tgit commit -m 1st &&\n-\t: > a2 &&\n-\tgit add a2 &&\n-\ttest_tick &&\n-\tgit commit -m 2nd\n+test_expect_success 'setup' '\n+\ttest_commit 1st &&\n+\ttest_commit 2nd\n '\n \n test_expect_success 'need valid notes ref' '\n@@ -50,189 +44,163 @@ test_expect_success 'handle empty notes gracefully' '\n '\n \n test_expect_success 'show non-existent notes entry with %N' '\n-\tfor l in A B\n-\tdo\n-\t\techo \"$l\"\n-\tdone >expect &&\n-\tgit show -s --format='A%n%NB' >output &&\n+\ttest_write_lines A B >expect &&\n+\tgit show -s --format=\"A%n%NB\" >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'create notes' '\n-\tgit config core.notesRef refs/notes/commits &&\n \tMSG=b4 git notes add &&\n-\ttest ! -f .git/NOTES_EDITMSG &&\n-\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n-\ttest b4 = $(git notes show) &&\n+\ttest_path_is_missing .git/NOTES_EDITMSG &&\n+\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n+\ttest \"b4\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n '\n \n test_expect_success 'show notes entry with %N' '\n-\tfor l in A b4 B\n-\tdo\n-\t\techo \"$l\"\n-\tdone >expect &&\n-\tgit show -s --format='A%n%NB' >output &&\n+\ttest_write_lines A b4 B >expect &&\n+\tgit show -s --format=\"A%n%NB\" >output &&\n \ttest_cmp expect output\n '\n \n-cat >expect <<EOF\n-d423f8c refs/notes/commits@{0}: notes: Notes added by 'git notes add'\n-EOF\n-\n test_expect_success 'create reflog entry' '\n+\tcat <<-EOF >expect &&\n+\t\ta1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\"'\"'git notes add'\"'\"'\n+\tEOF\n \tgit reflog show refs/notes/commits >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'edit existing notes' '\n \tMSG=b3 git notes edit &&\n-\ttest ! -f .git/NOTES_EDITMSG &&\n-\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n-\ttest b3 = $(git notes show) &&\n+\ttest_path_is_missing .git/NOTES_EDITMSG &&\n+\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n+\ttest \"b3\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n '\n \n test_expect_success 'cannot \"git notes add -m\" where notes already exists' '\n \ttest_must_fail git notes add -m \"b2\" &&\n-\ttest ! -f .git/NOTES_EDITMSG &&\n-\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n-\ttest b3 = $(git notes show) &&\n+\ttest_path_is_missing .git/NOTES_EDITMSG &&\n+\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n+\ttest \"b3\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n '\n \n test_expect_success 'can overwrite existing note with \"git notes add -f -m\"' '\n \tgit notes add -f -m \"b1\" &&\n-\ttest ! -f .git/NOTES_EDITMSG &&\n-\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n-\ttest b1 = $(git notes show) &&\n+\ttest_path_is_missing .git/NOTES_EDITMSG &&\n+\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n+\ttest \"b1\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n '\n \n test_expect_success 'add w/no options on existing note morphs into edit' '\n \tMSG=b2 git notes add &&\n-\ttest ! -f .git/NOTES_EDITMSG &&\n-\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n-\ttest b2 = $(git notes show) &&\n+\ttest_path_is_missing .git/NOTES_EDITMSG &&\n+\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n+\ttest \"b2\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n '\n \n test_expect_success 'can overwrite existing note with \"git notes add -f\"' '\n \tMSG=b1 git notes add -f &&\n-\ttest ! -f .git/NOTES_EDITMSG &&\n-\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n-\ttest b1 = $(git notes show) &&\n+\ttest_path_is_missing .git/NOTES_EDITMSG &&\n+\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n+\ttest \"b1\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n '\n \n-cat > expect << EOF\n-commit 268048bfb8a1fb38e703baceb8ab235421bf80c5\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:14:13 2005 -0700\n+test_expect_success 'show notes' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:14:13 2005 -0700\n \n-    2nd\n+\t\t${indent}2nd\n \n-Notes:\n-    b1\n-EOF\n-\n-test_expect_success 'show notes' '\n+\t\tNotes:\n+\t\t${indent}b1\n+\tEOF\n \t! (git cat-file commit HEAD | grep b1) &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n-test_expect_success 'create multi-line notes (setup)' '\n-\t: > a3 &&\n-\tgit add a3 &&\n-\ttest_tick &&\n-\tgit commit -m 3rd &&\n-\tMSG=\"b3\n-c3c3c3c3\n-d3d3d3\" git notes add\n-'\n-\n-cat > expect-multiline << EOF\n-commit 1584215f1d29c65e99c6c6848626553fdd07fd75\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:15:13 2005 -0700\n-\n-    3rd\n-\n-Notes:\n-    b3\n-    c3c3c3c3\n-    d3d3d3\n-EOF\n-\n-printf \"\\n\" >> expect-multiline\n-cat expect >> expect-multiline\n-\n test_expect_success 'show multi-line notes' '\n-\tgit log -2 > output &&\n+\ttest_commit 3rd &&\n+\tMSG=\"b3${LF}c3c3c3c3${LF}d3d3d3\" git notes add &&\n+\tcat >expect-multiline <<-EOF &&\n+\t\tcommit d07d62e5208f22eb5695e7eb47667dc8b9860290\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:15:13 2005 -0700\n+\n+\t\t${indent}3rd\n+\n+\t\tNotes:\n+\t\t${indent}b3\n+\t\t${indent}c3c3c3c3\n+\t\t${indent}d3d3d3\n+\n+\tEOF\n+\tcat expect >>expect-multiline &&\n+\tgit log -2 >output &&\n \ttest_cmp expect-multiline output\n '\n-test_expect_success 'create -F notes (setup)' '\n-\t: > a4 &&\n-\tgit add a4 &&\n-\ttest_tick &&\n-\tgit commit -m 4th &&\n-\techo \"xyzzy\" > note5 &&\n-\tgit notes add -F note5\n-'\n-\n-cat > expect-F << EOF\n-commit 15023535574ded8b1a89052b32673f84cf9582b8\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:16:13 2005 -0700\n-\n-    4th\n-\n-Notes:\n-    xyzzy\n-EOF\n-\n-printf \"\\n\" >> expect-F\n-cat expect-multiline >> expect-F\n \n test_expect_success 'show -F notes' '\n-\tgit log -3 > output &&\n+\ttest_commit 4th &&\n+\techo \"xyzzy\" >note5 &&\n+\tgit notes add -F note5 &&\n+\tcat >expect-F <<-EOF &&\n+\t\tcommit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:16:13 2005 -0700\n+\n+\t\t${indent}4th\n+\n+\t\tNotes:\n+\t\t${indent}xyzzy\n+\n+\tEOF\n+\tcat expect-multiline >>expect-F &&\n+\tgit log -3 >output &&\n \ttest_cmp expect-F output\n '\n \n test_expect_success 'Re-adding -F notes without -f fails' '\n-\techo \"zyxxy\" > note5 &&\n+\techo \"zyxxy\" >note5 &&\n \ttest_must_fail git notes add -F note5 &&\n-\tgit log -3 > output &&\n+\tgit log -3 >output &&\n \ttest_cmp expect-F output\n '\n \n-cat >expect << EOF\n-commit 15023535574ded8b1a89052b32673f84cf9582b8\n-tree e070e3af51011e47b183c33adf9736736a525709\n-parent 1584215f1d29c65e99c6c6848626553fdd07fd75\n-author A U Thor <author@example.com> 1112912173 -0700\n-committer C O Mitter <committer@example.com> 1112912173 -0700\n-\n-    4th\n-EOF\n test_expect_success 'git log --pretty=raw does not show notes' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11\n+\t\ttree 05ac65288c4c4b3b709a020ae94b2ece2f2201ae\n+\t\tparent d07d62e5208f22eb5695e7eb47667dc8b9860290\n+\t\tauthor A U Thor <author@example.com> 1112912173 -0700\n+\t\tcommitter C O Mitter <committer@example.com> 1112912173 -0700\n+\n+\t\t${indent}4th\n+\tEOF\n \tgit log -1 --pretty=raw >output &&\n \ttest_cmp expect output\n '\n \n-cat >>expect <<EOF\n-\n-Notes:\n-    xyzzy\n-EOF\n test_expect_success 'git log --show-notes' '\n+\tcat >>expect <<-EOF &&\n+\n+\tNotes:\n+\t${indent}xyzzy\n+\tEOF\n \tgit log -1 --pretty=raw --show-notes >output &&\n \ttest_cmp expect output\n '\n@@ -304,128 +272,98 @@ test_expect_success 'git log --no-notes resets ref list' '\n \t! grep alternate output\n '\n \n-test_expect_success 'create -m notes (setup)' '\n-\t: > a5 &&\n-\tgit add a5 &&\n-\ttest_tick &&\n-\tgit commit -m 5th &&\n-\tgit notes add -m spam -m \"foo\n-bar\n-baz\"\n-'\n-\n-whitespace=\"    \"\n-cat > expect-m << EOF\n-commit bd1753200303d0a0344be813e504253b3d98e74d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:17:13 2005 -0700\n-\n-    5th\n-\n-Notes:\n-    spam\n-$whitespace\n-    foo\n-    bar\n-    baz\n-EOF\n-\n-printf \"\\n\" >> expect-m\n-cat expect-F >> expect-m\n-\n test_expect_success 'show -m notes' '\n-\tgit log -4 > output &&\n+\ttest_commit 5th &&\n+\tgit notes add -m spam -m \"foo${LF}bar${LF}baz\" &&\n+\tcat >expect-m <<-EOF &&\n+\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n+\n+\t\t${indent}5th\n+\n+\t\tNotes:\n+\t\t${indent}spam\n+\t\t${indent}\n+\t\t${indent}foo\n+\t\t${indent}bar\n+\t\t${indent}baz\n+\n+\tEOF\n+\tcat expect-F >>expect-m &&\n+\tgit log -4 >output &&\n \ttest_cmp expect-m output\n '\n \n-test_expect_success 'remove note with add -f -F /dev/null (setup)' '\n-\tgit notes add -f -F /dev/null\n-'\n-\n-cat > expect-rm-F << EOF\n-commit bd1753200303d0a0344be813e504253b3d98e74d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:17:13 2005 -0700\n-\n-    5th\n-EOF\n+test_expect_success 'remove note with add -f -F /dev/null' '\n+\tgit notes add -f -F /dev/null &&\n+\tcat >expect-rm-F <<-EOF &&\n+\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n \n-printf \"\\n\" >> expect-rm-F\n-cat expect-F >> expect-rm-F\n+\t\t${indent}5th\n \n-test_expect_success 'verify note removal with -F /dev/null' '\n-\tgit log -4 > output &&\n+\tEOF\n+\tcat expect-F >>expect-rm-F &&\n+\tgit log -4 >output &&\n \ttest_cmp expect-rm-F output &&\n \ttest_must_fail git notes show\n '\n \n-test_expect_success 'do not create empty note with -m \"\" (setup)' '\n-\tgit notes add -m \"\"\n-'\n-\n-test_expect_success 'verify non-creation of note with -m \"\"' '\n-\tgit log -4 > output &&\n+test_expect_success 'do not create empty note with -m \"\"' '\n+\tgit notes add -m \"\" &&\n+\tgit log -4 >output &&\n \ttest_cmp expect-rm-F output &&\n \ttest_must_fail git notes show\n '\n \n-cat > expect-combine_m_and_F << EOF\n-foo\n-\n-xyzzy\n+test_expect_success 'create note with combination of -m and -F' '\n+\tcat >expect-combine_m_and_F <<-EOF &&\n+\t\tfoo\n \n-bar\n+\t\txyzzy\n \n-zyxxy\n+\t\tbar\n \n-baz\n-EOF\n+\t\tzyxxy\n \n-test_expect_success 'create note with combination of -m and -F' '\n-\techo \"xyzzy\" > note_a &&\n-\techo \"zyxxy\" > note_b &&\n+\t\tbaz\n+\tEOF\n+\techo \"xyzzy\" >note_a &&\n+\techo \"zyxxy\" >note_b &&\n \tgit notes add -m \"foo\" -F note_a -m \"bar\" -F note_b -m \"baz\" &&\n-\tgit notes show > output &&\n+\tgit notes show >output &&\n \ttest_cmp expect-combine_m_and_F output\n '\n \n-test_expect_success 'remove note with \"git notes remove\" (setup)' '\n+test_expect_success 'remove note with \"git notes remove\"' '\n \tgit notes remove HEAD^ &&\n-\tgit notes remove\n-'\n+\tgit notes remove &&\n+\tcat >expect-rm-remove <<-EOF &&\n+\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n \n-cat > expect-rm-remove << EOF\n-commit bd1753200303d0a0344be813e504253b3d98e74d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:17:13 2005 -0700\n+\t\t${indent}5th\n \n-    5th\n-\n-commit 15023535574ded8b1a89052b32673f84cf9582b8\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:16:13 2005 -0700\n-\n-    4th\n-EOF\n+\t\tcommit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:16:13 2005 -0700\n \n-printf \"\\n\" >> expect-rm-remove\n-cat expect-multiline >> expect-rm-remove\n+\t\t${indent}4th\n \n-test_expect_success 'verify note removal with \"git notes remove\"' '\n-\tgit log -4 > output &&\n+\tEOF\n+\tcat expect-multiline >>expect-rm-remove &&\n+\tgit log -4 >output &&\n \ttest_cmp expect-rm-remove output &&\n \ttest_must_fail git notes show HEAD^\n '\n \n-cat > expect << EOF\n-c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd75\n-c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5\n-EOF\n-\n test_expect_success 'removing non-existing note should not create new commit' '\n-\tgit rev-parse --verify refs/notes/commits > before_commit &&\n+\tgit rev-parse --verify refs/notes/commits >before_commit &&\n \ttest_must_fail git notes remove HEAD^ &&\n-\tgit rev-parse --verify refs/notes/commits > after_commit &&\n+\tgit rev-parse --verify refs/notes/commits >after_commit &&\n \ttest_cmp before_commit after_commit\n '\n \n@@ -505,69 +443,67 @@ test_expect_success 'removing with --stdin --ignore-missing' '\n '\n \n test_expect_success 'list notes with \"git notes list\"' '\n-\tgit notes list > output &&\n+\tcat >expect <<-EOF &&\n+\t\tc9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n+\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290\n+\tEOF\n+\tgit notes list >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'list notes with \"git notes\"' '\n-\tgit notes > output &&\n+\tgit notes >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-c18dc024e14f08d18d14eea0d747ff692d66d6a3\n-EOF\n-\n test_expect_success 'list specific note with \"git notes list <object>\"' '\n-\tgit notes list HEAD^^ > output &&\n+\tcat >expect <<-EOF &&\n+\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3\n+\tEOF\n+\tgit notes list HEAD^^ >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-EOF\n-\n test_expect_success 'listing non-existing notes fails' '\n-\ttest_must_fail git notes list HEAD > output &&\n+\tcat >expect <<-EOF &&\n+\tEOF\n+\ttest_must_fail git notes list HEAD >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-Initial set of notes\n-\n-More notes appended with git notes append\n-EOF\n-\n test_expect_success 'append to existing note with \"git notes append\"' '\n+\tcat >expect <<-EOF &&\n+\t\tInitial set of notes\n+\n+\t\tMore notes appended with git notes append\n+\tEOF\n \tgit notes add -m \"Initial set of notes\" &&\n \tgit notes append -m \"More notes appended with git notes append\" &&\n-\tgit notes show > output &&\n+\tgit notes show >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect_list << EOF\n-c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd75\n-c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5\n-4b6ad22357cc8a1296720574b8d2fbc22fab0671 bd1753200303d0a0344be813e504253b3d98e74d\n-EOF\n-\n test_expect_success '\"git notes list\" does not expand to \"git notes list HEAD\"' '\n-\tgit notes list > output &&\n+\tcat >expect_list <<-EOF &&\n+\t\tc9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n+\t\t4b6ad22357cc8a1296720574b8d2fbc22fab0671 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n+\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290\n+\tEOF\n+\tgit notes list >output &&\n \ttest_cmp expect_list output\n '\n \n test_expect_success 'appending empty string does not change existing note' '\n \tgit notes append -m \"\" &&\n-\tgit notes show > output &&\n+\tgit notes show >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'git notes append == add when there is no existing note' '\n \tgit notes remove HEAD &&\n \ttest_must_fail git notes list HEAD &&\n-\tgit notes append -m \"Initial set of notes\n-\n-More notes appended with git notes append\" &&\n-\tgit notes show > output &&\n+\tgit notes append -m \"Initial set of notes${LF}${LF}More notes appended with git notes append\" &&\n+\tgit notes show >output &&\n \ttest_cmp expect output\n '\n \n@@ -579,229 +515,208 @@ test_expect_success 'appending empty string to non-existing note does not create\n '\n \n test_expect_success 'create other note on a different notes ref (setup)' '\n-\t: > a6 &&\n-\tgit add a6 &&\n-\ttest_tick &&\n-\tgit commit -m 6th &&\n-\tGIT_NOTES_REF=\"refs/notes/other\" git notes add -m \"other note\"\n-'\n-\n-cat > expect-other << EOF\n-commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:18:13 2005 -0700\n+\ttest_commit 6th &&\n+\tGIT_NOTES_REF=\"refs/notes/other\" git notes add -m \"other note\" &&\n+\tcat >expect-not-other <<-EOF &&\n+\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n \n-    6th\n+\t\t${indent}6th\n+\tEOF\n+\tcp expect-not-other expect-other &&\n+\tcat >>expect-other <<-EOF\n \n-Notes (other):\n-    other note\n-EOF\n-\n-cat > expect-not-other << EOF\n-commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:18:13 2005 -0700\n-\n-    6th\n-EOF\n+\t\tNotes (other):\n+\t\t${indent}other note\n+\tEOF\n+'\n \n test_expect_success 'Do not show note on other ref by default' '\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect-not-other output\n '\n \n test_expect_success 'Do show note when ref is given in GIT_NOTES_REF' '\n-\tGIT_NOTES_REF=\"refs/notes/other\" git log -1 > output &&\n+\tGIT_NOTES_REF=\"refs/notes/other\" git log -1 >output &&\n \ttest_cmp expect-other output\n '\n \n test_expect_success 'Do show note when ref is given in core.notesRef config' '\n-\tgit config core.notesRef \"refs/notes/other\" &&\n-\tgit log -1 > output &&\n+\ttest_config core.notesRef \"refs/notes/other\" &&\n+\tgit log -1 >output &&\n \ttest_cmp expect-other output\n '\n \n test_expect_success 'Do not show note when core.notesRef is overridden' '\n-\tGIT_NOTES_REF=\"refs/notes/wrong\" git log -1 > output &&\n+\ttest_config core.notesRef \"refs/notes/other\" &&\n+\tGIT_NOTES_REF=\"refs/notes/wrong\" git log -1 >output &&\n \ttest_cmp expect-not-other output\n '\n \n-cat > expect-both << EOF\n-commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:18:13 2005 -0700\n-\n-    6th\n+test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '\n+\tcat >expect-both <<-EOF &&\n+\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n \n-Notes:\n-    order test\n+\t\t${indent}6th\n \n-Notes (other):\n-    other note\n+\t\tNotes:\n+\t\t${indent}order test\n \n-commit bd1753200303d0a0344be813e504253b3d98e74d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:17:13 2005 -0700\n+\t\tNotes (other):\n+\t\t${indent}other note\n \n-    5th\n+\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n \n-Notes:\n-    replacement for deleted note\n-EOF\n+\t\t${indent}5th\n \n-test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '\n+\t\tNotes:\n+\t\t${indent}replacement for deleted note\n+\tEOF\n \tGIT_NOTES_REF=refs/notes/commits git notes add \\\n \t\t-m\"replacement for deleted note\" HEAD^ &&\n \tGIT_NOTES_REF=refs/notes/commits git notes add -m\"order test\" &&\n-\tgit config --unset core.notesRef &&\n-\tgit config notes.displayRef \"refs/notes/*\" &&\n-\tgit log -2 > output &&\n+\ttest_unconfig core.notesRef &&\n+\ttest_config notes.displayRef \"refs/notes/*\" &&\n+\tgit log -2 >output &&\n \ttest_cmp expect-both output\n '\n \n test_expect_success 'core.notesRef is implicitly in notes.displayRef' '\n-\tgit config core.notesRef refs/notes/commits &&\n-\tgit config notes.displayRef refs/notes/other &&\n-\tgit log -2 > output &&\n+\ttest_config core.notesRef refs/notes/commits &&\n+\ttest_config notes.displayRef refs/notes/other &&\n+\tgit log -2 >output &&\n \ttest_cmp expect-both output\n '\n \n test_expect_success 'notes.displayRef can be given more than once' '\n-\tgit config --unset core.notesRef &&\n-\tgit config notes.displayRef refs/notes/commits &&\n+\ttest_unconfig core.notesRef &&\n+\ttest_config notes.displayRef refs/notes/commits &&\n \tgit config --add notes.displayRef refs/notes/other &&\n-\tgit log -2 > output &&\n+\tgit log -2 >output &&\n \ttest_cmp expect-both output\n '\n \n-cat > expect-both-reversed << EOF\n-commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:18:13 2005 -0700\n-\n-    6th\n-\n-Notes (other):\n-    other note\n-\n-Notes:\n-    order test\n-EOF\n-\n test_expect_success 'notes.displayRef respects order' '\n-\tgit config core.notesRef refs/notes/other &&\n-\tgit config --unset-all notes.displayRef &&\n-\tgit config notes.displayRef refs/notes/commits &&\n-\tgit log -1 > output &&\n+\tcat >expect-both-reversed <<-EOF &&\n+\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n+\n+\t\t${indent}6th\n+\n+\t\tNotes (other):\n+\t\t${indent}other note\n+\n+\t\tNotes:\n+\t\t${indent}order test\n+\tEOF\n+\ttest_config core.notesRef refs/notes/other &&\n+\ttest_config notes.displayRef refs/notes/commits &&\n+\tgit log -1 >output &&\n \ttest_cmp expect-both-reversed output\n '\n \n test_expect_success 'GIT_NOTES_DISPLAY_REF works' '\n-\tgit config --unset-all core.notesRef &&\n-\tgit config --unset-all notes.displayRef &&\n \tGIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \\\n-\t\tgit log -2 > output &&\n+\t\tgit log -2 >output &&\n \ttest_cmp expect-both output\n '\n \n-cat > expect-none << EOF\n-commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:18:13 2005 -0700\n+test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '\n+\tcat >expect-none <<-EOF &&\n+\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n \n-    6th\n+\t\t${indent}6th\n \n-commit bd1753200303d0a0344be813e504253b3d98e74d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:17:13 2005 -0700\n+\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n \n-    5th\n-EOF\n-\n-test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '\n-\tgit config notes.displayRef \"refs/notes/*\" &&\n-\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 > output &&\n+\t\t${indent}5th\n+\tEOF\n+\ttest_config notes.displayRef \"refs/notes/*\" &&\n+\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 >output &&\n \ttest_cmp expect-none output\n '\n \n test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '\n-\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 > output &&\n+\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 >output &&\n \ttest_cmp expect-both output\n '\n \n-cat > expect-commits << EOF\n-commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:18:13 2005 -0700\n-\n-    6th\n+test_expect_success '--no-standard-notes' '\n+\tcat >expect-commits <<EOF\n+\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n \n-Notes:\n-    order test\n-EOF\n+\t\t${indent}6th\n \n-test_expect_success '--no-standard-notes' '\n-\tgit log --no-standard-notes --show-notes=commits -1 > output &&\n+\t\tNotes:\n+\t\t${indent}order test\n+\tEOF\n+\tgit log --no-standard-notes --show-notes=commits -1 >output &&\n \ttest_cmp expect-commits output\n '\n \n test_expect_success '--standard-notes' '\n+\ttest_config notes.displayRef \"refs/notes/*\" &&\n \tgit log --no-standard-notes --show-notes=commits \\\n-\t\t--standard-notes -2 > output &&\n+\t\t--standard-notes -2 >output &&\n \ttest_cmp expect-both output\n '\n \n test_expect_success '--show-notes=ref accumulates' '\n \tgit log --show-notes=other --show-notes=commits \\\n-\t\t --no-standard-notes -1 > output &&\n+\t\t --no-standard-notes -1 >output &&\n \ttest_cmp expect-both-reversed output\n '\n \n test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '\n-\tgit config core.notesRef refs/notes/other &&\n-\techo \"Note on a tree\" > expect &&\n+\ttest_config core.notesRef refs/notes/other &&\n+\techo \"Note on a tree\" >expect &&\n \tgit notes add -m \"Note on a tree\" HEAD: &&\n-\tgit notes show HEAD: > actual &&\n+\tgit notes show HEAD: >actual &&\n \ttest_cmp expect actual &&\n-\techo \"Note on a blob\" > expect &&\n+\techo \"Note on a blob\" >expect &&\n \tfilename=$(git ls-tree --name-only HEAD | head -n1) &&\n \tgit notes add -m \"Note on a blob\" HEAD:$filename &&\n-\tgit notes show HEAD:$filename > actual &&\n+\tgit notes show HEAD:$filename >actual &&\n \ttest_cmp expect actual &&\n-\techo \"Note on a tag\" > expect &&\n+\techo \"Note on a tag\" >expect &&\n \tgit tag -a -m \"This is an annotated tag\" foobar HEAD^ &&\n \tgit notes add -m \"Note on a tag\" foobar &&\n-\tgit notes show foobar > actual &&\n+\tgit notes show foobar >actual &&\n \ttest_cmp expect actual\n '\n \n-cat > expect << EOF\n-commit 2ede89468182a62d0bde2583c736089bcf7d7e92\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:19:13 2005 -0700\n+test_expect_success 'create note from other note with \"git notes add -C\"' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit fb01e0ca8c33b6cc0c6451dde747f97df567cb5c\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:19:13 2005 -0700\n \n-    7th\n+\t\t${indent}7th\n \n-Notes (other):\n-    other note\n-EOF\n-\n-test_expect_success 'create note from other note with \"git notes add -C\"' '\n-\t: > a7 &&\n-\tgit add a7 &&\n-\ttest_tick &&\n-\tgit commit -m 7th &&\n+\t\tNotes:\n+\t\t${indent}order test\n+\tEOF\n+\ttest_commit 7th &&\n \tgit notes add -C $(git notes list HEAD^) &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual &&\n \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD^)\"\n '\n \n test_expect_success 'create note from non-existing note with \"git notes add -C\" fails' '\n-\t: > a8 &&\n-\tgit add a8 &&\n-\ttest_tick &&\n-\tgit commit -m 8th &&\n+\ttest_commit 8th &&\n \ttest_must_fail git notes add -C deadbeef &&\n \ttest_must_fail git notes list HEAD\n '\n@@ -814,404 +729,385 @@ test_expect_success 'create note from non-blob with \"git notes add -C\" fails' '\n \ttest_must_fail git notes list HEAD\n '\n \n-cat > expect << EOF\n-commit 80d796defacd5db327b7a4e50099663902fbdc5c\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:20:13 2005 -0700\n+test_expect_success 'create note from blob with \"git notes add -C\" reuses blob id' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 9a4c31c7f722b5d517e92c64e932dd751e1413bf\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:20:13 2005 -0700\n \n-    8th\n+\t\t${indent}8th\n \n-Notes (other):\n-    This is a blob object\n-EOF\n-\n-test_expect_success 'create note from blob with \"git notes add -C\" reuses blob id' '\n+\t\tNotes:\n+\t\t${indent}This is a blob object\n+\tEOF\n \tblob=$(echo \"This is a blob object\" | git hash-object -w --stdin) &&\n \tgit notes add -C $blob &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual &&\n \ttest \"$(git notes list HEAD)\" = \"$blob\"\n '\n \n-cat > expect << EOF\n-commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:21:13 2005 -0700\n-\n-    9th\n+test_expect_success 'create note from other note with \"git notes add -c\"' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 2e0db4bc649e174d667a1cde19e725cf897a5bd2\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:21:13 2005 -0700\n \n-Notes (other):\n-    yet another note\n-EOF\n+\t\t${indent}9th\n \n-test_expect_success 'create note from other note with \"git notes add -c\"' '\n-\t: > a9 &&\n-\tgit add a9 &&\n-\ttest_tick &&\n-\tgit commit -m 9th &&\n+\t\tNotes:\n+\t\t${indent}yet another note\n+\tEOF\n+\ttest_commit 9th &&\n \tMSG=\"yet another note\" git notes add -c $(git notes list HEAD^^) &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual\n '\n \n test_expect_success 'create note from non-existing note with \"git notes add -c\" fails' '\n-\t: > a10 &&\n-\tgit add a10 &&\n-\ttest_tick &&\n-\tgit commit -m 10th &&\n+\ttest_commit 10th &&\n \ttest_must_fail env MSG=\"yet another note\" git notes add -c deadbeef &&\n \ttest_must_fail git notes list HEAD\n '\n \n-cat > expect << EOF\n-commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:21:13 2005 -0700\n-\n-    9th\n-\n-Notes (other):\n-    yet another note\n-$whitespace\n-    yet another note\n-EOF\n-\n test_expect_success 'append to note from other note with \"git notes append -C\"' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 2e0db4bc649e174d667a1cde19e725cf897a5bd2\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:21:13 2005 -0700\n+\n+\t\t${indent}9th\n+\n+\t\tNotes:\n+\t\t${indent}yet another note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\tEOF\n \tgit notes append -C $(git notes list HEAD^) HEAD^ &&\n-\tgit log -1 HEAD^ > actual &&\n+\tgit log -1 HEAD^ >actual &&\n \ttest_cmp expect actual\n '\n \n-cat > expect << EOF\n-commit ffed603236bfa3891c49644257a83598afe8ae5a\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:22:13 2005 -0700\n-\n-    10th\n+test_expect_success 'create note from other note with \"git notes append -c\"' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:22:13 2005 -0700\n \n-Notes (other):\n-    other note\n-EOF\n+\t\t${indent}10th\n \n-test_expect_success 'create note from other note with \"git notes append -c\"' '\n+\t\tNotes:\n+\t\t${indent}other note\n+\tEOF\n \tMSG=\"other note\" git notes append -c $(git notes list HEAD^) &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual\n '\n \n-cat > expect << EOF\n-commit ffed603236bfa3891c49644257a83598afe8ae5a\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:22:13 2005 -0700\n-\n-    10th\n-\n-Notes (other):\n-    other note\n-$whitespace\n-    yet another note\n-EOF\n-\n test_expect_success 'append to note from other note with \"git notes append -c\"' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:22:13 2005 -0700\n+\n+\t\t${indent}10th\n+\n+\t\tNotes:\n+\t\t${indent}other note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\tEOF\n \tMSG=\"yet another note\" git notes append -c $(git notes list HEAD) &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual\n '\n \n-cat > expect << EOF\n-commit 6352c5e33dbcab725fe0579be16aa2ba8eb369be\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:23:13 2005 -0700\n-\n-    11th\n-\n-Notes (other):\n-    other note\n-$whitespace\n-    yet another note\n-EOF\n-\n test_expect_success 'copy note with \"git notes copy\"' '\n-\t: > a11 &&\n-\tgit add a11 &&\n-\ttest_tick &&\n-\tgit commit -m 11th &&\n+\tcat >expect <<-EOF &&\n+\t\tcommit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:23:13 2005 -0700\n+\n+\t\t${indent}11th\n+\n+\t\tNotes:\n+\t\t${indent}other note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\tEOF\n+\ttest_commit 11th &&\n \tgit notes copy HEAD^ HEAD &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual &&\n \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD^)\"\n '\n \n test_expect_success 'prevent overwrite with \"git notes copy\"' '\n \ttest_must_fail git notes copy HEAD~2 HEAD &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual &&\n \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD^)\"\n '\n \n-cat > expect << EOF\n-commit 6352c5e33dbcab725fe0579be16aa2ba8eb369be\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:23:13 2005 -0700\n-\n-    11th\n-\n-Notes (other):\n-    yet another note\n-$whitespace\n-    yet another note\n-EOF\n-\n test_expect_success 'allow overwrite with \"git notes copy -f\"' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:23:13 2005 -0700\n+\n+\t\t${indent}11th\n+\n+\t\tNotes:\n+\t\t${indent}yet another note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\tEOF\n \tgit notes copy -f HEAD~2 HEAD &&\n-\tgit log -1 > actual &&\n+\tgit log -1 >actual &&\n \ttest_cmp expect actual &&\n \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD~2)\"\n '\n \n test_expect_success 'cannot copy note from object without notes' '\n-\t: > a12 &&\n-\tgit add a12 &&\n-\ttest_tick &&\n-\tgit commit -m 12th &&\n-\t: > a13 &&\n-\tgit add a13 &&\n-\ttest_tick &&\n-\tgit commit -m 13th &&\n+\ttest_commit 12th &&\n+\ttest_commit 13th &&\n \ttest_must_fail git notes copy HEAD^ HEAD\n '\n \n-cat > expect << EOF\n-commit e5d4fb5698d564ab8c73551538ecaf2b0c666185\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:25:13 2005 -0700\n-\n-    13th\n+test_expect_success 'git notes copy --stdin' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit e871aa61182b1d95d0a6fb75445d891722863b6b\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:25:13 2005 -0700\n \n-Notes (other):\n-    yet another note\n-$whitespace\n-    yet another note\n+\t\t${indent}13th\n \n-commit 7038787dfe22a14c3867ce816dbba39845359719\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:24:13 2005 -0700\n+\t\tNotes:\n+\t\t${indent}yet another note\n+\t\t${indent}\n+\t\t${indent}yet another note\n \n-    12th\n+\t\tcommit 65e263ded02ae4e8839bc151095113737579dc12\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:24:13 2005 -0700\n \n-Notes (other):\n-    other note\n-$whitespace\n-    yet another note\n-EOF\n+\t\t${indent}12th\n \n-test_expect_success 'git notes copy --stdin' '\n+\t\tNotes:\n+\t\t${indent}other note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\tEOF\n \t(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \\\n \techo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |\n \tgit notes copy --stdin &&\n-\tgit log -2 > output &&\n+\tgit log -2 >output &&\n \ttest_cmp expect output &&\n \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD~2)\" &&\n \ttest \"$(git notes list HEAD^)\" = \"$(git notes list HEAD~3)\"\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n+test_expect_success 'git notes copy --for-rewrite (unconfigured)' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n \n-commit be28d8b4d9951ad940d229ee3b0b9ee3b1ec273d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:26:13 2005 -0700\n+\t\t${indent}15th\n \n-    14th\n-EOF\n+\t\tcommit 07c85d77059393ed0154b8c96906547a59dfcddd\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:26:13 2005 -0700\n \n-test_expect_success 'git notes copy --for-rewrite (unconfigured)' '\n+\t\t${indent}14th\n+\tEOF\n \ttest_commit 14th &&\n \ttest_commit 15th &&\n \t(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \\\n \techo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -2 > output &&\n+\tgit log -2 >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n-\n-Notes (other):\n-    yet another note\n-$whitespace\n-    yet another note\n-\n-commit be28d8b4d9951ad940d229ee3b0b9ee3b1ec273d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:26:13 2005 -0700\n-\n-    14th\n-\n-Notes (other):\n-    other note\n-$whitespace\n-    yet another note\n-EOF\n-\n test_expect_success 'git notes copy --for-rewrite (enabled)' '\n-\tgit config notes.rewriteMode overwrite &&\n-\tgit config notes.rewriteRef \"refs/notes/*\" &&\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n+\n+\t\t${indent}15th\n+\n+\t\tNotes:\n+\t\t${indent}yet another note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\n+\t\tcommit 07c85d77059393ed0154b8c96906547a59dfcddd\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:26:13 2005 -0700\n+\n+\t\t${indent}14th\n+\n+\t\tNotes:\n+\t\t${indent}other note\n+\t\t${indent}\n+\t\t${indent}yet another note\n+\tEOF\n+\ttest_config notes.rewriteMode overwrite &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \t(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \\\n \techo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -2 > output &&\n+\tgit log -2 >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'git notes copy --for-rewrite (disabled)' '\n-\tgit config notes.rewrite.bar false &&\n+\ttest_config notes.rewrite.bar false &&\n \techo $(git rev-parse HEAD~3) $(git rev-parse HEAD) |\n \tgit notes copy --for-rewrite=bar &&\n-\tgit log -2 > output &&\n+\tgit log -2 >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n+test_expect_success 'git notes copy --for-rewrite (overwrite)' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n \n-Notes (other):\n-    a fresh note\n-EOF\n+\t\t${indent}15th\n \n-test_expect_success 'git notes copy --for-rewrite (overwrite)' '\n+\t\tNotes:\n+\t\t${indent}a fresh note\n+\tEOF\n \tgit notes add -f -m\"a fresh note\" HEAD^ &&\n+\ttest_config notes.rewriteMode overwrite &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'git notes copy --for-rewrite (ignore)' '\n-\tgit config notes.rewriteMode ignore &&\n+\ttest_config notes.rewriteMode ignore &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n-\n-Notes (other):\n-    a fresh note\n-$whitespace\n-    another fresh note\n-EOF\n-\n test_expect_success 'git notes copy --for-rewrite (append)' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n+\n+\t\t${indent}15th\n+\n+\t\tNotes:\n+\t\t${indent}a fresh note\n+\t\t${indent}\n+\t\t${indent}another fresh note\n+\tEOF\n \tgit notes add -f -m\"another fresh note\" HEAD^ &&\n-\tgit config notes.rewriteMode concatenate &&\n+\ttest_config notes.rewriteMode concatenate &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n-\n-Notes (other):\n-    a fresh note\n-$whitespace\n-    another fresh note\n-$whitespace\n-    append 1\n-$whitespace\n-    append 2\n-EOF\n-\n test_expect_success 'git notes copy --for-rewrite (append two to one)' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n+\n+\t\t${indent}15th\n+\n+\t\tNotes:\n+\t\t${indent}a fresh note\n+\t\t${indent}\n+\t\t${indent}another fresh note\n+\t\t${indent}\n+\t\t${indent}append 1\n+\t\t${indent}\n+\t\t${indent}append 2\n+\tEOF\n \tgit notes add -f -m\"append 1\" HEAD^ &&\n \tgit notes add -f -m\"append 2\" HEAD^^ &&\n+\ttest_config notes.rewriteMode concatenate &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \t(echo $(git rev-parse HEAD^) $(git rev-parse HEAD);\n \techo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'git notes copy --for-rewrite (append empty)' '\n \tgit notes remove HEAD^ &&\n+\ttest_config notes.rewriteMode concatenate &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tgit notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n-\n-Notes (other):\n-    replacement note 1\n-EOF\n-\n test_expect_success 'GIT_NOTES_REWRITE_MODE works' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n+\n+\t\t${indent}15th\n+\n+\t\tNotes:\n+\t\t${indent}replacement note 1\n+\tEOF\n+\ttest_config notes.rewriteMode concatenate &&\n+\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n \tgit notes add -f -m\"replacement note 1\" HEAD^ &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tGIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n-cat > expect << EOF\n-commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:27:13 2005 -0700\n-\n-    15th\n+test_expect_success 'GIT_NOTES_REWRITE_REF works' '\n+\tcat >expect <<-EOF &&\n+\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n+\t\tAuthor: A U Thor <author@example.com>\n+\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n \n-Notes (other):\n-    replacement note 2\n-EOF\n+\t\t${indent}15th\n \n-test_expect_success 'GIT_NOTES_REWRITE_REF works' '\n-\tgit config notes.rewriteMode overwrite &&\n+\t\tNotes:\n+\t\t${indent}replacement note 2\n+\tEOF\n \tgit notes add -f -m\"replacement note 2\" HEAD^ &&\n-\tgit config --unset-all notes.rewriteRef &&\n+\ttest_config notes.rewriteMode overwrite &&\n+\ttest_unconfig notes.rewriteRef &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tGIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \\\n \t\tgit notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '\n-\tgit config notes.rewriteRef refs/notes/other &&\n \tgit notes add -f -m\"replacement note 3\" HEAD^ &&\n+\ttest_config notes.rewriteMode overwrite &&\n+\ttest_config notes.rewriteRef refs/notes/other &&\n \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n \tGIT_NOTES_REWRITE_REF= git notes copy --for-rewrite=foo &&\n-\tgit log -1 > output &&\n+\tgit log -1 >output &&\n \ttest_cmp expect output\n '\n \n@@ -1221,13 +1117,13 @@ test_expect_success 'git notes copy diagnoses too many or too few parameters' '\n '\n \n test_expect_success 'git notes get-ref (no overrides)' '\n-\tgit config --unset core.notesRef &&\n+\ttest_unconfig core.notesRef &&\n \tsane_unset GIT_NOTES_REF &&\n \ttest \"$(git notes get-ref)\" = \"refs/notes/commits\"\n '\n \n test_expect_success 'git notes get-ref (core.notesRef)' '\n-\tgit config core.notesRef refs/notes/foo &&\n+\ttest_config core.notesRef refs/notes/foo &&\n \ttest \"$(git notes get-ref)\" = \"refs/notes/foo\"\n '\n \n@@ -1277,10 +1173,10 @@ EOF\n test_expect_success 'empty notes are displayed by git log' '\n \ttest_commit 17th &&\n \tgit log -1 >expect &&\n-\tcat >>expect <<\\EOF &&\n+\tcat >>expect <<-EOF &&\n \n-Notes:\n-EOF\n+\t\tNotes:\n+\tEOF\n \tgit notes add -C \"$empty_blob\" --allow-empty &&\n \tgit log -1 >actual &&\n \ttest_cmp expect actual\n-- \n2.1.1.392.g062cc5d\n"},{"id":"251690","messageId":"xmqqmw7y94jm.fsf@gitster.dls.corp.google.com","threadId":"37914","inReplyTo":"1415536255-19961-6-git-send-email-johan@herland.net","subject":"Re: [PATCHv4 5/9] builtin/notes: Simplify early exit code in add()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-10T20:36:13Z","receivedAt":"2014-11-10T20:36:13Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johan Herland <johan@herland.net> writes:\n\n> Signed-off-by: Johan Herland <johan@herland.net>\n> ---\n>  builtin/notes.c | 12 +++++-------\n>  1 file changed, 5 insertions(+), 7 deletions(-)\n>\n> diff --git a/builtin/notes.c b/builtin/notes.c\n> index 1017472..f1480cf 100644\n> --- a/builtin/notes.c\n> +++ b/builtin/notes.c\n> @@ -399,7 +399,7 @@ static int append_edit(int argc, const char **argv, const char *prefix);\n>  \n>  static int add(int argc, const char **argv, const char *prefix)\n>  {\n> -\tint retval = 0, force = 0;\n> +\tint force = 0;\n>  \tconst char *object_ref;\n>  \tstruct notes_tree *t;\n>  \tunsigned char object[20], new_note[20];\n> @@ -441,6 +441,8 @@ static int add(int argc, const char **argv, const char *prefix)\n>  \n>  \tif (note) {\n>  \t\tif (!force) {\n> +\t\t\tfree_note_data(&d);\n> +\t\t\tfree_notes(t);\n>  \t\t\tif (!d.given) {\n\nIt looks a bit strange to refer to d.given after calling a function\nthat sounds as if it is meant to clear what is recorded in and to\ninvalidate &d; yes, I can read the implementation to see that\nd.given keeps its stale value, but that is something other people\nmay want to \"clean up\" later and this reference to d.given will get\nin the way when that happens.\n\nAt this point of the code, it makes sense to free t in preparation\nto either switching to append codepath or erroring out, but does &d\nhave anything in it already to necessitate its freeing?\n\n>  \t\t\t\t/*\n>  \t\t\t\t * Redirect to \"edit\" subcommand.\n> @@ -450,14 +452,11 @@ static int add(int argc, const char **argv, const char *prefix)\n>  \t\t\t\t * therefore still in argv[0-1].\n>  \t\t\t\t */\n>  \t\t\t\targv[0] = \"edit\";\n> -\t\t\t\tfree_note_data(&d);\n> -\t\t\t\tfree_notes(t);\n>  \t\t\t\treturn append_edit(argc, argv, prefix);\n>  \t\t\t}\n> -\t\t\tretval = error(_(\"Cannot add notes. Found existing notes \"\n> +\t\t\treturn error(_(\"Cannot add notes. Found existing notes \"\n>  \t\t\t\t       \"for object %s. Use '-f' to overwrite \"\n>  \t\t\t\t       \"existing notes\"), sha1_to_hex(object));\n> -\t\t\tgoto out;\n>  \t\t}\n>  \t\tfprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n>  \t\t\tsha1_to_hex(object));\n> @@ -474,9 +473,8 @@ static int add(int argc, const char **argv, const char *prefix)\n>  \tsnprintf(logmsg, sizeof(logmsg), \"Notes %s by 'git notes %s'\",\n>  \t\t is_null_sha1(new_note) ? \"removed\" : \"added\", \"add\");\n>  \tcommit_notes(t, logmsg);\n> -out:\n>  \tfree_notes(t);\n> -\treturn retval;\n> +\treturn 0;\n>  }\n>  \n>  static int copy(int argc, const char **argv, const char *prefix)\n"},{"id":"251691","messageId":"xmqqioim9498.fsf@gitster.dls.corp.google.com","threadId":"37914","inReplyTo":"1415536255-19961-10-git-send-email-johan@herland.net","subject":"Re: [PATCHv4 9/9] t3301: Modernize","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-10T20:42:27Z","receivedAt":"2014-11-10T20:42:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johan Herland <johan@herland.net> writes:\n\n> Make this test script appear somewhat less old-fashioned:\n>  - Use test helper functions:\n>     - write_script\n>     - test_commit\n>     - test_write_lines\n>     - test_config\n>     - test_unconfig\n>     - test_path_is_missing\n>  - Remove whitespace between redirection operators and their targets.\n>  - Move preparation of \"except\" files into tests.\n\nexpect, I think (no need to resend; I've fixed it up locally).\n\n>  - More consistent quoting, especially around commands that might\n>    expand to nothing.\n>  - More visibility of important whitespace with ${indent}.\n>  - Combine pairs of tests that unnecessarily split setup and verification.\n>\n> Improved-by: Eric Sunshine <sunshine@sunshineco.com>\n> Improved-by: Junio C Hamano <gitster@pobox.com>\n> Signed-off-by: Johan Herland <johan@herland.net>\n> ---\n>  t/t3301-notes.sh | 1148 +++++++++++++++++++++++++-----------------------------\n>  1 file changed, 522 insertions(+), 626 deletions(-)\n>\n> diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\n> index 416ed9e..cd756ec 100755\n> --- a/t/t3301-notes.sh\n> +++ b/t/t3301-notes.sh\n> @@ -7,28 +7,22 @@ test_description='Test commit notes'\n>  \n>  . ./test-lib.sh\n>  \n> -cat > fake_editor.sh << \\EOF\n> -#!/bin/sh\n> -echo \"$MSG\" > \"$1\"\n> -echo \"$MSG\" >& 2\n> +write_script fake_editor <<\\EOF\n> +echo \"$MSG\" >\"$1\"\n> +echo \"$MSG\" >&2\n>  EOF\n> -chmod a+x fake_editor.sh\n> -GIT_EDITOR=./fake_editor.sh\n> +GIT_EDITOR=./fake_editor\n>  export GIT_EDITOR\n>  \n> +indent=\"    \"\n> +\n>  test_expect_success 'cannot annotate non-existing HEAD' '\n>  \ttest_must_fail env MSG=3 git notes add\n>  '\n>  \n> -test_expect_success setup '\n> -\t: > a1 &&\n> -\tgit add a1 &&\n> -\ttest_tick &&\n> -\tgit commit -m 1st &&\n> -\t: > a2 &&\n> -\tgit add a2 &&\n> -\ttest_tick &&\n> -\tgit commit -m 2nd\n> +test_expect_success 'setup' '\n> +\ttest_commit 1st &&\n> +\ttest_commit 2nd\n>  '\n>  \n>  test_expect_success 'need valid notes ref' '\n> @@ -50,189 +44,163 @@ test_expect_success 'handle empty notes gracefully' '\n>  '\n>  \n>  test_expect_success 'show non-existent notes entry with %N' '\n> -\tfor l in A B\n> -\tdo\n> -\t\techo \"$l\"\n> -\tdone >expect &&\n> -\tgit show -s --format='A%n%NB' >output &&\n> +\ttest_write_lines A B >expect &&\n> +\tgit show -s --format=\"A%n%NB\" >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'create notes' '\n> -\tgit config core.notesRef refs/notes/commits &&\n>  \tMSG=b4 git notes add &&\n> -\ttest ! -f .git/NOTES_EDITMSG &&\n> -\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -\ttest b4 = $(git notes show) &&\n> +\ttest_path_is_missing .git/NOTES_EDITMSG &&\n> +\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n> +\ttest \"b4\" = \"$(git notes show)\" &&\n>  \tgit show HEAD^ &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n>  test_expect_success 'show notes entry with %N' '\n> -\tfor l in A b4 B\n> -\tdo\n> -\t\techo \"$l\"\n> -\tdone >expect &&\n> -\tgit show -s --format='A%n%NB' >output &&\n> +\ttest_write_lines A b4 B >expect &&\n> +\tgit show -s --format=\"A%n%NB\" >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat >expect <<EOF\n> -d423f8c refs/notes/commits@{0}: notes: Notes added by 'git notes add'\n> -EOF\n> -\n>  test_expect_success 'create reflog entry' '\n> +\tcat <<-EOF >expect &&\n> +\t\ta1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\"'\"'git notes add'\"'\"'\n> +\tEOF\n>  \tgit reflog show refs/notes/commits >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'edit existing notes' '\n>  \tMSG=b3 git notes edit &&\n> -\ttest ! -f .git/NOTES_EDITMSG &&\n> -\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -\ttest b3 = $(git notes show) &&\n> +\ttest_path_is_missing .git/NOTES_EDITMSG &&\n> +\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n> +\ttest \"b3\" = \"$(git notes show)\" &&\n>  \tgit show HEAD^ &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n>  test_expect_success 'cannot \"git notes add -m\" where notes already exists' '\n>  \ttest_must_fail git notes add -m \"b2\" &&\n> -\ttest ! -f .git/NOTES_EDITMSG &&\n> -\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -\ttest b3 = $(git notes show) &&\n> +\ttest_path_is_missing .git/NOTES_EDITMSG &&\n> +\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n> +\ttest \"b3\" = \"$(git notes show)\" &&\n>  \tgit show HEAD^ &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n>  test_expect_success 'can overwrite existing note with \"git notes add -f -m\"' '\n>  \tgit notes add -f -m \"b1\" &&\n> -\ttest ! -f .git/NOTES_EDITMSG &&\n> -\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -\ttest b1 = $(git notes show) &&\n> +\ttest_path_is_missing .git/NOTES_EDITMSG &&\n> +\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n> +\ttest \"b1\" = \"$(git notes show)\" &&\n>  \tgit show HEAD^ &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n>  test_expect_success 'add w/no options on existing note morphs into edit' '\n>  \tMSG=b2 git notes add &&\n> -\ttest ! -f .git/NOTES_EDITMSG &&\n> -\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -\ttest b2 = $(git notes show) &&\n> +\ttest_path_is_missing .git/NOTES_EDITMSG &&\n> +\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n> +\ttest \"b2\" = \"$(git notes show)\" &&\n>  \tgit show HEAD^ &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n>  test_expect_success 'can overwrite existing note with \"git notes add -f\"' '\n>  \tMSG=b1 git notes add -f &&\n> -\ttest ! -f .git/NOTES_EDITMSG &&\n> -\ttest 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -\ttest b1 = $(git notes show) &&\n> +\ttest_path_is_missing .git/NOTES_EDITMSG &&\n> +\ttest \"1\" = \"$(git ls-tree refs/notes/commits | wc -l)\" &&\n> +\ttest \"b1\" = \"$(git notes show)\" &&\n>  \tgit show HEAD^ &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n> -cat > expect << EOF\n> -commit 268048bfb8a1fb38e703baceb8ab235421bf80c5\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:14:13 2005 -0700\n> +test_expect_success 'show notes' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:14:13 2005 -0700\n>  \n> -    2nd\n> +\t\t${indent}2nd\n>  \n> -Notes:\n> -    b1\n> -EOF\n> -\n> -test_expect_success 'show notes' '\n> +\t\tNotes:\n> +\t\t${indent}b1\n> +\tEOF\n>  \t! (git cat-file commit HEAD | grep b1) &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -test_expect_success 'create multi-line notes (setup)' '\n> -\t: > a3 &&\n> -\tgit add a3 &&\n> -\ttest_tick &&\n> -\tgit commit -m 3rd &&\n> -\tMSG=\"b3\n> -c3c3c3c3\n> -d3d3d3\" git notes add\n> -'\n> -\n> -cat > expect-multiline << EOF\n> -commit 1584215f1d29c65e99c6c6848626553fdd07fd75\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:15:13 2005 -0700\n> -\n> -    3rd\n> -\n> -Notes:\n> -    b3\n> -    c3c3c3c3\n> -    d3d3d3\n> -EOF\n> -\n> -printf \"\\n\" >> expect-multiline\n> -cat expect >> expect-multiline\n> -\n>  test_expect_success 'show multi-line notes' '\n> -\tgit log -2 > output &&\n> +\ttest_commit 3rd &&\n> +\tMSG=\"b3${LF}c3c3c3c3${LF}d3d3d3\" git notes add &&\n> +\tcat >expect-multiline <<-EOF &&\n> +\t\tcommit d07d62e5208f22eb5695e7eb47667dc8b9860290\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:15:13 2005 -0700\n> +\n> +\t\t${indent}3rd\n> +\n> +\t\tNotes:\n> +\t\t${indent}b3\n> +\t\t${indent}c3c3c3c3\n> +\t\t${indent}d3d3d3\n> +\n> +\tEOF\n> +\tcat expect >>expect-multiline &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect-multiline output\n>  '\n> -test_expect_success 'create -F notes (setup)' '\n> -\t: > a4 &&\n> -\tgit add a4 &&\n> -\ttest_tick &&\n> -\tgit commit -m 4th &&\n> -\techo \"xyzzy\" > note5 &&\n> -\tgit notes add -F note5\n> -'\n> -\n> -cat > expect-F << EOF\n> -commit 15023535574ded8b1a89052b32673f84cf9582b8\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:16:13 2005 -0700\n> -\n> -    4th\n> -\n> -Notes:\n> -    xyzzy\n> -EOF\n> -\n> -printf \"\\n\" >> expect-F\n> -cat expect-multiline >> expect-F\n>  \n>  test_expect_success 'show -F notes' '\n> -\tgit log -3 > output &&\n> +\ttest_commit 4th &&\n> +\techo \"xyzzy\" >note5 &&\n> +\tgit notes add -F note5 &&\n> +\tcat >expect-F <<-EOF &&\n> +\t\tcommit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:16:13 2005 -0700\n> +\n> +\t\t${indent}4th\n> +\n> +\t\tNotes:\n> +\t\t${indent}xyzzy\n> +\n> +\tEOF\n> +\tcat expect-multiline >>expect-F &&\n> +\tgit log -3 >output &&\n>  \ttest_cmp expect-F output\n>  '\n>  \n>  test_expect_success 'Re-adding -F notes without -f fails' '\n> -\techo \"zyxxy\" > note5 &&\n> +\techo \"zyxxy\" >note5 &&\n>  \ttest_must_fail git notes add -F note5 &&\n> -\tgit log -3 > output &&\n> +\tgit log -3 >output &&\n>  \ttest_cmp expect-F output\n>  '\n>  \n> -cat >expect << EOF\n> -commit 15023535574ded8b1a89052b32673f84cf9582b8\n> -tree e070e3af51011e47b183c33adf9736736a525709\n> -parent 1584215f1d29c65e99c6c6848626553fdd07fd75\n> -author A U Thor <author@example.com> 1112912173 -0700\n> -committer C O Mitter <committer@example.com> 1112912173 -0700\n> -\n> -    4th\n> -EOF\n>  test_expect_success 'git log --pretty=raw does not show notes' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11\n> +\t\ttree 05ac65288c4c4b3b709a020ae94b2ece2f2201ae\n> +\t\tparent d07d62e5208f22eb5695e7eb47667dc8b9860290\n> +\t\tauthor A U Thor <author@example.com> 1112912173 -0700\n> +\t\tcommitter C O Mitter <committer@example.com> 1112912173 -0700\n> +\n> +\t\t${indent}4th\n> +\tEOF\n>  \tgit log -1 --pretty=raw >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat >>expect <<EOF\n> -\n> -Notes:\n> -    xyzzy\n> -EOF\n>  test_expect_success 'git log --show-notes' '\n> +\tcat >>expect <<-EOF &&\n> +\n> +\tNotes:\n> +\t${indent}xyzzy\n> +\tEOF\n>  \tgit log -1 --pretty=raw --show-notes >output &&\n>  \ttest_cmp expect output\n>  '\n> @@ -304,128 +272,98 @@ test_expect_success 'git log --no-notes resets ref list' '\n>  \t! grep alternate output\n>  '\n>  \n> -test_expect_success 'create -m notes (setup)' '\n> -\t: > a5 &&\n> -\tgit add a5 &&\n> -\ttest_tick &&\n> -\tgit commit -m 5th &&\n> -\tgit notes add -m spam -m \"foo\n> -bar\n> -baz\"\n> -'\n> -\n> -whitespace=\"    \"\n> -cat > expect-m << EOF\n> -commit bd1753200303d0a0344be813e504253b3d98e74d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:17:13 2005 -0700\n> -\n> -    5th\n> -\n> -Notes:\n> -    spam\n> -$whitespace\n> -    foo\n> -    bar\n> -    baz\n> -EOF\n> -\n> -printf \"\\n\" >> expect-m\n> -cat expect-F >> expect-m\n> -\n>  test_expect_success 'show -m notes' '\n> -\tgit log -4 > output &&\n> +\ttest_commit 5th &&\n> +\tgit notes add -m spam -m \"foo${LF}bar${LF}baz\" &&\n> +\tcat >expect-m <<-EOF &&\n> +\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n> +\n> +\t\t${indent}5th\n> +\n> +\t\tNotes:\n> +\t\t${indent}spam\n> +\t\t${indent}\n> +\t\t${indent}foo\n> +\t\t${indent}bar\n> +\t\t${indent}baz\n> +\n> +\tEOF\n> +\tcat expect-F >>expect-m &&\n> +\tgit log -4 >output &&\n>  \ttest_cmp expect-m output\n>  '\n>  \n> -test_expect_success 'remove note with add -f -F /dev/null (setup)' '\n> -\tgit notes add -f -F /dev/null\n> -'\n> -\n> -cat > expect-rm-F << EOF\n> -commit bd1753200303d0a0344be813e504253b3d98e74d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:17:13 2005 -0700\n> -\n> -    5th\n> -EOF\n> +test_expect_success 'remove note with add -f -F /dev/null' '\n> +\tgit notes add -f -F /dev/null &&\n> +\tcat >expect-rm-F <<-EOF &&\n> +\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n>  \n> -printf \"\\n\" >> expect-rm-F\n> -cat expect-F >> expect-rm-F\n> +\t\t${indent}5th\n>  \n> -test_expect_success 'verify note removal with -F /dev/null' '\n> -\tgit log -4 > output &&\n> +\tEOF\n> +\tcat expect-F >>expect-rm-F &&\n> +\tgit log -4 >output &&\n>  \ttest_cmp expect-rm-F output &&\n>  \ttest_must_fail git notes show\n>  '\n>  \n> -test_expect_success 'do not create empty note with -m \"\" (setup)' '\n> -\tgit notes add -m \"\"\n> -'\n> -\n> -test_expect_success 'verify non-creation of note with -m \"\"' '\n> -\tgit log -4 > output &&\n> +test_expect_success 'do not create empty note with -m \"\"' '\n> +\tgit notes add -m \"\" &&\n> +\tgit log -4 >output &&\n>  \ttest_cmp expect-rm-F output &&\n>  \ttest_must_fail git notes show\n>  '\n>  \n> -cat > expect-combine_m_and_F << EOF\n> -foo\n> -\n> -xyzzy\n> +test_expect_success 'create note with combination of -m and -F' '\n> +\tcat >expect-combine_m_and_F <<-EOF &&\n> +\t\tfoo\n>  \n> -bar\n> +\t\txyzzy\n>  \n> -zyxxy\n> +\t\tbar\n>  \n> -baz\n> -EOF\n> +\t\tzyxxy\n>  \n> -test_expect_success 'create note with combination of -m and -F' '\n> -\techo \"xyzzy\" > note_a &&\n> -\techo \"zyxxy\" > note_b &&\n> +\t\tbaz\n> +\tEOF\n> +\techo \"xyzzy\" >note_a &&\n> +\techo \"zyxxy\" >note_b &&\n>  \tgit notes add -m \"foo\" -F note_a -m \"bar\" -F note_b -m \"baz\" &&\n> -\tgit notes show > output &&\n> +\tgit notes show >output &&\n>  \ttest_cmp expect-combine_m_and_F output\n>  '\n>  \n> -test_expect_success 'remove note with \"git notes remove\" (setup)' '\n> +test_expect_success 'remove note with \"git notes remove\"' '\n>  \tgit notes remove HEAD^ &&\n> -\tgit notes remove\n> -'\n> +\tgit notes remove &&\n> +\tcat >expect-rm-remove <<-EOF &&\n> +\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n>  \n> -cat > expect-rm-remove << EOF\n> -commit bd1753200303d0a0344be813e504253b3d98e74d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:17:13 2005 -0700\n> +\t\t${indent}5th\n>  \n> -    5th\n> -\n> -commit 15023535574ded8b1a89052b32673f84cf9582b8\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:16:13 2005 -0700\n> -\n> -    4th\n> -EOF\n> +\t\tcommit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:16:13 2005 -0700\n>  \n> -printf \"\\n\" >> expect-rm-remove\n> -cat expect-multiline >> expect-rm-remove\n> +\t\t${indent}4th\n>  \n> -test_expect_success 'verify note removal with \"git notes remove\"' '\n> -\tgit log -4 > output &&\n> +\tEOF\n> +\tcat expect-multiline >>expect-rm-remove &&\n> +\tgit log -4 >output &&\n>  \ttest_cmp expect-rm-remove output &&\n>  \ttest_must_fail git notes show HEAD^\n>  '\n>  \n> -cat > expect << EOF\n> -c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd75\n> -c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5\n> -EOF\n> -\n>  test_expect_success 'removing non-existing note should not create new commit' '\n> -\tgit rev-parse --verify refs/notes/commits > before_commit &&\n> +\tgit rev-parse --verify refs/notes/commits >before_commit &&\n>  \ttest_must_fail git notes remove HEAD^ &&\n> -\tgit rev-parse --verify refs/notes/commits > after_commit &&\n> +\tgit rev-parse --verify refs/notes/commits >after_commit &&\n>  \ttest_cmp before_commit after_commit\n>  '\n>  \n> @@ -505,69 +443,67 @@ test_expect_success 'removing with --stdin --ignore-missing' '\n>  '\n>  \n>  test_expect_success 'list notes with \"git notes list\"' '\n> -\tgit notes list > output &&\n> +\tcat >expect <<-EOF &&\n> +\t\tc9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n> +\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290\n> +\tEOF\n> +\tgit notes list >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'list notes with \"git notes\"' '\n> -\tgit notes > output &&\n> +\tgit notes >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -c18dc024e14f08d18d14eea0d747ff692d66d6a3\n> -EOF\n> -\n>  test_expect_success 'list specific note with \"git notes list <object>\"' '\n> -\tgit notes list HEAD^^ > output &&\n> +\tcat >expect <<-EOF &&\n> +\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3\n> +\tEOF\n> +\tgit notes list HEAD^^ >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -EOF\n> -\n>  test_expect_success 'listing non-existing notes fails' '\n> -\ttest_must_fail git notes list HEAD > output &&\n> +\tcat >expect <<-EOF &&\n> +\tEOF\n> +\ttest_must_fail git notes list HEAD >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -Initial set of notes\n> -\n> -More notes appended with git notes append\n> -EOF\n> -\n>  test_expect_success 'append to existing note with \"git notes append\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tInitial set of notes\n> +\n> +\t\tMore notes appended with git notes append\n> +\tEOF\n>  \tgit notes add -m \"Initial set of notes\" &&\n>  \tgit notes append -m \"More notes appended with git notes append\" &&\n> -\tgit notes show > output &&\n> +\tgit notes show >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect_list << EOF\n> -c18dc024e14f08d18d14eea0d747ff692d66d6a3 1584215f1d29c65e99c6c6848626553fdd07fd75\n> -c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 268048bfb8a1fb38e703baceb8ab235421bf80c5\n> -4b6ad22357cc8a1296720574b8d2fbc22fab0671 bd1753200303d0a0344be813e504253b3d98e74d\n> -EOF\n> -\n>  test_expect_success '\"git notes list\" does not expand to \"git notes list HEAD\"' '\n> -\tgit notes list > output &&\n> +\tcat >expect_list <<-EOF &&\n> +\t\tc9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n> +\t\t4b6ad22357cc8a1296720574b8d2fbc22fab0671 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n> +\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290\n> +\tEOF\n> +\tgit notes list >output &&\n>  \ttest_cmp expect_list output\n>  '\n>  \n>  test_expect_success 'appending empty string does not change existing note' '\n>  \tgit notes append -m \"\" &&\n> -\tgit notes show > output &&\n> +\tgit notes show >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'git notes append == add when there is no existing note' '\n>  \tgit notes remove HEAD &&\n>  \ttest_must_fail git notes list HEAD &&\n> -\tgit notes append -m \"Initial set of notes\n> -\n> -More notes appended with git notes append\" &&\n> -\tgit notes show > output &&\n> +\tgit notes append -m \"Initial set of notes${LF}${LF}More notes appended with git notes append\" &&\n> +\tgit notes show >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> @@ -579,229 +515,208 @@ test_expect_success 'appending empty string to non-existing note does not create\n>  '\n>  \n>  test_expect_success 'create other note on a different notes ref (setup)' '\n> -\t: > a6 &&\n> -\tgit add a6 &&\n> -\ttest_tick &&\n> -\tgit commit -m 6th &&\n> -\tGIT_NOTES_REF=\"refs/notes/other\" git notes add -m \"other note\"\n> -'\n> -\n> -cat > expect-other << EOF\n> -commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:18:13 2005 -0700\n> +\ttest_commit 6th &&\n> +\tGIT_NOTES_REF=\"refs/notes/other\" git notes add -m \"other note\" &&\n> +\tcat >expect-not-other <<-EOF &&\n> +\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n>  \n> -    6th\n> +\t\t${indent}6th\n> +\tEOF\n> +\tcp expect-not-other expect-other &&\n> +\tcat >>expect-other <<-EOF\n>  \n> -Notes (other):\n> -    other note\n> -EOF\n> -\n> -cat > expect-not-other << EOF\n> -commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:18:13 2005 -0700\n> -\n> -    6th\n> -EOF\n> +\t\tNotes (other):\n> +\t\t${indent}other note\n> +\tEOF\n> +'\n>  \n>  test_expect_success 'Do not show note on other ref by default' '\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect-not-other output\n>  '\n>  \n>  test_expect_success 'Do show note when ref is given in GIT_NOTES_REF' '\n> -\tGIT_NOTES_REF=\"refs/notes/other\" git log -1 > output &&\n> +\tGIT_NOTES_REF=\"refs/notes/other\" git log -1 >output &&\n>  \ttest_cmp expect-other output\n>  '\n>  \n>  test_expect_success 'Do show note when ref is given in core.notesRef config' '\n> -\tgit config core.notesRef \"refs/notes/other\" &&\n> -\tgit log -1 > output &&\n> +\ttest_config core.notesRef \"refs/notes/other\" &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect-other output\n>  '\n>  \n>  test_expect_success 'Do not show note when core.notesRef is overridden' '\n> -\tGIT_NOTES_REF=\"refs/notes/wrong\" git log -1 > output &&\n> +\ttest_config core.notesRef \"refs/notes/other\" &&\n> +\tGIT_NOTES_REF=\"refs/notes/wrong\" git log -1 >output &&\n>  \ttest_cmp expect-not-other output\n>  '\n>  \n> -cat > expect-both << EOF\n> -commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:18:13 2005 -0700\n> -\n> -    6th\n> +test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '\n> +\tcat >expect-both <<-EOF &&\n> +\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n>  \n> -Notes:\n> -    order test\n> +\t\t${indent}6th\n>  \n> -Notes (other):\n> -    other note\n> +\t\tNotes:\n> +\t\t${indent}order test\n>  \n> -commit bd1753200303d0a0344be813e504253b3d98e74d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:17:13 2005 -0700\n> +\t\tNotes (other):\n> +\t\t${indent}other note\n>  \n> -    5th\n> +\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n>  \n> -Notes:\n> -    replacement for deleted note\n> -EOF\n> +\t\t${indent}5th\n>  \n> -test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '\n> +\t\tNotes:\n> +\t\t${indent}replacement for deleted note\n> +\tEOF\n>  \tGIT_NOTES_REF=refs/notes/commits git notes add \\\n>  \t\t-m\"replacement for deleted note\" HEAD^ &&\n>  \tGIT_NOTES_REF=refs/notes/commits git notes add -m\"order test\" &&\n> -\tgit config --unset core.notesRef &&\n> -\tgit config notes.displayRef \"refs/notes/*\" &&\n> -\tgit log -2 > output &&\n> +\ttest_unconfig core.notesRef &&\n> +\ttest_config notes.displayRef \"refs/notes/*\" &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect-both output\n>  '\n>  \n>  test_expect_success 'core.notesRef is implicitly in notes.displayRef' '\n> -\tgit config core.notesRef refs/notes/commits &&\n> -\tgit config notes.displayRef refs/notes/other &&\n> -\tgit log -2 > output &&\n> +\ttest_config core.notesRef refs/notes/commits &&\n> +\ttest_config notes.displayRef refs/notes/other &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect-both output\n>  '\n>  \n>  test_expect_success 'notes.displayRef can be given more than once' '\n> -\tgit config --unset core.notesRef &&\n> -\tgit config notes.displayRef refs/notes/commits &&\n> +\ttest_unconfig core.notesRef &&\n> +\ttest_config notes.displayRef refs/notes/commits &&\n>  \tgit config --add notes.displayRef refs/notes/other &&\n> -\tgit log -2 > output &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect-both output\n>  '\n>  \n> -cat > expect-both-reversed << EOF\n> -commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:18:13 2005 -0700\n> -\n> -    6th\n> -\n> -Notes (other):\n> -    other note\n> -\n> -Notes:\n> -    order test\n> -EOF\n> -\n>  test_expect_success 'notes.displayRef respects order' '\n> -\tgit config core.notesRef refs/notes/other &&\n> -\tgit config --unset-all notes.displayRef &&\n> -\tgit config notes.displayRef refs/notes/commits &&\n> -\tgit log -1 > output &&\n> +\tcat >expect-both-reversed <<-EOF &&\n> +\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n> +\n> +\t\t${indent}6th\n> +\n> +\t\tNotes (other):\n> +\t\t${indent}other note\n> +\n> +\t\tNotes:\n> +\t\t${indent}order test\n> +\tEOF\n> +\ttest_config core.notesRef refs/notes/other &&\n> +\ttest_config notes.displayRef refs/notes/commits &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect-both-reversed output\n>  '\n>  \n>  test_expect_success 'GIT_NOTES_DISPLAY_REF works' '\n> -\tgit config --unset-all core.notesRef &&\n> -\tgit config --unset-all notes.displayRef &&\n>  \tGIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \\\n> -\t\tgit log -2 > output &&\n> +\t\tgit log -2 >output &&\n>  \ttest_cmp expect-both output\n>  '\n>  \n> -cat > expect-none << EOF\n> -commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:18:13 2005 -0700\n> +test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '\n> +\tcat >expect-none <<-EOF &&\n> +\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n>  \n> -    6th\n> +\t\t${indent}6th\n>  \n> -commit bd1753200303d0a0344be813e504253b3d98e74d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:17:13 2005 -0700\n> +\t\tcommit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:17:13 2005 -0700\n>  \n> -    5th\n> -EOF\n> -\n> -test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '\n> -\tgit config notes.displayRef \"refs/notes/*\" &&\n> -\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 > output &&\n> +\t\t${indent}5th\n> +\tEOF\n> +\ttest_config notes.displayRef \"refs/notes/*\" &&\n> +\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 >output &&\n>  \ttest_cmp expect-none output\n>  '\n>  \n>  test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '\n> -\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 > output &&\n> +\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 >output &&\n>  \ttest_cmp expect-both output\n>  '\n>  \n> -cat > expect-commits << EOF\n> -commit 387a89921c73d7ed72cd94d179c1c7048ca47756\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:18:13 2005 -0700\n> -\n> -    6th\n> +test_expect_success '--no-standard-notes' '\n> +\tcat >expect-commits <<EOF\n> +\t\tcommit 2c125331118caba0ff8238b7f4958ac6e93fe39c\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:18:13 2005 -0700\n>  \n> -Notes:\n> -    order test\n> -EOF\n> +\t\t${indent}6th\n>  \n> -test_expect_success '--no-standard-notes' '\n> -\tgit log --no-standard-notes --show-notes=commits -1 > output &&\n> +\t\tNotes:\n> +\t\t${indent}order test\n> +\tEOF\n> +\tgit log --no-standard-notes --show-notes=commits -1 >output &&\n>  \ttest_cmp expect-commits output\n>  '\n>  \n>  test_expect_success '--standard-notes' '\n> +\ttest_config notes.displayRef \"refs/notes/*\" &&\n>  \tgit log --no-standard-notes --show-notes=commits \\\n> -\t\t--standard-notes -2 > output &&\n> +\t\t--standard-notes -2 >output &&\n>  \ttest_cmp expect-both output\n>  '\n>  \n>  test_expect_success '--show-notes=ref accumulates' '\n>  \tgit log --show-notes=other --show-notes=commits \\\n> -\t\t --no-standard-notes -1 > output &&\n> +\t\t --no-standard-notes -1 >output &&\n>  \ttest_cmp expect-both-reversed output\n>  '\n>  \n>  test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '\n> -\tgit config core.notesRef refs/notes/other &&\n> -\techo \"Note on a tree\" > expect &&\n> +\ttest_config core.notesRef refs/notes/other &&\n> +\techo \"Note on a tree\" >expect &&\n>  \tgit notes add -m \"Note on a tree\" HEAD: &&\n> -\tgit notes show HEAD: > actual &&\n> +\tgit notes show HEAD: >actual &&\n>  \ttest_cmp expect actual &&\n> -\techo \"Note on a blob\" > expect &&\n> +\techo \"Note on a blob\" >expect &&\n>  \tfilename=$(git ls-tree --name-only HEAD | head -n1) &&\n>  \tgit notes add -m \"Note on a blob\" HEAD:$filename &&\n> -\tgit notes show HEAD:$filename > actual &&\n> +\tgit notes show HEAD:$filename >actual &&\n>  \ttest_cmp expect actual &&\n> -\techo \"Note on a tag\" > expect &&\n> +\techo \"Note on a tag\" >expect &&\n>  \tgit tag -a -m \"This is an annotated tag\" foobar HEAD^ &&\n>  \tgit notes add -m \"Note on a tag\" foobar &&\n> -\tgit notes show foobar > actual &&\n> +\tgit notes show foobar >actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n> -cat > expect << EOF\n> -commit 2ede89468182a62d0bde2583c736089bcf7d7e92\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:19:13 2005 -0700\n> +test_expect_success 'create note from other note with \"git notes add -C\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit fb01e0ca8c33b6cc0c6451dde747f97df567cb5c\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:19:13 2005 -0700\n>  \n> -    7th\n> +\t\t${indent}7th\n>  \n> -Notes (other):\n> -    other note\n> -EOF\n> -\n> -test_expect_success 'create note from other note with \"git notes add -C\"' '\n> -\t: > a7 &&\n> -\tgit add a7 &&\n> -\ttest_tick &&\n> -\tgit commit -m 7th &&\n> +\t\tNotes:\n> +\t\t${indent}order test\n> +\tEOF\n> +\ttest_commit 7th &&\n>  \tgit notes add -C $(git notes list HEAD^) &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual &&\n>  \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD^)\"\n>  '\n>  \n>  test_expect_success 'create note from non-existing note with \"git notes add -C\" fails' '\n> -\t: > a8 &&\n> -\tgit add a8 &&\n> -\ttest_tick &&\n> -\tgit commit -m 8th &&\n> +\ttest_commit 8th &&\n>  \ttest_must_fail git notes add -C deadbeef &&\n>  \ttest_must_fail git notes list HEAD\n>  '\n> @@ -814,404 +729,385 @@ test_expect_success 'create note from non-blob with \"git notes add -C\" fails' '\n>  \ttest_must_fail git notes list HEAD\n>  '\n>  \n> -cat > expect << EOF\n> -commit 80d796defacd5db327b7a4e50099663902fbdc5c\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:20:13 2005 -0700\n> +test_expect_success 'create note from blob with \"git notes add -C\" reuses blob id' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 9a4c31c7f722b5d517e92c64e932dd751e1413bf\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:20:13 2005 -0700\n>  \n> -    8th\n> +\t\t${indent}8th\n>  \n> -Notes (other):\n> -    This is a blob object\n> -EOF\n> -\n> -test_expect_success 'create note from blob with \"git notes add -C\" reuses blob id' '\n> +\t\tNotes:\n> +\t\t${indent}This is a blob object\n> +\tEOF\n>  \tblob=$(echo \"This is a blob object\" | git hash-object -w --stdin) &&\n>  \tgit notes add -C $blob &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual &&\n>  \ttest \"$(git notes list HEAD)\" = \"$blob\"\n>  '\n>  \n> -cat > expect << EOF\n> -commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:21:13 2005 -0700\n> -\n> -    9th\n> +test_expect_success 'create note from other note with \"git notes add -c\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 2e0db4bc649e174d667a1cde19e725cf897a5bd2\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:21:13 2005 -0700\n>  \n> -Notes (other):\n> -    yet another note\n> -EOF\n> +\t\t${indent}9th\n>  \n> -test_expect_success 'create note from other note with \"git notes add -c\"' '\n> -\t: > a9 &&\n> -\tgit add a9 &&\n> -\ttest_tick &&\n> -\tgit commit -m 9th &&\n> +\t\tNotes:\n> +\t\t${indent}yet another note\n> +\tEOF\n> +\ttest_commit 9th &&\n>  \tMSG=\"yet another note\" git notes add -c $(git notes list HEAD^^) &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n>  test_expect_success 'create note from non-existing note with \"git notes add -c\" fails' '\n> -\t: > a10 &&\n> -\tgit add a10 &&\n> -\ttest_tick &&\n> -\tgit commit -m 10th &&\n> +\ttest_commit 10th &&\n>  \ttest_must_fail env MSG=\"yet another note\" git notes add -c deadbeef &&\n>  \ttest_must_fail git notes list HEAD\n>  '\n>  \n> -cat > expect << EOF\n> -commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:21:13 2005 -0700\n> -\n> -    9th\n> -\n> -Notes (other):\n> -    yet another note\n> -$whitespace\n> -    yet another note\n> -EOF\n> -\n>  test_expect_success 'append to note from other note with \"git notes append -C\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 2e0db4bc649e174d667a1cde19e725cf897a5bd2\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:21:13 2005 -0700\n> +\n> +\t\t${indent}9th\n> +\n> +\t\tNotes:\n> +\t\t${indent}yet another note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\tEOF\n>  \tgit notes append -C $(git notes list HEAD^) HEAD^ &&\n> -\tgit log -1 HEAD^ > actual &&\n> +\tgit log -1 HEAD^ >actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n> -cat > expect << EOF\n> -commit ffed603236bfa3891c49644257a83598afe8ae5a\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:22:13 2005 -0700\n> -\n> -    10th\n> +test_expect_success 'create note from other note with \"git notes append -c\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:22:13 2005 -0700\n>  \n> -Notes (other):\n> -    other note\n> -EOF\n> +\t\t${indent}10th\n>  \n> -test_expect_success 'create note from other note with \"git notes append -c\"' '\n> +\t\tNotes:\n> +\t\t${indent}other note\n> +\tEOF\n>  \tMSG=\"other note\" git notes append -c $(git notes list HEAD^) &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n> -cat > expect << EOF\n> -commit ffed603236bfa3891c49644257a83598afe8ae5a\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:22:13 2005 -0700\n> -\n> -    10th\n> -\n> -Notes (other):\n> -    other note\n> -$whitespace\n> -    yet another note\n> -EOF\n> -\n>  test_expect_success 'append to note from other note with \"git notes append -c\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:22:13 2005 -0700\n> +\n> +\t\t${indent}10th\n> +\n> +\t\tNotes:\n> +\t\t${indent}other note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\tEOF\n>  \tMSG=\"yet another note\" git notes append -c $(git notes list HEAD) &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual\n>  '\n>  \n> -cat > expect << EOF\n> -commit 6352c5e33dbcab725fe0579be16aa2ba8eb369be\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:23:13 2005 -0700\n> -\n> -    11th\n> -\n> -Notes (other):\n> -    other note\n> -$whitespace\n> -    yet another note\n> -EOF\n> -\n>  test_expect_success 'copy note with \"git notes copy\"' '\n> -\t: > a11 &&\n> -\tgit add a11 &&\n> -\ttest_tick &&\n> -\tgit commit -m 11th &&\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:23:13 2005 -0700\n> +\n> +\t\t${indent}11th\n> +\n> +\t\tNotes:\n> +\t\t${indent}other note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\tEOF\n> +\ttest_commit 11th &&\n>  \tgit notes copy HEAD^ HEAD &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual &&\n>  \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD^)\"\n>  '\n>  \n>  test_expect_success 'prevent overwrite with \"git notes copy\"' '\n>  \ttest_must_fail git notes copy HEAD~2 HEAD &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual &&\n>  \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD^)\"\n>  '\n>  \n> -cat > expect << EOF\n> -commit 6352c5e33dbcab725fe0579be16aa2ba8eb369be\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:23:13 2005 -0700\n> -\n> -    11th\n> -\n> -Notes (other):\n> -    yet another note\n> -$whitespace\n> -    yet another note\n> -EOF\n> -\n>  test_expect_success 'allow overwrite with \"git notes copy -f\"' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:23:13 2005 -0700\n> +\n> +\t\t${indent}11th\n> +\n> +\t\tNotes:\n> +\t\t${indent}yet another note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\tEOF\n>  \tgit notes copy -f HEAD~2 HEAD &&\n> -\tgit log -1 > actual &&\n> +\tgit log -1 >actual &&\n>  \ttest_cmp expect actual &&\n>  \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD~2)\"\n>  '\n>  \n>  test_expect_success 'cannot copy note from object without notes' '\n> -\t: > a12 &&\n> -\tgit add a12 &&\n> -\ttest_tick &&\n> -\tgit commit -m 12th &&\n> -\t: > a13 &&\n> -\tgit add a13 &&\n> -\ttest_tick &&\n> -\tgit commit -m 13th &&\n> +\ttest_commit 12th &&\n> +\ttest_commit 13th &&\n>  \ttest_must_fail git notes copy HEAD^ HEAD\n>  '\n>  \n> -cat > expect << EOF\n> -commit e5d4fb5698d564ab8c73551538ecaf2b0c666185\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:25:13 2005 -0700\n> -\n> -    13th\n> +test_expect_success 'git notes copy --stdin' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit e871aa61182b1d95d0a6fb75445d891722863b6b\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:25:13 2005 -0700\n>  \n> -Notes (other):\n> -    yet another note\n> -$whitespace\n> -    yet another note\n> +\t\t${indent}13th\n>  \n> -commit 7038787dfe22a14c3867ce816dbba39845359719\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:24:13 2005 -0700\n> +\t\tNotes:\n> +\t\t${indent}yet another note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n>  \n> -    12th\n> +\t\tcommit 65e263ded02ae4e8839bc151095113737579dc12\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:24:13 2005 -0700\n>  \n> -Notes (other):\n> -    other note\n> -$whitespace\n> -    yet another note\n> -EOF\n> +\t\t${indent}12th\n>  \n> -test_expect_success 'git notes copy --stdin' '\n> +\t\tNotes:\n> +\t\t${indent}other note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\tEOF\n>  \t(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \\\n>  \techo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |\n>  \tgit notes copy --stdin &&\n> -\tgit log -2 > output &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect output &&\n>  \ttest \"$(git notes list HEAD)\" = \"$(git notes list HEAD~2)\" &&\n>  \ttest \"$(git notes list HEAD^)\" = \"$(git notes list HEAD~3)\"\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> +test_expect_success 'git notes copy --for-rewrite (unconfigured)' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n>  \n> -commit be28d8b4d9951ad940d229ee3b0b9ee3b1ec273d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:26:13 2005 -0700\n> +\t\t${indent}15th\n>  \n> -    14th\n> -EOF\n> +\t\tcommit 07c85d77059393ed0154b8c96906547a59dfcddd\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:26:13 2005 -0700\n>  \n> -test_expect_success 'git notes copy --for-rewrite (unconfigured)' '\n> +\t\t${indent}14th\n> +\tEOF\n>  \ttest_commit 14th &&\n>  \ttest_commit 15th &&\n>  \t(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \\\n>  \techo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -2 > output &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> -\n> -Notes (other):\n> -    yet another note\n> -$whitespace\n> -    yet another note\n> -\n> -commit be28d8b4d9951ad940d229ee3b0b9ee3b1ec273d\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:26:13 2005 -0700\n> -\n> -    14th\n> -\n> -Notes (other):\n> -    other note\n> -$whitespace\n> -    yet another note\n> -EOF\n> -\n>  test_expect_success 'git notes copy --for-rewrite (enabled)' '\n> -\tgit config notes.rewriteMode overwrite &&\n> -\tgit config notes.rewriteRef \"refs/notes/*\" &&\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n> +\n> +\t\t${indent}15th\n> +\n> +\t\tNotes:\n> +\t\t${indent}yet another note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\n> +\t\tcommit 07c85d77059393ed0154b8c96906547a59dfcddd\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:26:13 2005 -0700\n> +\n> +\t\t${indent}14th\n> +\n> +\t\tNotes:\n> +\t\t${indent}other note\n> +\t\t${indent}\n> +\t\t${indent}yet another note\n> +\tEOF\n> +\ttest_config notes.rewriteMode overwrite &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \t(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \\\n>  \techo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -2 > output &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'git notes copy --for-rewrite (disabled)' '\n> -\tgit config notes.rewrite.bar false &&\n> +\ttest_config notes.rewrite.bar false &&\n>  \techo $(git rev-parse HEAD~3) $(git rev-parse HEAD) |\n>  \tgit notes copy --for-rewrite=bar &&\n> -\tgit log -2 > output &&\n> +\tgit log -2 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> +test_expect_success 'git notes copy --for-rewrite (overwrite)' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n>  \n> -Notes (other):\n> -    a fresh note\n> -EOF\n> +\t\t${indent}15th\n>  \n> -test_expect_success 'git notes copy --for-rewrite (overwrite)' '\n> +\t\tNotes:\n> +\t\t${indent}a fresh note\n> +\tEOF\n>  \tgit notes add -f -m\"a fresh note\" HEAD^ &&\n> +\ttest_config notes.rewriteMode overwrite &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'git notes copy --for-rewrite (ignore)' '\n> -\tgit config notes.rewriteMode ignore &&\n> +\ttest_config notes.rewriteMode ignore &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> -\n> -Notes (other):\n> -    a fresh note\n> -$whitespace\n> -    another fresh note\n> -EOF\n> -\n>  test_expect_success 'git notes copy --for-rewrite (append)' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n> +\n> +\t\t${indent}15th\n> +\n> +\t\tNotes:\n> +\t\t${indent}a fresh note\n> +\t\t${indent}\n> +\t\t${indent}another fresh note\n> +\tEOF\n>  \tgit notes add -f -m\"another fresh note\" HEAD^ &&\n> -\tgit config notes.rewriteMode concatenate &&\n> +\ttest_config notes.rewriteMode concatenate &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> -\n> -Notes (other):\n> -    a fresh note\n> -$whitespace\n> -    another fresh note\n> -$whitespace\n> -    append 1\n> -$whitespace\n> -    append 2\n> -EOF\n> -\n>  test_expect_success 'git notes copy --for-rewrite (append two to one)' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n> +\n> +\t\t${indent}15th\n> +\n> +\t\tNotes:\n> +\t\t${indent}a fresh note\n> +\t\t${indent}\n> +\t\t${indent}another fresh note\n> +\t\t${indent}\n> +\t\t${indent}append 1\n> +\t\t${indent}\n> +\t\t${indent}append 2\n> +\tEOF\n>  \tgit notes add -f -m\"append 1\" HEAD^ &&\n>  \tgit notes add -f -m\"append 2\" HEAD^^ &&\n> +\ttest_config notes.rewriteMode concatenate &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \t(echo $(git rev-parse HEAD^) $(git rev-parse HEAD);\n>  \techo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'git notes copy --for-rewrite (append empty)' '\n>  \tgit notes remove HEAD^ &&\n> +\ttest_config notes.rewriteMode concatenate &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tgit notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> -\n> -Notes (other):\n> -    replacement note 1\n> -EOF\n> -\n>  test_expect_success 'GIT_NOTES_REWRITE_MODE works' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n> +\n> +\t\t${indent}15th\n> +\n> +\t\tNotes:\n> +\t\t${indent}replacement note 1\n> +\tEOF\n> +\ttest_config notes.rewriteMode concatenate &&\n> +\ttest_config notes.rewriteRef \"refs/notes/*\" &&\n>  \tgit notes add -f -m\"replacement note 1\" HEAD^ &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tGIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> -cat > expect << EOF\n> -commit 37a0d4cba38afef96ba54a3ea567e6dac575700b\n> -Author: A U Thor <author@example.com>\n> -Date:   Thu Apr 7 15:27:13 2005 -0700\n> -\n> -    15th\n> +test_expect_success 'GIT_NOTES_REWRITE_REF works' '\n> +\tcat >expect <<-EOF &&\n> +\t\tcommit 4acf42e847e7fffbbf89ee365c20ac7caf40de89\n> +\t\tAuthor: A U Thor <author@example.com>\n> +\t\tDate:   Thu Apr 7 15:27:13 2005 -0700\n>  \n> -Notes (other):\n> -    replacement note 2\n> -EOF\n> +\t\t${indent}15th\n>  \n> -test_expect_success 'GIT_NOTES_REWRITE_REF works' '\n> -\tgit config notes.rewriteMode overwrite &&\n> +\t\tNotes:\n> +\t\t${indent}replacement note 2\n> +\tEOF\n>  \tgit notes add -f -m\"replacement note 2\" HEAD^ &&\n> -\tgit config --unset-all notes.rewriteRef &&\n> +\ttest_config notes.rewriteMode overwrite &&\n> +\ttest_unconfig notes.rewriteRef &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tGIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \\\n>  \t\tgit notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n>  test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '\n> -\tgit config notes.rewriteRef refs/notes/other &&\n>  \tgit notes add -f -m\"replacement note 3\" HEAD^ &&\n> +\ttest_config notes.rewriteMode overwrite &&\n> +\ttest_config notes.rewriteRef refs/notes/other &&\n>  \techo $(git rev-parse HEAD^) $(git rev-parse HEAD) |\n>  \tGIT_NOTES_REWRITE_REF= git notes copy --for-rewrite=foo &&\n> -\tgit log -1 > output &&\n> +\tgit log -1 >output &&\n>  \ttest_cmp expect output\n>  '\n>  \n> @@ -1221,13 +1117,13 @@ test_expect_success 'git notes copy diagnoses too many or too few parameters' '\n>  '\n>  \n>  test_expect_success 'git notes get-ref (no overrides)' '\n> -\tgit config --unset core.notesRef &&\n> +\ttest_unconfig core.notesRef &&\n>  \tsane_unset GIT_NOTES_REF &&\n>  \ttest \"$(git notes get-ref)\" = \"refs/notes/commits\"\n>  '\n>  \n>  test_expect_success 'git notes get-ref (core.notesRef)' '\n> -\tgit config core.notesRef refs/notes/foo &&\n> +\ttest_config core.notesRef refs/notes/foo &&\n>  \ttest \"$(git notes get-ref)\" = \"refs/notes/foo\"\n>  '\n>  \n> @@ -1277,10 +1173,10 @@ EOF\n>  test_expect_success 'empty notes are displayed by git log' '\n>  \ttest_commit 17th &&\n>  \tgit log -1 >expect &&\n> -\tcat >>expect <<\\EOF &&\n> +\tcat >>expect <<-EOF &&\n>  \n> -Notes:\n> -EOF\n> +\t\tNotes:\n> +\tEOF\n>  \tgit notes add -C \"$empty_blob\" --allow-empty &&\n>  \tgit log -1 >actual &&\n>  \ttest_cmp expect actual\n"},{"id":"251700","messageId":"CALKQrgdBhm91tipHRQ3sF_DacSh5nRJmS7eP4S5Z4vB8R8O4_w@mail.gmail.com","threadId":"37914","inReplyTo":"xmqqmw7y94jm.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCHv4 5/9] builtin/notes: Simplify early exit code in add()","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-11T00:49:58Z","receivedAt":"2014-11-11T00:49:58Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Mon, Nov 10, 2014 at 9:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Johan Herland <johan@herland.net> writes:\n>\n>> Signed-off-by: Johan Herland <johan@herland.net>\n>> ---\n>>  builtin/notes.c | 12 +++++-------\n>>  1 file changed, 5 insertions(+), 7 deletions(-)\n>>\n>> diff --git a/builtin/notes.c b/builtin/notes.c\n>> index 1017472..f1480cf 100644\n>> --- a/builtin/notes.c\n>> +++ b/builtin/notes.c\n>> @@ -399,7 +399,7 @@ static int append_edit(int argc, const char **argv, const char *prefix);\n>>\n>>  static int add(int argc, const char **argv, const char *prefix)\n>>  {\n>> -     int retval = 0, force = 0;\n>> +     int force = 0;\n>>       const char *object_ref;\n>>       struct notes_tree *t;\n>>       unsigned char object[20], new_note[20];\n>> @@ -441,6 +441,8 @@ static int add(int argc, const char **argv, const char *prefix)\n>>\n>>       if (note) {\n>>               if (!force) {\n>> +                     free_note_data(&d);\n>> +                     free_notes(t);\n>>                       if (!d.given) {\n>\n> It looks a bit strange to refer to d.given after calling a function\n> that sounds as if it is meant to clear what is recorded in and to\n> invalidate &d; yes, I can read the implementation to see that\n> d.given keeps its stale value, but that is something other people\n> may want to \"clean up\" later and this reference to d.given will get\n> in the way when that happens.\n\nYes, that was obviously an oversight on my part.\n\n> At this point of the code, it makes sense to free t in preparation\n> to either switching to append codepath or erroring out, but does &d\n> have anything in it already to necessitate its freeing?\n\nActually, no, although verifying that required double-checking that\neach of the -m/-F/-c/-C parsers which store data into &d, do in fact\nset d.given.\n\nI suggest to either move the free_note_data(&d) call below the \"if\n(!d.given)\" block, or reorganize into this (which at the moment reads\nbetter to me):\n\n    if (note) {\n        if (!force) {\n            free_notes(t);\n            if (d.given) {\n                free_note_data(&d);\n                return error(_(\"Cannot add notes. \"\n                    \"Found existing notes for object %s. \"\n                    \"Use '-f' to overwrite existing notes\"),\n                    sha1_to_hex(object));\n            }\n            /*\n             * Redirect to \"edit\" subcommand.\n             *\n             * We only end up here if none of -m/-F/-c/-C or -f are\n             * given. The original args are therefore still in\n             * argv[0-1].\n             */\n            argv[0] = \"edit\";\n            return append_edit(argc, argv, prefix);\n        }\n        fprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n            sha1_to_hex(object));\n    }\n\nThis keeps the two free_* calls close together, only separated by if\n(d.given), which nicely indicates whether we need to call\nfree_notes_data(&d) at all.\n\nIf that looks good to you, do you want a re-roll, or is it easier to\nfix up yourself?\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"251701","messageId":"CALKQrgec-_9kbqba7PBFvNpCpeRAb=Pq6-OMnrJ2nw0fh_5LjQ@mail.gmail.com","threadId":"37914","inReplyTo":"xmqqioim9498.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCHv4 9/9] t3301: Modernize","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-11T01:04:46Z","receivedAt":"2014-11-11T01:04:46Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Mon, Nov 10, 2014 at 9:42 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Johan Herland <johan@herland.net> writes:\n>\n>> Make this test script appear somewhat less old-fashioned:\n>>  - Use test helper functions:\n>>     - write_script\n>>     - test_commit\n>>     - test_write_lines\n>>     - test_config\n>>     - test_unconfig\n>>     - test_path_is_missing\n>>  - Remove whitespace between redirection operators and their targets.\n>>  - Move preparation of \"except\" files into tests.\n>\n> expect, I think (no need to resend; I've fixed it up locally).\n\nThanks.\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"251702","messageId":"CAPig+cQuZ7F5OEVDJ8M-p8B5YB9YNgnNzbbNXS2Dzy6u5_rxdw@mail.gmail.com","threadId":"37914","inReplyTo":"CALKQrgec-_9kbqba7PBFvNpCpeRAb=Pq6-OMnrJ2nw0fh_5LjQ@mail.gmail.com","subject":"Re: [PATCHv4 9/9] t3301: Modernize","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-11-11T01:07:32Z","receivedAt":"2014-11-11T01:07:32Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Nov 10, 2014 at 8:04 PM, Johan Herland <johan@herland.net> wrote:\n> On Mon, Nov 10, 2014 at 9:42 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Johan Herland <johan@herland.net> writes:\n>>\n>>> Make this test script appear somewhat less old-fashioned:\n>>>  - Use test helper functions:\n>>>     - write_script\n>>>     - test_commit\n>>>     - test_write_lines\n>>>     - test_config\n>>>     - test_unconfig\n>>>     - test_path_is_missing\n>>>  - Remove whitespace between redirection operators and their targets.\n>>>  - Move preparation of \"except\" files into tests.\n>>\n>> expect, I think (no need to resend; I've fixed it up locally).\n>\n> Thanks.\n\nOne further modernization would be to use the name \"actual\" rather\nthan \"output\" for files holding actual contents (as opposed to the\n\"expect\" contents).\n"},{"id":"251706","messageId":"CALKQrgfHNj=TRnFL+5P-_8YCs4D6SF6S9xBqeVAdvj0c+USp4Q@mail.gmail.com","threadId":"37914","inReplyTo":"CAPig+cQuZ7F5OEVDJ8M-p8B5YB9YNgnNzbbNXS2Dzy6u5_rxdw@mail.gmail.com","subject":"Re: [PATCHv4 9/9] t3301: Modernize","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-11T01:50:20Z","receivedAt":"2014-11-11T01:50:20Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Tue, Nov 11, 2014 at 2:07 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Mon, Nov 10, 2014 at 8:04 PM, Johan Herland <johan@herland.net> wrote:\n>> On Mon, Nov 10, 2014 at 9:42 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Johan Herland <johan@herland.net> writes:\n>>>\n>>>> Make this test script appear somewhat less old-fashioned:\n>>>>  - Use test helper functions:\n>>>>     - write_script\n>>>>     - test_commit\n>>>>     - test_write_lines\n>>>>     - test_config\n>>>>     - test_unconfig\n>>>>     - test_path_is_missing\n>>>>  - Remove whitespace between redirection operators and their targets.\n>>>>  - Move preparation of \"except\" files into tests.\n>>>\n>>> expect, I think (no need to resend; I've fixed it up locally).\n>>\n>> Thanks.\n>\n> One further modernization would be to use the name \"actual\" rather\n> than \"output\" for files holding actual contents (as opposed to the\n> \"expect\" contents).\n\nAgreed. Will be fixed in the re-roll.\n\n...Johan\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"251717","messageId":"xmqqvbml7mzl.fsf@gitster.dls.corp.google.com","threadId":"37914","inReplyTo":"CALKQrgdBhm91tipHRQ3sF_DacSh5nRJmS7eP4S5Z4vB8R8O4_w@mail.gmail.com","subject":"Re: [PATCHv4 5/9] builtin/notes: Simplify early exit code in add()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-11T15:53:02Z","receivedAt":"2014-11-11T15:53:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johan Herland <johan@herland.net> writes:\n\n> On Mon, Nov 10, 2014 at 9:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Johan Herland <johan@herland.net> writes:\n>>\n>>> Signed-off-by: Johan Herland <johan@herland.net>\n>>> ---\n>>>  builtin/notes.c | 12 +++++-------\n>>>  1 file changed, 5 insertions(+), 7 deletions(-)\n>>>\n>>> diff --git a/builtin/notes.c b/builtin/notes.c\n>>> index 1017472..f1480cf 100644\n>>> --- a/builtin/notes.c\n>>> +++ b/builtin/notes.c\n>>> @@ -399,7 +399,7 @@ static int append_edit(int argc, const char **argv, const char *prefix);\n>>>\n>>>  static int add(int argc, const char **argv, const char *prefix)\n>>>  {\n>>> -     int retval = 0, force = 0;\n>>> +     int force = 0;\n>>>       const char *object_ref;\n>>>       struct notes_tree *t;\n>>>       unsigned char object[20], new_note[20];\n>>> @@ -441,6 +441,8 @@ static int add(int argc, const char **argv, const char *prefix)\n>>>\n>>>       if (note) {\n>>>               if (!force) {\n>>> +                     free_note_data(&d);\n>>> +                     free_notes(t);\n>>>                       if (!d.given) {\n>>\n>> It looks a bit strange to refer to d.given after calling a function\n>> that sounds as if it is meant to clear what is recorded in and to\n>> invalidate &d; yes, I can read the implementation to see that\n>> d.given keeps its stale value, but that is something other people\n>> may want to \"clean up\" later and this reference to d.given will get\n>> in the way when that happens.\n>\n> Yes, that was obviously an oversight on my part.\n>\n>> At this point of the code, it makes sense to free t in preparation\n>> to either switching to append codepath or erroring out, but does &d\n>> have anything in it already to necessitate its freeing?\n>\n> Actually, no, although verifying that required double-checking that\n> each of the -m/-F/-c/-C parsers which store data into &d, do in fact\n> set d.given.\n>\n> I suggest to either move the free_note_data(&d) call below the \"if\n> (!d.given)\" block, or reorganize into this (which at the moment reads\n> better to me):\n>\n>     if (note) {\n>         if (!force) {\n>             free_notes(t);\n>             if (d.given) {\n>                 free_note_data(&d);\n>                 return error(_(\"Cannot add notes. \"\n>                     \"Found existing notes for object %s. \"\n>                     \"Use '-f' to overwrite existing notes\"),\n>                     sha1_to_hex(object));\n>             }\n>             /*\n>              * Redirect to \"edit\" subcommand.\n>              *\n>              * We only end up here if none of -m/-F/-c/-C or -f are\n>              * given. The original args are therefore still in\n>              * argv[0-1].\n>              */\n>             argv[0] = \"edit\";\n>             return append_edit(argc, argv, prefix);\n>         }\n>         fprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n>             sha1_to_hex(object));\n>     }\n>\n> This keeps the two free_* calls close together, only separated by if\n> (d.given), which nicely indicates whether we need to call\n> free_notes_data(&d) at all.\n>\n> If that looks good to you, do you want a re-roll, or is it easier to\n> fix up yourself?\n\nI strongly prefer reroll for anything bigger than single-line tweaks\nto avoid mistakes.\n\nThans.\n"}]}