git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johan Herland <johan@herland.net>
To: gitster@pobox.com
Cc: git@vger.kernel.org, mackyle@gmail.com, jhf@trifork.com,
	sunshine@sunshineco.com, Johan Herland <johan@herland.net>
Subject: [PATCHv4 7/9] builtin/notes: Add --allow-empty, to allow storing empty notes
Date: Sun,  9 Nov 2014 13:30:53 +0100	[thread overview]
Message-ID: <1415536255-19961-8-git-send-email-johan@herland.net> (raw)
In-Reply-To: <1415536255-19961-1-git-send-email-johan@herland.net>

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>
---
 Documentation/git-notes.txt | 12 ++++++++----
 builtin/notes.c             | 17 +++++++++++------
 t/t3301-notes.sh            | 10 +++++++++-
 3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index 310f0a5..851518d 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -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`
diff --git a/builtin/notes.c b/builtin/notes.c
index 7017434..4605210 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -22,10 +22,10 @@
 
 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()
 	};
@@ -444,7 +446,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");
@@ -539,6 +541,7 @@ out:
 
 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];
@@ -559,6 +562,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");
@@ -601,7 +606,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");
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index f74b3fa..70ec5c3 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -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
-- 
2.1.1.392.g062cc5d

  parent reply	other threads:[~2014-11-09 12:31 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-09 12:30 [PATCHv4 0/9] Handling empty notes Johan Herland
2014-11-09 12:30 ` [PATCHv4 1/9] builtin/notes: Fix premature failure when trying to add the empty blob Johan Herland
2014-11-09 12:30 ` [PATCHv4 2/9] t3301: Verify that 'git notes' removes empty notes by default Johan Herland
2014-11-09 12:30 ` [PATCHv4 3/9] builtin/notes: Improve naming Johan Herland
2014-11-09 12:30 ` [PATCHv4 4/9] builtin/notes: Refactor note file path into struct note_data Johan Herland
2014-11-09 12:30 ` [PATCHv4 5/9] builtin/notes: Simplify early exit code in add() Johan Herland
2014-11-10 20:36   ` Junio C Hamano
2014-11-11  0:49     ` Johan Herland
2014-11-11 15:53       ` Junio C Hamano
2014-11-09 12:30 ` [PATCHv4 6/9] builtin/notes: Split create_note() to clarify add vs. remove logic Johan Herland
2014-11-09 12:30 ` Johan Herland [this message]
2014-11-09 12:30 ` [PATCHv4 8/9] notes: Empty notes should be shown by 'git log' Johan Herland
2014-11-09 12:30 ` [PATCHv4 9/9] t3301: Modernize Johan Herland
2014-11-10 20:42   ` Junio C Hamano
2014-11-11  1:04     ` Johan Herland
2014-11-11  1:07       ` Eric Sunshine
2014-11-11  1:50         ` Johan Herland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1415536255-19961-8-git-send-email-johan@herland.net \
    --to=johan@herland.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jhf@trifork.com \
    --cc=mackyle@gmail.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).