builtin/notes: add --allow-empty, to allow storing empty notes
authorJohan Herland <johan@herland.net>
Wed, 12 Nov 2014 00:40:14 +0000 (01:40 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 12 Nov 2014 19:00:11 +0000 (11:00 -0800)
Although the "git notes" man page advertises that we support binary-safe
notes addition (using the -C option), we currently do not support adding
the empty note (i.e. using the empty blob to annotate an object). Instead,
an empty note is always treated as an intent to remove the note
altogether.

Introduce the --allow-empty option to the add/append/edit subcommands,
to explicitly allow an empty note to be stored into the notes tree.

Also update the documentation, and add test cases for the new option.

Reported-by: James H. Fisher <jhf@trifork.com>
Improved-by: Kyle J. McKay <mackyle@gmail.com>
Improved-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-notes.txt
builtin/notes.c
t/t3301-notes.sh
index 310f0a5e8c1819f1f49e00b78aacface36ac21ad..851518d531b53966dc6dca1321c71e8381f50e7b 100644 (file)
@@ -9,10 +9,10 @@ SYNOPSIS
 --------
 [verse]
 'git notes' [list [<object>]]
-'git notes' add [-f] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
+'git notes' add [-f] [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
 'git notes' copy [-f] ( --stdin | <from-object> <to-object> )
-'git notes' append [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
-'git notes' edit [<object>]
+'git notes' append [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
+'git notes' edit [--allow-empty] [<object>]
 'git notes' show [<object>]
 'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref>
 'git notes' merge --commit [-v | -q]
@@ -155,6 +155,10 @@ OPTIONS
        Like '-C', but with '-c' the editor is invoked, so that
        the user can further edit the note message.
 
+--allow-empty::
+       Allow an empty note object to be stored. The default behavior is
+       to automatically remove empty notes.
+
 --ref <ref>::
        Manipulate the notes tree in <ref>.  This overrides
        'GIT_NOTES_REF' and the "core.notesRef" configuration.  The ref
@@ -287,7 +291,7 @@ arbitrary files using 'git hash-object':
 ------------
 $ cc *.c
 $ blob=$(git hash-object -w a.out)
-$ git notes --ref=built add -C "$blob" HEAD
+$ git notes --ref=built add --allow-empty -C "$blob" HEAD
 ------------
 
 (You cannot simply use `git notes --ref=built add -F a.out HEAD`
index ed32d634fcb546a681afd65ec657cc1603770636..a9f37d045641236ee910f3eb22be6ac8d04e386a 100644 (file)
 
 static const char * const git_notes_usage[] = {
        N_("git notes [--ref <notes_ref>] [list [<object>]]"),
-       N_("git notes [--ref <notes_ref>] add [-f] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+       N_("git notes [--ref <notes_ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
        N_("git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>"),
-       N_("git notes [--ref <notes_ref>] append [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
-       N_("git notes [--ref <notes_ref>] edit [<object>]"),
+       N_("git notes [--ref <notes_ref>] append [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+       N_("git notes [--ref <notes_ref>] edit [--allow-empty] [<object>]"),
        N_("git notes [--ref <notes_ref>] show [<object>]"),
        N_("git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>"),
        N_("git notes merge --commit [-v | -q]"),
@@ -381,7 +381,7 @@ static int append_edit(int argc, const char **argv, const char *prefix);
 
 static int add(int argc, const char **argv, const char *prefix)
 {
-       int force = 0;
+       int force = 0, allow_empty = 0;
        const char *object_ref;
        struct notes_tree *t;
        unsigned char object[20], new_note[20];
@@ -400,6 +400,8 @@ static int add(int argc, const char **argv, const char *prefix)
                { OPTION_CALLBACK, 'C', "reuse-message", &d, N_("object"),
                        N_("reuse specified note object"), PARSE_OPT_NONEG,
                        parse_reuse_arg},
+               OPT_BOOL(0, "allow-empty", &allow_empty,
+                       N_("allow storing empty note")),
                OPT__FORCE(&force, N_("replace existing notes")),
                OPT_END()
        };
@@ -445,7 +447,7 @@ static int add(int argc, const char **argv, const char *prefix)
        }
 
        prepare_note_data(object, &d, note);
-       if (d.buf.len) {
+       if (d.buf.len || allow_empty) {
                write_note_data(&d, new_note);
                if (add_note(t, object, new_note, combine_notes_overwrite))
                        die("BUG: combine_notes_overwrite failed");
@@ -540,6 +542,7 @@ static int copy(int argc, const char **argv, const char *prefix)
 
 static int append_edit(int argc, const char **argv, const char *prefix)
 {
+       int allow_empty = 0;
        const char *object_ref;
        struct notes_tree *t;
        unsigned char object[20], new_note[20];
@@ -560,6 +563,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)
                { OPTION_CALLBACK, 'C', "reuse-message", &d, N_("object"),
                        N_("reuse specified note object"), PARSE_OPT_NONEG,
                        parse_reuse_arg},
+               OPT_BOOL(0, "allow-empty", &allow_empty,
+                       N_("allow storing empty note")),
                OPT_END()
        };
        int edit = !strcmp(argv[0], "edit");
@@ -602,7 +607,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
                free(prev_buf);
        }
 
-       if (d.buf.len) {
+       if (d.buf.len || allow_empty) {
                write_note_data(&d, new_note);
                if (add_note(t, object, new_note, combine_notes_overwrite))
                        die("BUG: combine_notes_overwrite failed");
index f74b3fa335235e61d91e7e2fb2947b637a9b425c..70ec5c395f861bf392ad91d7c9929337048500c8 100755 (executable)
@@ -1242,7 +1242,8 @@ test_expect_success 'git notes get-ref (--ref)' '
 test_expect_success 'setup testing of empty notes' '
        test_unconfig core.notesRef &&
        test_commit 16th &&
-       empty_blob=$(git hash-object -w /dev/null)
+       empty_blob=$(git hash-object -w /dev/null) &&
+       echo "$empty_blob" >expect_empty
 '
 
 while read cmd
@@ -1252,6 +1253,13 @@ do
                MSG= git notes $cmd &&
                test_must_fail git notes list HEAD
        "
+
+       test_expect_success "'git notes $cmd --allow-empty' stores empty note" "
+               test_might_fail git notes remove HEAD &&
+               MSG= git notes $cmd --allow-empty &&
+               git notes list HEAD >actual &&
+               test_cmp expect_empty actual
+       "
 done <<\EOF
 add
 add -F /dev/null