resolve_gitlink_ref_recursive(): change to work with struct ref_cache
[gitweb.git] / builtin / notes.c
index 30cee0fd3cf0713502eb7d47c683b7186069bc61..10b8bc7ad9c392d9dad9e06cf2d1b3ae3f7fd001 100644 (file)
@@ -804,6 +804,7 @@ static int merge_commit(struct notes_merge_options *o)
        struct notes_tree *t;
        struct commit *partial;
        struct pretty_print_context pretty_ctx;
+       int ret;
 
        /*
         * Read partial merge result from .git/NOTES_MERGE_PARTIAL,
@@ -828,6 +829,7 @@ static int merge_commit(struct notes_merge_options *o)
        o->local_ref = resolve_ref("NOTES_MERGE_REF", sha1, 0, NULL);
        if (!o->local_ref)
                die("Failed to resolve NOTES_MERGE_REF");
+       o->local_ref = xstrdup(o->local_ref);
 
        if (notes_merge_commit(o, t, partial, sha1))
                die("Failed to finalize notes merge");
@@ -843,7 +845,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((char *)o->local_ref);
+       return ret;
 }
 
 static int merge(int argc, const char **argv, const char *prefix)
@@ -953,7 +957,9 @@ static int merge(int argc, const char **argv, const char *prefix)
        return result < 0; /* return non-zero on conflicts */
 }
 
-static int remove_one_note(struct notes_tree *t, const char *name)
+#define IGNORE_MISSING 1
+
+static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag)
 {
        int status;
        unsigned char sha1[20];
@@ -964,12 +970,19 @@ static int remove_one_note(struct notes_tree *t, const char *name)
                fprintf(stderr, _("Object %s has no note\n"), name);
        else
                fprintf(stderr, _("Removing note for object %s\n"), name);
-       return status;
+       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()
        };
        struct notes_tree *t;
@@ -980,14 +993,22 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
 
        t = init_notes_check("remove");
 
-       if (!argc) {
-               retval = remove_one_note(t, "HEAD");
+       if (!argc && !from_stdin) {
+               retval = remove_one_note(t, "HEAD", flag);
        } else {
                while (*argv) {
-                       retval |= remove_one_note(t, *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);