summaryrefslogtreecommitdiff
path: root/builtin/notes.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/notes.c')
-rw-r--r--builtin/notes.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/builtin/notes.c b/builtin/notes.c
index 1fb1f73439..3644d140ec 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -29,7 +29,7 @@ static const char * const git_notes_usage[] = {
"git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>",
"git notes merge --commit [-v | -q]",
"git notes merge --abort [-v | -q]",
- "git notes [--ref <notes_ref>] remove [<object>]",
+ "git notes [--ref <notes_ref>] remove [<object>...]",
"git notes [--ref <notes_ref>] prune [-n | -v]",
"git notes [--ref <notes_ref>] get-ref",
NULL
@@ -301,12 +301,12 @@ void commit_notes(struct notes_tree *t, const char *msg)
return; /* don't have to commit an unchanged tree */
/* Prepare commit message and reflog message */
- strbuf_addstr(&buf, "notes: "); /* commit message starts at index 7 */
strbuf_addstr(&buf, msg);
if (buf.buf[buf.len - 1] != '\n')
strbuf_addch(&buf, '\n'); /* Make sure msg ends with newline */
- create_notes_commit(t, NULL, buf.buf + 7, commit_sha1);
+ create_notes_commit(t, NULL, &buf, commit_sha1);
+ strbuf_insert(&buf, 0, "notes: ", 7); /* commit message starts at index 7 */
update_ref(buf.buf, t->ref, commit_sha1, NULL, 0, DIE_ON_ERR);
strbuf_release(&buf);
@@ -804,6 +804,8 @@ static int merge_commit(struct notes_merge_options *o)
struct notes_tree *t;
struct commit *partial;
struct pretty_print_context pretty_ctx;
+ void *local_ref_to_free;
+ int ret;
/*
* Read partial merge result from .git/NOTES_MERGE_PARTIAL,
@@ -825,7 +827,8 @@ static int merge_commit(struct notes_merge_options *o)
t = xcalloc(1, sizeof(struct notes_tree));
init_notes(t, "NOTES_MERGE_PARTIAL", combine_notes_overwrite, 0);
- o->local_ref = resolve_ref("NOTES_MERGE_REF", sha1, 0, NULL);
+ o->local_ref = local_ref_to_free =
+ resolve_refdup("NOTES_MERGE_REF", sha1, 0, NULL);
if (!o->local_ref)
die("Failed to resolve NOTES_MERGE_REF");
@@ -843,7 +846,9 @@ static int merge_commit(struct notes_merge_options *o)
free_notes(t);
strbuf_release(&msg);
- return merge_abort(o);
+ ret = merge_abort(o);
+ free(local_ref_to_free);
+ return ret;
}
static int merge(int argc, const char **argv, const char *prefix)
@@ -953,40 +958,60 @@ static int merge(int argc, const char **argv, const char *prefix)
return result < 0; /* return non-zero on conflicts */
}
+#define IGNORE_MISSING 1
+
+static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag)
+{
+ int status;
+ unsigned char sha1[20];
+ if (get_sha1(name, sha1))
+ return error(_("Failed to resolve '%s' as a valid ref."), name);
+ status = remove_note(t, sha1);
+ if (status)
+ fprintf(stderr, _("Object %s has no note\n"), name);
+ else
+ fprintf(stderr, _("Removing note for object %s\n"), name);
+ return (flag & IGNORE_MISSING) ? 0 : status;
+}
+
static int remove_cmd(int argc, const char **argv, const char *prefix)
{
+ unsigned flag = 0;
+ int from_stdin = 0;
struct option options[] = {
+ OPT_BIT(0, "ignore-missing", &flag,
+ "attempt to remove non-existent note is not an error",
+ IGNORE_MISSING),
+ OPT_BOOLEAN(0, "stdin", &from_stdin,
+ "read object names from the standard input"),
OPT_END()
};
- const char *object_ref;
struct notes_tree *t;
- unsigned char object[20];
- int retval;
+ int retval = 0;
argc = parse_options(argc, argv, prefix, options,
git_notes_remove_usage, 0);
- if (1 < argc) {
- error(_("too many parameters"));
- usage_with_options(git_notes_remove_usage, options);
- }
-
- object_ref = argc ? argv[0] : "HEAD";
-
- if (get_sha1(object_ref, object))
- die(_("Failed to resolve '%s' as a valid ref."), object_ref);
-
t = init_notes_check("remove");
- retval = remove_note(t, object);
- if (retval)
- fprintf(stderr, _("Object %s has no note\n"), sha1_to_hex(object));
- else {
- fprintf(stderr, _("Removing note for object %s\n"),
- sha1_to_hex(object));
-
- commit_notes(t, "Notes removed by 'git notes remove'");
+ if (!argc && !from_stdin) {
+ retval = remove_one_note(t, "HEAD", flag);
+ } else {
+ while (*argv) {
+ retval |= remove_one_note(t, *argv, flag);
+ argv++;
+ }
}
+ if (from_stdin) {
+ struct strbuf sb = STRBUF_INIT;
+ while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
+ strbuf_rtrim(&sb);
+ retval |= remove_one_note(t, sb.buf, flag);
+ }
+ strbuf_release(&sb);
+ }
+ if (!retval)
+ commit_notes(t, "Notes removed by 'git notes remove'");
free_notes(t);
return retval;
}