From: Johan Herland <johan@herland.net>
To: gitster@pobox.com
Cc: git@vger.kernel.org, johan@herland.net
Subject: [PATCHv13 28/30] builtin-notes: Add -c/-C options for reusing notes
Date: Sat, 13 Feb 2010 22:28:36 +0100 [thread overview]
Message-ID: <1266096518-2104-29-git-send-email-johan@herland.net> (raw)
In-Reply-To: <1266096518-2104-1-git-send-email-johan@herland.net>
Inspired by the -c/-C options to "git commit", we teach these options to
"git notes add/append" to allow reuse of note objects.
With this patch in place, it is now easy to copy or move notes between
objects. For example, to copy object A's notes to object B:
git notes add [-f] -C $(git notes list A) B
To move instead of copying, you simply remove the notes from the source
object afterwards, e.g.:
git notes remove A
The patch includes tests verifying correct behaviour of the new functionality.
Signed-off-by: Johan Herland <johan@herland.net>
---
Documentation/git-notes.txt | 12 ++++-
builtin-notes.c | 63 +++++++++++++++++++----
t/t3301-notes.sh | 116 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 179 insertions(+), 12 deletions(-)
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index 53c5d90..15de4b3 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -9,8 +9,8 @@ SYNOPSIS
--------
[verse]
'git notes' [list [<object>]]
-'git notes' add [-f] [-F <file> | -m <msg>] [<object>]
-'git notes' append [-F <file> | -m <msg>] [<object>]
+'git notes' add [-f] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
+'git notes' append [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' edit [<object>]
'git notes' show [<object>]
'git notes' remove [<object>]
@@ -84,6 +84,14 @@ OPTIONS
Take the note message from the given file. Use '-' to
read the note message from the standard input.
+-C <object>::
+--reuse-message=<object>::
+ Reuse the note message from the given note object.
+
+-c <object>::
+--reedit-message=<object>::
+ Like '-C', but with '-c' the editor is invoked, so that
+ the user can further edit the note message.
Author
------
diff --git a/builtin-notes.c b/builtin-notes.c
index 190c46c..98de115 100644
--- a/builtin-notes.c
+++ b/builtin-notes.c
@@ -19,8 +19,8 @@
static const char * const git_notes_usage[] = {
"git notes [list [<object>]]",
- "git notes add [-f] [-m <msg> | -F <file>] [<object>]",
- "git notes append [-m <msg> | -F <file>] [<object>]",
+ "git notes add [-f] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]",
+ "git notes append [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]",
"git notes edit [<object>]",
"git notes show [<object>]",
"git notes remove [<object>]",
@@ -36,6 +36,7 @@ static const char note_template[] =
struct msg_arg {
int given;
+ int use_editor;
struct strbuf buf;
};
@@ -104,7 +105,7 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,
{
char *path = NULL;
- if (!msg->given) {
+ if (msg->use_editor || !msg->given) {
int fd;
/* write the template message before editing: */
@@ -113,13 +114,16 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,
if (fd < 0)
die_errno("could not create file '%s'", path);
- if (prev && !append_only)
+ if (msg->given)
+ write_or_die(fd, msg->buf.buf, msg->buf.len);
+ else if (prev && !append_only)
write_note_data(fd, prev);
write_or_die(fd, note_template, strlen(note_template));
write_commented_object(fd, object);
close(fd);
+ strbuf_reset(&(msg->buf));
if (launch_editor(path, &(msg->buf), NULL)) {
die("Please supply the note contents using either -m" \
@@ -199,6 +203,40 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset)
return 0;
}
+static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
+{
+ struct msg_arg *msg = opt->value;
+ char *buf;
+ unsigned char object[20];
+ enum object_type type;
+ unsigned long len;
+
+ if (!arg)
+ return -1;
+
+ if (msg->buf.len)
+ strbuf_addstr(&(msg->buf), "\n");
+
+ if (get_sha1(arg, object))
+ 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);;
+ }
+ strbuf_add(&(msg->buf), buf, len);
+ free(buf);
+
+ msg->given = 1;
+ return 0;
+}
+
+static int parse_reedit_arg(const struct option *opt, const char *arg, int unset)
+{
+ struct msg_arg *msg = opt->value;
+ msg->use_editor = 1;
+ return parse_reuse_arg(opt, arg, unset);
+}
+
int commit_notes(struct notes_tree *t, const char *msg)
{
struct commit_list *parent;
@@ -250,13 +288,17 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
int list = 0, add = 0, append = 0, edit = 0, show = 0, remove = 0,
prune = 0, force = 0;
int given_object;
- struct msg_arg msg = { 0, STRBUF_INIT };
+ struct msg_arg msg = { 0, 0, STRBUF_INIT };
struct option options[] = {
OPT_GROUP("Notes options"),
OPT_CALLBACK('m', "message", &msg, "MSG",
"note contents as a string", parse_msg_arg),
OPT_CALLBACK('F', "file", &msg, "FILE",
"note contents in a file", parse_file_arg),
+ OPT_CALLBACK('c', "reedit-message", &msg, "OBJECT",
+ "reuse and edit specified note object", parse_reedit_arg),
+ OPT_CALLBACK('C', "reuse-message", &msg, "OBJECT",
+ "reuse specified note object", parse_reuse_arg),
OPT_BOOLEAN('f', "force", &force, "replace existing notes"),
OPT_END()
};
@@ -286,17 +328,17 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
usage_with_options(git_notes_usage, options);
if (msg.given && !(add || append || edit)) {
- error("cannot use -m/-F options with %s subcommand.", argv[0]);
+ error("cannot use -m/-F/-c/-C options with %s subcommand.",
+ argv[0]);
usage_with_options(git_notes_usage, options);
}
if (msg.given && edit) {
- fprintf(stderr, "The -m and -F options has been deprecated for"
- " the 'edit' subcommand.\n"
- "Please use 'git notes add -f -m/-F' instead.\n");
+ fprintf(stderr, "The -m/-F/-c/-C options have been deprecated "
+ "for the 'edit' subcommand.\n"
+ "Please use 'git notes add -f -m/-F/-c/-C' instead.\n");
}
-
if (force && !add) {
error("cannot use -f option with %s subcommand.", argv[0]);
usage_with_options(git_notes_usage, options);
@@ -359,6 +401,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
if (remove) {
msg.given = 1;
+ msg.use_editor = 0;
strbuf_reset(&(msg.buf));
}
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 07090e3..6447e5f 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -465,4 +465,120 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
test_cmp expect actual
'
+cat > expect << EOF
+commit 2ede89468182a62d0bde2583c736089bcf7d7e92
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:19:13 2005 -0700
+
+ 7th
+
+Notes:
+ other note
+EOF
+
+test_expect_success 'create note from other note with "git notes add -C"' '
+ : > a7 &&
+ git add a7 &&
+ test_tick &&
+ git commit -m 7th &&
+ git notes add -C $(git notes list HEAD^) &&
+ git log -1 > actual &&
+ test_cmp expect actual &&
+ test "$(git notes list HEAD)" = "$(git notes list HEAD^)"
+'
+
+test_expect_success 'create note from non-existing note with "git notes add -C" fails' '
+ : > a8 &&
+ git add a8 &&
+ test_tick &&
+ git commit -m 8th &&
+ test_must_fail git notes add -C deadbeef &&
+ test_must_fail git notes list HEAD
+'
+
+cat > expect << EOF
+commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:21:13 2005 -0700
+
+ 9th
+
+Notes:
+ yet another note
+EOF
+
+test_expect_success 'create note from other note with "git notes add -c"' '
+ : > a9 &&
+ git add a9 &&
+ test_tick &&
+ git commit -m 9th &&
+ MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
+ git log -1 > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'create note from non-existing note with "git notes add -c" fails' '
+ : > a10 &&
+ git add a10 &&
+ test_tick &&
+ git commit -m 10th &&
+ test_must_fail MSG="yet another note" git notes add -c deadbeef &&
+ test_must_fail git notes list HEAD
+'
+
+cat > expect << EOF
+commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:21:13 2005 -0700
+
+ 9th
+
+Notes:
+ yet another note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'append to note from other note with "git notes append -C"' '
+ git notes append -C $(git notes list HEAD^) HEAD^ &&
+ git log -1 HEAD^ > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+commit ffed603236bfa3891c49644257a83598afe8ae5a
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:22:13 2005 -0700
+
+ 10th
+
+Notes:
+ other note
+EOF
+
+test_expect_success 'create note from other note with "git notes append -c"' '
+ MSG="other note" git notes append -c $(git notes list HEAD^) &&
+ git log -1 > actual &&
+ test_cmp expect actual
+'
+
+cat > expect << EOF
+commit ffed603236bfa3891c49644257a83598afe8ae5a
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:22:13 2005 -0700
+
+ 10th
+
+Notes:
+ other note
+$whitespace
+ yet another note
+EOF
+
+test_expect_success 'append to note from other note with "git notes append -c"' '
+ MSG="yet another note" git notes append -c $(git notes list HEAD) &&
+ git log -1 > actual &&
+ test_cmp expect actual
+'
+
test_done
--
1.7.0.rc1.141.gd3fd
next prev parent reply other threads:[~2010-02-13 21:30 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-13 21:28 [PATCHv13 00/30] git notes Johan Herland
2010-02-13 21:28 ` [PATCHv13 01/30] Minor cosmetic fixes to notes.c Johan Herland
2010-02-13 21:28 ` [PATCHv13 02/30] Notes API: get_commit_notes() -> format_note() + remove the commit restriction Johan Herland
2010-02-13 21:28 ` [PATCHv13 03/30] Add tests for checking correct handling of $GIT_NOTES_REF and core.notesRef Johan Herland
2010-02-13 21:28 ` [PATCHv13 04/30] Notes API: init_notes(): Initialize the notes tree from the given notes ref Johan Herland
2010-02-13 21:28 ` [PATCHv13 05/30] Notes API: add_note(): Add note objects to the internal notes tree structure Johan Herland
2010-02-13 21:28 ` [PATCHv13 06/30] Notes API: remove_note(): Remove note objects from the " Johan Herland
2010-02-13 21:28 ` [PATCHv13 07/30] Notes API: get_note(): Return the note annotating the given object Johan Herland
2010-02-13 21:28 ` [PATCHv13 08/30] Notes API: for_each_note(): Traverse the entire notes tree with a callback Johan Herland
2010-02-13 21:28 ` [PATCHv13 09/30] Notes API: write_notes_tree(): Store the notes tree in the database Johan Herland
2010-02-13 21:28 ` [PATCHv13 10/30] Notes API: Allow multiple concurrent notes trees with new struct notes_tree Johan Herland
2010-02-13 21:28 ` [PATCHv13 11/30] Refactor notes concatenation into a flexible interface for combining notes Johan Herland
2010-02-13 21:28 ` [PATCHv13 12/30] Builtin-ify git-notes Johan Herland
2010-02-13 21:28 ` [PATCHv13 13/30] t3301: Verify successful annotation of non-commits Johan Herland
2010-02-13 21:28 ` [PATCHv13 14/30] t3305: Verify that adding many notes with git-notes triggers increased fanout Johan Herland
2010-02-13 21:28 ` [PATCHv13 15/30] Teach notes code to properly preserve non-notes in the notes tree Johan Herland
2010-02-13 21:28 ` [PATCHv13 16/30] Teach builtin-notes to remove empty notes Johan Herland
2010-02-13 21:28 ` [PATCHv13 17/30] builtin-notes: Add "remove" subcommand for removing existing notes Johan Herland
2010-02-13 21:28 ` [PATCHv13 18/30] t3305: Verify that removing notes triggers automatic fanout consolidation Johan Herland
2010-02-13 21:28 ` [PATCHv13 19/30] Notes API: prune_notes(): Prune notes that belong to non-existing objects Johan Herland
2010-02-13 21:28 ` [PATCHv13 20/30] builtin-notes: Add "prune" subcommand for removing notes for missing objects Johan Herland
2010-02-13 21:28 ` [PATCHv13 21/30] Documentation: Generalize git-notes docs to 'objects' instead of 'commits' Johan Herland
2010-02-13 21:28 ` [PATCHv13 22/30] builtin-notes: Add "list" subcommand for listing note objects Johan Herland
2010-02-13 21:28 ` [PATCHv13 23/30] builtin-notes: Add --message/--file aliases for -m/-F options Johan Herland
2010-02-13 21:28 ` [PATCHv13 24/30] builtin-notes: Add "add" subcommand for adding notes to objects Johan Herland
2010-02-13 21:28 ` [PATCHv13 25/30] builtin-notes: Add "append" subcommand for appending to note objects Johan Herland
2010-02-13 21:28 ` [PATCHv13 26/30] builtin-notes: Deprecate the -m/-F options for "git notes edit" Johan Herland
2010-02-13 21:28 ` [PATCHv13 27/30] builtin-notes: Refactor handling of -F option to allow combining -m and -F Johan Herland
2010-02-13 21:28 ` Johan Herland [this message]
2010-02-15 10:34 ` [PATCHv13 28/30] builtin-notes: Add -c/-C options for reusing notes Stephen Boyd
2010-02-16 1:47 ` Johan Herland
2010-02-25 0:48 ` [PATCH] builtin-notes: Minor (mostly parse_options-related) fixes Johan Herland
2010-02-25 3:07 ` Stephen Boyd
2010-02-13 21:28 ` [PATCHv13 29/30] builtin-notes: Misc. refactoring of argc and exit value handling Johan Herland
2010-02-13 21:28 ` [PATCHv13 30/30] builtin-notes: Add "copy" subcommand for copying notes between objects 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=1266096518-2104-29-git-send-email-johan@herland.net \
--to=johan@herland.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.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).