notes: disallow reusing non-blob as a note object
authorJohan Herland <johan@herland.net>
Wed, 12 Feb 2014 09:54:16 +0000 (10:54 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 20 Feb 2014 22:14:33 +0000 (14:14 -0800)
Currently "git notes add -C $object" will read the raw bytes from $object,
and then copy those bytes into the note object, which is hardcoded to be
of type blob. This means that if the given $object is a non-blob (e.g.
tree or commit), the raw bytes from that object is copied into a blob
object. This is probably not useful, and certainly not what any sane
user would expect. So disallow it, by erroring out if the $object passed
to the -C option is not a blob.

The fix also applies to the -c option (in which the user is prompted to
edit/verify the note contents in a text editor), and also when -c/-C is
passed to "git notes append" (which appends the $object contents to an
existing note object). In both cases, passing a non-blob $object does not
make sense.

Also add a couple of tests demonstrating expected behavior.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/notes.c
t/t3301-notes.sh
index e4100c49820306b881a20db4bb3af7c13f12c019..c11d6e6dc82c3d52329c04a848bf6f02c2768854 100644 (file)
@@ -269,7 +269,11 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
                die(_("Failed to resolve '%s' as a valid ref."), arg);
        if (!(buf = read_sha1_file(object, &type, &len)) || !len) {
                free(buf);
-               die(_("Failed to read object '%s'."), arg);;
+               die(_("Failed to read object '%s'."), arg);
+       }
+       if (type != OBJ_BLOB) {
+               free(buf);
+               die(_("Cannot read note data from non-blob object '%s'."), arg);
        }
        strbuf_add(&(msg->buf), buf, len);
        free(buf);
index 16de05aff941c73b3e5f5371bd4739959f679efa..3bb79a47af5e2f619753c61436ec577ec025a8ae 100755 (executable)
@@ -812,6 +812,33 @@ test_expect_success 'create note from non-existing note with "git notes add -C"
        test_must_fail git notes list HEAD
 '
 
+test_expect_success 'create note from non-blob with "git notes add -C" fails' '
+       commit=$(git rev-parse --verify HEAD) &&
+       tree=$(git rev-parse --verify HEAD:) &&
+       test_must_fail git notes add -C $commit &&
+       test_must_fail git notes add -C $tree &&
+       test_must_fail git notes list HEAD
+'
+
+cat > expect << EOF
+commit 80d796defacd5db327b7a4e50099663902fbdc5c
+Author: A U Thor <author@example.com>
+Date:   Thu Apr 7 15:20:13 2005 -0700
+
+    8th
+
+Notes (other):
+    This is a blob object
+EOF
+
+test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
+       blob=$(echo "This is a blob object" | git hash-object -w --stdin) &&
+       git notes add -C $blob &&
+       git log -1 > actual &&
+       test_cmp expect actual &&
+       test "$(git notes list HEAD)" = "$blob"
+'
+
 cat > expect << EOF
 commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b
 Author: A U Thor <author@example.com>