{"thread":{"id":"37935","subject":"[PATCHv5 0/9] Handling empty notes","startedAt":"2014-11-12T00:40:07Z","lastAt":"2014-11-12T23:43:41Z","messageCount":14,"participants":["Johan Herland","Eric Sunshine","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"251733","messageId":"1415752816-22782-1-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":null,"subject":"[PATCHv5 0/9] Handling empty notes","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:07Z","receivedAt":"2014-11-12T00:40:07Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Changes v4 -> v5:\n\n - Patch #5: Reorder code to ease readability and fix issue with\n   checking d.given after free_note_data(&d), noticed by Junio.\n\n - Patch #9: Fix typo in commit message, noticed by Junio.\n\n - Patch #9: Rename \"output\" files to \"actual\", suggested by Eric.\n\n - Patch #9: Use test_line_count instead of wc -l, which behaves\n   differently on Macs. noticed by Michael, diagnosed by Eric, and\n   fix suggested by Peff.\n\n - Patch #9: Use -r option to ls-tree when counting entries in notes,\n   tree as this also works for trees with fanout level > 0. Noticed\n   by Peff.\n\n\nHave fun! :)\n\n...Johan\n\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             |  258 +++++----\n notes.c                     |    3 +-\n t/t3301-notes.sh            | 1341 +++++++++++++++++++++----------------------\n 4 files changed, 789 insertions(+), 825 deletions(-)\n\n-- \n2.0.0.rc4.501.gdaf83ca\n"},{"id":"251742","messageId":"1415752816-22782-2-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 1/9] builtin/notes: Fix premature failure when trying to add the empty blob","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:08Z","receivedAt":"2014-11-12T00:40:08Z","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.0.0.rc4.501.gdaf83ca\n"},{"id":"251741","messageId":"1415752816-22782-3-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 2/9] t3301: Verify that 'git notes' removes empty notes by default","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:09Z","receivedAt":"2014-11-12T00:40:09Z","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.0.0.rc4.501.gdaf83ca\n"},{"id":"251735","messageId":"1415752816-22782-4-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 3/9] builtin/notes: Improve naming","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:10Z","receivedAt":"2014-11-12T00:40:10Z","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.0.0.rc4.501.gdaf83ca\n"},{"id":"251734","messageId":"1415752816-22782-5-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 4/9] builtin/notes: Refactor note file path into struct note_data","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:11Z","receivedAt":"2014-11-12T00:40:11Z","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.0.0.rc4.501.gdaf83ca\n"},{"id":"251739","messageId":"1415752816-22782-6-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 5/9] builtin/notes: Simplify early exit code in add()","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:12Z","receivedAt":"2014-11-12T00:40:12Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Remove the need for 'retval' and the unnecessary goto. Also reorganize\nto only call free_note_data() is actually needed.\n\nImproved-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n builtin/notes.c | 35 +++++++++++++++++------------------\n 1 file changed, 17 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 1017472..acdedbd 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,23 +441,23 @@ static int add(int argc, const char **argv, const char *prefix)\n \n \tif (note) {\n \t\tif (!force) {\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-\t\t\t\t * We only end up here if none of -m/-F/-c/-C\n-\t\t\t\t * or -f are given. The original args are\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\tfree_notes(t);\n+\t\t\tif (d.given) {\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\treturn error(_(\"Cannot add notes. \"\n+\t\t\t\t\t\"Found existing notes for object %s. \"\n+\t\t\t\t\t\"Use '-f' to overwrite existing notes\"),\n+\t\t\t\t\tsha1_to_hex(object));\n \t\t\t}\n-\t\t\tretval = 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\t/*\n+\t\t\t * Redirect to \"edit\" subcommand.\n+\t\t\t *\n+\t\t\t * We only end up here if none of -m/-F/-c/-C or -f are\n+\t\t\t * given. The original args are therefore still in\n+\t\t\t * argv[0-1].\n+\t\t\t */\n+\t\t\targv[0] = \"edit\";\n+\t\t\treturn append_edit(argc, argv, prefix);\n \t\t}\n \t\tfprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n \t\t\tsha1_to_hex(object));\n@@ -474,9 +474,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.0.0.rc4.501.gdaf83ca\n"},{"id":"251736","messageId":"1415752816-22782-7-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 6/9] builtin/notes: Split create_note() to clarify add vs. remove logic","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:13Z","receivedAt":"2014-11-12T00:40:13Z","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 acdedbd..ed32d63 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@@ -463,17 +444,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@@ -602,17 +586,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.0.0.rc4.501.gdaf83ca\n"},{"id":"251737","messageId":"1415752816-22782-8-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 7/9] builtin/notes: Add --allow-empty, to allow storing empty notes","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:14Z","receivedAt":"2014-11-12T00:40:14Z","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 ed32d63..a9f37d0 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@@ -445,7 +447,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@@ -540,6 +542,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@@ -560,6 +563,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@@ -602,7 +607,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.0.0.rc4.501.gdaf83ca\n"},{"id":"251740","messageId":"1415752816-22782-9-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 8/9] notes: Empty notes should be shown by 'git log'","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:15Z","receivedAt":"2014-11-12T00:40:15Z","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.0.0.rc4.501.gdaf83ca\n"},{"id":"251738","messageId":"1415752816-22782-10-git-send-email-johan@herland.net","threadId":"37935","inReplyTo":"1415752816-22782-1-git-send-email-johan@herland.net","subject":"[PATCHv5 9/9] t3301: Modernize","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T00:40:16Z","receivedAt":"2014-11-12T00:40:16Z","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_line_count\n    - test_config\n    - test_unconfig\n    - test_path_is_missing\n - Remove whitespace between redirection operators and their targets.\n - Move preparation of \"expect\" files into tests.\n - Rename \"output\" files to \"actual\".\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>\nImproved-by: Michael Blume <blume.mike@gmail.com>\nImproved-by: Jeff King <peff@peff.net>\nSigned-off-by: Johan Herland <johan@herland.net>\n---\n t/t3301-notes.sh | 1300 +++++++++++++++++++++++++-----------------------------\n 1 file changed, 601 insertions(+), 699 deletions(-)\n\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex 416ed9e..861c159 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,206 +44,186 @@ 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_cmp expect output\n+\ttest_write_lines A B >expect &&\n+\tgit show -s --format=\"A%n%NB\" >actual &&\n+\ttest_cmp expect actual\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+\tgit ls-tree -r refs/notes/commits >actual &&\n+\ttest_line_count = 1 actual\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_cmp expect output\n+\ttest_write_lines A b4 B >expect &&\n+\tgit show -s --format=\"A%n%NB\" >actual &&\n+\ttest_cmp expect actual\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-\tgit reflog show refs/notes/commits >output &&\n-\ttest_cmp expect output\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 >actual &&\n+\ttest_cmp expect actual\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+\tgit ls-tree -r refs/notes/commits >actual &&\n+\ttest_line_count = 1 actual\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+\tgit ls-tree -r refs/notes/commits >actual &&\n+\ttest_line_count = 1 actual\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+\tgit ls-tree -r refs/notes/commits >actual &&\n+\ttest_line_count = 1 actual\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+\tgit ls-tree -r refs/notes/commits >actual &&\n+\ttest_line_count = 1 actual\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+\tgit ls-tree -r refs/notes/commits >actual &&\n+\ttest_line_count = 1 actual\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-\n-    2nd\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-Notes:\n-    b1\n-EOF\n+\t\t${indent}2nd\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-\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+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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+test_expect_success 'show multi-line notes' '\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-Notes:\n-    b3\n-    c3c3c3c3\n-    d3d3d3\n-EOF\n+\t\t${indent}3rd\n \n-printf \"\\n\" >> expect-multiline\n-cat expect >> expect-multiline\n+\t\tNotes:\n+\t\t${indent}b3\n+\t\t${indent}c3c3c3c3\n+\t\t${indent}d3d3d3\n \n-test_expect_success 'show multi-line notes' '\n-\tgit log -2 > output &&\n-\ttest_cmp expect-multiline output\n+\tEOF\n+\tcat expect >>expect-multiline &&\n+\tgit log -2 >actual &&\n+\ttest_cmp expect-multiline actual\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+test_expect_success 'show -F notes' '\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-Notes:\n-    xyzzy\n-EOF\n+\t\t${indent}4th\n \n-printf \"\\n\" >> expect-F\n-cat expect-multiline >> expect-F\n+\t\tNotes:\n+\t\t${indent}xyzzy\n \n-test_expect_success 'show -F notes' '\n-\tgit log -3 > output &&\n-\ttest_cmp expect-F output\n+\tEOF\n+\tcat expect-multiline >>expect-F &&\n+\tgit log -3 >actual &&\n+\ttest_cmp expect-F actual\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-\ttest_cmp expect-F output\n+\tgit log -3 >actual &&\n+\ttest_cmp expect-F actual\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-\tgit log -1 --pretty=raw >output &&\n-\ttest_cmp expect output\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 >actual &&\n+\ttest_cmp expect actual\n '\n \n-cat >>expect <<EOF\n-\n-Notes:\n-    xyzzy\n-EOF\n test_expect_success 'git log --show-notes' '\n-\tgit log -1 --pretty=raw --show-notes >output &&\n-\ttest_cmp expect output\n+\tcat >>expect <<-EOF &&\n+\n+\tNotes:\n+\t${indent}xyzzy\n+\tEOF\n+\tgit log -1 --pretty=raw --show-notes >actual &&\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'git log --no-notes' '\n-\tgit log -1 --no-notes >output &&\n-\t! grep xyzzy output\n+\tgit log -1 --no-notes >actual &&\n+\t! grep xyzzy actual\n '\n \n test_expect_success 'git format-patch does not show notes' '\n-\tgit format-patch -1 --stdout >output &&\n-\t! grep xyzzy output\n+\tgit format-patch -1 --stdout >actual &&\n+\t! grep xyzzy actual\n '\n \n test_expect_success 'git format-patch --show-notes does show notes' '\n-\tgit format-patch --show-notes -1 --stdout >output &&\n-\tgrep xyzzy output\n+\tgit format-patch --show-notes -1 --stdout >actual &&\n+\tgrep xyzzy actual\n '\n \n for pretty in \\\n@@ -261,8 +235,8 @@ do\n \t?*) p=\"$pretty\" not=\" not\" negate=\"!\" ;;\n \tesac\n \ttest_expect_success \"git show $pretty does$not show notes\" '\n-\t\tgit show $p >output &&\n-\t\teval \"$negate grep xyzzy output\"\n+\t\tgit show $p >actual &&\n+\t\teval \"$negate grep xyzzy actual\"\n \t'\n done\n \n@@ -271,161 +245,131 @@ test_expect_success 'setup alternate notes ref' '\n '\n \n test_expect_success 'git log --notes shows default notes' '\n-\tgit log -1 --notes >output &&\n-\tgrep xyzzy output &&\n-\t! grep alternate output\n+\tgit log -1 --notes >actual &&\n+\tgrep xyzzy actual &&\n+\t! grep alternate actual\n '\n \n test_expect_success 'git log --notes=X shows only X' '\n-\tgit log -1 --notes=alternate >output &&\n-\t! grep xyzzy output &&\n-\tgrep alternate output\n+\tgit log -1 --notes=alternate >actual &&\n+\t! grep xyzzy actual &&\n+\tgrep alternate actual\n '\n \n test_expect_success 'git log --notes --notes=X shows both' '\n-\tgit log -1 --notes --notes=alternate >output &&\n-\tgrep xyzzy output &&\n-\tgrep alternate output\n+\tgit log -1 --notes --notes=alternate >actual &&\n+\tgrep xyzzy actual &&\n+\tgrep alternate actual\n '\n \n test_expect_success 'git log --no-notes resets default state' '\n \tgit log -1 --notes --notes=alternate \\\n \t\t--no-notes --notes=alternate \\\n-\t\t>output &&\n-\t! grep xyzzy output &&\n-\tgrep alternate output\n+\t\t>actual &&\n+\t! grep xyzzy actual &&\n+\tgrep alternate actual\n '\n \n test_expect_success 'git log --no-notes resets ref list' '\n \tgit log -1 --notes --notes=alternate \\\n \t\t--no-notes --notes \\\n-\t\t>output &&\n-\tgrep xyzzy output &&\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_cmp expect-m output\n+\t\t>actual &&\n+\tgrep xyzzy actual &&\n+\t! grep alternate actual\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-\n-printf \"\\n\" >> expect-rm-F\n-cat expect-F >> expect-rm-F\n-\n-test_expect_success 'verify note removal with -F /dev/null' '\n-\tgit log -4 > output &&\n-\ttest_cmp expect-rm-F output &&\n+test_expect_success 'show -m notes' '\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 >actual &&\n+\ttest_cmp expect-m actual\n+'\n+\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+\t\t${indent}5th\n+\n+\tEOF\n+\tcat expect-F >>expect-rm-F &&\n+\tgit log -4 >actual &&\n+\ttest_cmp expect-rm-F actual &&\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-\ttest_cmp expect-rm-F output &&\n+test_expect_success 'do not create empty note with -m \"\"' '\n+\tgit notes add -m \"\" &&\n+\tgit log -4 >actual &&\n+\ttest_cmp expect-rm-F actual &&\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-\ttest_cmp expect-combine_m_and_F output\n+\tgit notes show >actual &&\n+\ttest_cmp expect-combine_m_and_F actual\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+\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-commit 15023535574ded8b1a89052b32673f84cf9582b8\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:16:13 2005 -0700\n+\t\t${indent}4th\n \n-    4th\n-EOF\n-\n-printf \"\\n\" >> expect-rm-remove\n-cat expect-multiline >> expect-rm-remove\n-\n-test_expect_success 'verify note removal with \"git notes remove\"' '\n-\tgit log -4 > output &&\n-\ttest_cmp expect-rm-remove output &&\n+\tEOF\n+\tcat expect-multiline >>expect-rm-remove &&\n+\tgit log -4 >actual &&\n+\ttest_cmp expect-rm-remove actual &&\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,70 +449,68 @@ 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-\ttest_cmp expect output\n+\tcat >expect <<-EOF &&\n+\t\tc9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691\n+\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290\n+\tEOF\n+\tgit notes list >actual &&\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'list notes with \"git notes\"' '\n-\tgit notes > output &&\n-\ttest_cmp expect output\n+\tgit notes >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tcat >expect <<-EOF &&\n+\t\tc18dc024e14f08d18d14eea0d747ff692d66d6a3\n+\tEOF\n+\tgit notes list HEAD^^ >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tcat >expect <<-EOF &&\n+\tEOF\n+\ttest_must_fail git notes list HEAD >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit notes show >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect_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 >actual &&\n+\ttest_cmp expect_list actual\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-\ttest_cmp expect output\n+\tgit notes show >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit notes append -m \"Initial set of notes${LF}${LF}More notes appended with git notes append\" &&\n+\tgit notes show >actual &&\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'appending empty string to non-existing note does not create note' '\n@@ -579,229 +521,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-\ttest_cmp expect-not-other output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect-not-other actual\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-\ttest_cmp expect-other output\n+\tGIT_NOTES_REF=\"refs/notes/other\" git log -1 >actual &&\n+\ttest_cmp expect-other actual\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_cmp expect-other output\n+\ttest_config core.notesRef \"refs/notes/other\" &&\n+\tgit log -1 >actual &&\n+\ttest_cmp expect-other actual\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_cmp expect-not-other output\n+\ttest_config core.notesRef \"refs/notes/other\" &&\n+\tGIT_NOTES_REF=\"refs/notes/wrong\" git log -1 >actual &&\n+\ttest_cmp expect-not-other actual\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_cmp expect-both output\n+\ttest_unconfig core.notesRef &&\n+\ttest_config notes.displayRef \"refs/notes/*\" &&\n+\tgit log -2 >actual &&\n+\ttest_cmp expect-both actual\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_cmp expect-both output\n+\ttest_config core.notesRef refs/notes/commits &&\n+\ttest_config notes.displayRef refs/notes/other &&\n+\tgit log -2 >actual &&\n+\ttest_cmp expect-both actual\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-\ttest_cmp expect-both output\n+\tgit log -2 >actual &&\n+\ttest_cmp expect-both actual\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+test_expect_success 'notes.displayRef respects order' '\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-Notes (other):\n-    other note\n+\t\t${indent}6th\n \n-Notes:\n-    order test\n-EOF\n+\t\tNotes (other):\n+\t\t${indent}other note\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-\ttest_cmp expect-both-reversed output\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 >actual &&\n+\ttest_cmp expect-both-reversed actual\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-\ttest_cmp expect-both output\n+\t\tgit log -2 >actual &&\n+\ttest_cmp expect-both actual\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-\n-    6th\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-commit bd1753200303d0a0344be813e504253b3d98e74d\n-Author: A U Thor <author@example.com>\n-Date:   Thu Apr 7 15:17:13 2005 -0700\n+\t\t${indent}6th\n \n-    5th\n-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-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-\ttest_cmp expect-none 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 >actual &&\n+\ttest_cmp expect-none actual\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-\ttest_cmp expect-both output\n+\tGIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 >actual &&\n+\ttest_cmp expect-both actual\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-\ttest_cmp expect-commits output\n+\t\tNotes:\n+\t\t${indent}order test\n+\tEOF\n+\tgit log --no-standard-notes --show-notes=commits -1 >actual &&\n+\ttest_cmp expect-commits actual\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-\ttest_cmp expect-both output\n+\t\t--standard-notes -2 >actual &&\n+\ttest_cmp expect-both actual\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-\ttest_cmp expect-both-reversed output\n+\t\t --no-standard-notes -1 >actual &&\n+\ttest_cmp expect-both-reversed actual\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-\n-    7th\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-Notes (other):\n-    other note\n-EOF\n+\t\t${indent}7th\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,405 +735,386 @@ 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-\n-    8th\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-Notes (other):\n-    This is a blob object\n-EOF\n+\t\t${indent}8th\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+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-    9th\n+\t\t${indent}9th\n \n-Notes (other):\n-    yet another note\n-EOF\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-\ttest_cmp expect output &&\n+\tgit log -2 >actual &&\n+\ttest_cmp expect actual &&\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-\ttest_cmp expect output\n+\tgit log -2 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -2 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -2 >actual &&\n+\ttest_cmp expect actual\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+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-    15th\n+\t\t${indent}15th\n \n-Notes (other):\n-    a fresh note\n-EOF\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\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-\ttest_cmp expect output\n+\tgit log -1 >actual &&\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'git notes copy diagnoses too many or too few parameters' '\n@@ -1221,13 +1123,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 +1179,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.0.0.rc4.501.gdaf83ca\n"},{"id":"251743","messageId":"CAPig+cSVtAi-n4EKaOgNwDqLvajzvozRG5_o3XjfZAMzW8T8-g@mail.gmail.com","threadId":"37935","inReplyTo":"1415752816-22782-10-git-send-email-johan@herland.net","subject":"Re: [PATCHv5 9/9] t3301: Modernize","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-11-12T01:57:41Z","receivedAt":"2014-11-12T01:57:41Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Nov 11, 2014 at 7:40 PM, Johan Herland <johan@herland.net> wrote:\n> Make this test script appear somewhat less old-fashioned:\n> Signed-off-by: Johan Herland <johan@herland.net>\n> ---\n> diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\n> index 416ed9e..861c159 100755\n> --- a/t/t3301-notes.sh\n> +++ b/t/t3301-notes.sh\n> @@ -50,206 +44,186 @@ test_expect_success 'handle empty notes gracefully' '\n>  '\n>\n>  test_expect_success 'create notes' '\n> -       git config core.notesRef refs/notes/commits &&\n>         MSG=b4 git notes add &&\n> -       test ! -f .git/NOTES_EDITMSG &&\n> -       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -       test b4 = $(git notes show) &&\n> +       test_path_is_missing .git/NOTES_EDITMSG &&\n> +       git ls-tree -r refs/notes/commits >actual &&\n> +       test_line_count = 1 actual\n\nBroken &&-chain. This problem is repeated each place use invoke\ntest_line_count().\n\n> +       test \"b4\" = \"$(git notes show)\" &&\n>         git show HEAD^ &&\n>         test_must_fail git notes show HEAD^\n>  '\n>\n>  test_expect_success 'show notes entry with %N' '\n> -       for l in A b4 B\n> -       do\n> -               echo \"$l\"\n> -       done >expect &&\n> -       git show -s --format='A%n%NB' >output &&\n> -       test_cmp expect output\n> +       test_write_lines A b4 B >expect &&\n> +       git show -s --format=\"A%n%NB\" >actual &&\n> +       test_cmp expect actual\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> -       git reflog show refs/notes/commits >output &&\n> -       test_cmp expect output\n> +       cat <<-EOF >expect &&\n> +               a1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\"'\"'git notes add'\"'\"'\n> +       EOF\n> +       git reflog show refs/notes/commits >actual &&\n> +       test_cmp expect actual\n>  '\n>\n>  test_expect_success 'edit existing notes' '\n>         MSG=b3 git notes edit &&\n> -       test ! -f .git/NOTES_EDITMSG &&\n> -       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -       test b3 = $(git notes show) &&\n> +       test_path_is_missing .git/NOTES_EDITMSG &&\n> +       git ls-tree -r refs/notes/commits >actual &&\n> +       test_line_count = 1 actual\n> +       test \"b3\" = \"$(git notes show)\" &&\n>         git show HEAD^ &&\n>         test_must_fail git notes show HEAD^\n>  '\n>\n>  test_expect_success 'cannot \"git notes add -m\" where notes already exists' '\n>         test_must_fail git notes add -m \"b2\" &&\n> -       test ! -f .git/NOTES_EDITMSG &&\n> -       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -       test b3 = $(git notes show) &&\n> +       test_path_is_missing .git/NOTES_EDITMSG &&\n> +       git ls-tree -r refs/notes/commits >actual &&\n> +       test_line_count = 1 actual\n> +       test \"b3\" = \"$(git notes show)\" &&\n>         git show HEAD^ &&\n>         test_must_fail git notes show HEAD^\n>  '\n>\n>  test_expect_success 'can overwrite existing note with \"git notes add -f -m\"' '\n>         git notes add -f -m \"b1\" &&\n> -       test ! -f .git/NOTES_EDITMSG &&\n> -       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -       test b1 = $(git notes show) &&\n> +       test_path_is_missing .git/NOTES_EDITMSG &&\n> +       git ls-tree -r refs/notes/commits >actual &&\n> +       test_line_count = 1 actual\n> +       test \"b1\" = \"$(git notes show)\" &&\n>         git show HEAD^ &&\n>         test_must_fail git notes show HEAD^\n>  '\n>\n>  test_expect_success 'add w/no options on existing note morphs into edit' '\n>         MSG=b2 git notes add &&\n> -       test ! -f .git/NOTES_EDITMSG &&\n> -       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -       test b2 = $(git notes show) &&\n> +       test_path_is_missing .git/NOTES_EDITMSG &&\n> +       git ls-tree -r refs/notes/commits >actual &&\n> +       test_line_count = 1 actual\n> +       test \"b2\" = \"$(git notes show)\" &&\n>         git show HEAD^ &&\n>         test_must_fail git notes show HEAD^\n>  '\n>\n>  test_expect_success 'can overwrite existing note with \"git notes add -f\"' '\n>         MSG=b1 git notes add -f &&\n> -       test ! -f .git/NOTES_EDITMSG &&\n> -       test 1 = $(git ls-tree refs/notes/commits | wc -l) &&\n> -       test b1 = $(git notes show) &&\n> +       test_path_is_missing .git/NOTES_EDITMSG &&\n> +       git ls-tree -r refs/notes/commits >actual &&\n> +       test_line_count = 1 actual\n> +       test \"b1\" = \"$(git notes show)\" &&\n>         git show HEAD^ &&\n>         test_must_fail git notes show HEAD^\n>  '\n"},{"id":"251747","messageId":"CALKQrgd-XzAhyZCADmQbCuUL6bdr1nrY8XACBb7UbEv9c=X3dQ@mail.gmail.com","threadId":"37935","inReplyTo":"CAPig+cSVtAi-n4EKaOgNwDqLvajzvozRG5_o3XjfZAMzW8T8-g@mail.gmail.com","subject":"Re: [PATCHv5 9/9] t3301: Modernize","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T09:08:02Z","receivedAt":"2014-11-12T09:08:02Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Wed, Nov 12, 2014 at 2:57 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Tue, Nov 11, 2014 at 7:40 PM, Johan Herland <johan@herland.net> wrote:\n>> +       test_line_count = 1 actual\n>\n> Broken &&-chain. This problem is repeated each place use invoke\n> test_line_count().\n\nThanks. Fixed in the next iteration.\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"251776","messageId":"xmqq389o3yop.fsf@gitster.dls.corp.google.com","threadId":"37935","inReplyTo":"CALKQrgd-XzAhyZCADmQbCuUL6bdr1nrY8XACBb7UbEv9c=X3dQ@mail.gmail.com","subject":"Re: [PATCHv5 9/9] t3301: Modernize","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-12T21:18:30Z","receivedAt":"2014-11-12T21:18:30Z","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 Wed, Nov 12, 2014 at 2:57 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> On Tue, Nov 11, 2014 at 7:40 PM, Johan Herland <johan@herland.net> wrote:\n>>> +       test_line_count = 1 actual\n>>\n>> Broken &&-chain. This problem is repeated each place use invoke\n>> test_line_count().\n>\n> Thanks. Fixed in the next iteration.\n>\n> ...Johan\n\nJust FYI, here is what I came up with on top of 9/9 as 10/9, and it\ncan be squashed in.  If these will be the only differences between\nv5 and upcoming v6, you can just tell me to squash them together.\n\nOne unrelated changes is that '\\'' is a bit shorter than '\"'\"' (and\nthe four-letter sequence is idiomatic and easier to spot, once your\neyes are used to reading strings in single-quote pairs).\n\nThanks.\n\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex 861c159..245406a 100755\n--- a/t/t3301-notes.sh\n+++ b/t/t3301-notes.sh\n@@ -53,7 +53,7 @@ test_expect_success 'create notes' '\n \tMSG=b4 git notes add &&\n \ttest_path_is_missing .git/NOTES_EDITMSG &&\n \tgit ls-tree -r refs/notes/commits >actual &&\n-\ttest_line_count = 1 actual\n+\ttest_line_count = 1 actual &&\n \ttest \"b4\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n@@ -67,7 +67,7 @@ test_expect_success 'show notes entry with %N' '\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+\t\ta1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\\''git notes add'\\''\n \tEOF\n \tgit reflog show refs/notes/commits >actual &&\n \ttest_cmp expect actual\n@@ -77,7 +77,7 @@ test_expect_success 'edit existing notes' '\n \tMSG=b3 git notes edit &&\n \ttest_path_is_missing .git/NOTES_EDITMSG &&\n \tgit ls-tree -r refs/notes/commits >actual &&\n-\ttest_line_count = 1 actual\n+\ttest_line_count = 1 actual &&\n \ttest \"b3\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n@@ -87,7 +87,7 @@ test_expect_success 'cannot \"git notes add -m\" where notes already exists' '\n \ttest_must_fail git notes add -m \"b2\" &&\n \ttest_path_is_missing .git/NOTES_EDITMSG &&\n \tgit ls-tree -r refs/notes/commits >actual &&\n-\ttest_line_count = 1 actual\n+\ttest_line_count = 1 actual &&\n \ttest \"b3\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n@@ -97,7 +97,7 @@ test_expect_success 'can overwrite existing note with \"git notes add -f -m\"' '\n \tgit notes add -f -m \"b1\" &&\n \ttest_path_is_missing .git/NOTES_EDITMSG &&\n \tgit ls-tree -r refs/notes/commits >actual &&\n-\ttest_line_count = 1 actual\n+\ttest_line_count = 1 actual &&\n \ttest \"b1\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n@@ -107,7 +107,7 @@ test_expect_success 'add w/no options on existing note morphs into edit' '\n \tMSG=b2 git notes add &&\n \ttest_path_is_missing .git/NOTES_EDITMSG &&\n \tgit ls-tree -r refs/notes/commits >actual &&\n-\ttest_line_count = 1 actual\n+\ttest_line_count = 1 actual &&\n \ttest \"b2\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n@@ -117,7 +117,7 @@ test_expect_success 'can overwrite existing note with \"git notes add -f\"' '\n \tMSG=b1 git notes add -f &&\n \ttest_path_is_missing .git/NOTES_EDITMSG &&\n \tgit ls-tree -r refs/notes/commits >actual &&\n-\ttest_line_count = 1 actual\n+\ttest_line_count = 1 actual &&\n \ttest \"b1\" = \"$(git notes show)\" &&\n \tgit show HEAD^ &&\n \ttest_must_fail git notes show HEAD^\n-- \n2.2.0-rc1-84-gcd6439f\n"},{"id":"251783","messageId":"CALKQrge2FM79XQy14jEYQBY+DwQ9xpcC-yMmKk1kE-yJixzJVw@mail.gmail.com","threadId":"37935","inReplyTo":"xmqq389o3yop.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCHv5 9/9] t3301: Modernize","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-12T23:43:41Z","receivedAt":"2014-11-12T23:43:41Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Wed, Nov 12, 2014 at 10:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Johan Herland <johan@herland.net> writes:\n>> On Wed, Nov 12, 2014 at 2:57 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>> On Tue, Nov 11, 2014 at 7:40 PM, Johan Herland <johan@herland.net> wrote:\n>>>> +       test_line_count = 1 actual\n>>>\n>>> Broken &&-chain. This problem is repeated each place use invoke\n>>> test_line_count().\n>>\n>> Thanks. Fixed in the next iteration.\n>\n> Just FYI, here is what I came up with on top of 9/9 as 10/9, and it\n> can be squashed in.  If these will be the only differences between\n> v5 and upcoming v6, you can just tell me to squash them together.\n\nSo far this is the only diff on top of v5. I've squashed it into my\ntree, so if a re-roll is needed, this diff will also be part of it.\nBut if no other issues show up to trigger a re-roll, then please\nsquash them on your end as well.\n\n> One unrelated changes is that '\\'' is a bit shorter than '\"'\"' (and\n> the four-letter sequence is idiomatic and easier to spot, once your\n> eyes are used to reading strings in single-quote pairs).\n\nAgreed, thanks.\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"}]}