static int prune(int argc, const char **argv, const char *prefix) { struct notes_tree *t; int show_only = 0, verbose = 0; struct option options[] = { OPT_BOOLEAN('n', "dry-run", &show_only, "do not remove, show only"), OPT_BOOLEAN('v', "verbose", &verbose, "report pruned notes"), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_notes_prune_usage, 0); if (argc) { error("too many parameters"); usage_with_options(git_notes_prune_usage, options); } t = init_notes_check("prune"); prune_notes(t, (verbose ? NOTES_PRUNE_VERBOSE : 0) | (show_only ? NOTES_PRUNE_VERBOSE|NOTES_PRUNE_DRYRUN : 0) ); if (!show_only) commit_notes(t, "Notes removed by 'git notes prune'"); free_notes(t); return 0; }
static int remove_cmd(int argc, const char **argv, const char *prefix) { struct option options[] = { OPT_END() }; const char *object_ref; struct notes_tree *t; unsigned char object[20]; 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"); fprintf(stderr, "Removing note for object %s\n", sha1_to_hex(object)); remove_note(t, object); commit_notes(t, "Notes removed by 'git notes remove'"); free_notes(t); return 0; }
static int notes_copy_from_stdin(int force, const char *rewrite_cmd) { struct strbuf buf = STRBUF_INIT; struct notes_rewrite_cfg *c = NULL; struct notes_tree *t = NULL; int ret = 0; const char *msg = "Notes added by 'git notes copy'"; if (rewrite_cmd) { c = init_copy_notes_for_rewrite(rewrite_cmd); if (!c) return 0; } else { init_notes(NULL, NULL, NULL, NOTES_INIT_WRITABLE); t = &default_notes_tree; } while (strbuf_getline_lf(&buf, stdin) != EOF) { struct object_id from_obj, to_obj; struct strbuf **split; int err; split = strbuf_split(&buf, ' '); if (!split[0] || !split[1]) die(_("malformed input line: '%s'."), buf.buf); strbuf_rtrim(split[0]); strbuf_rtrim(split[1]); if (get_oid(split[0]->buf, &from_obj)) die(_("failed to resolve '%s' as a valid ref."), split[0]->buf); if (get_oid(split[1]->buf, &to_obj)) die(_("failed to resolve '%s' as a valid ref."), split[1]->buf); if (rewrite_cmd) err = copy_note_for_rewrite(c, &from_obj, &to_obj); else err = copy_note(t, &from_obj, &to_obj, force, combine_notes_overwrite); if (err) { error(_("failed to copy notes from '%s' to '%s'"), split[0]->buf, split[1]->buf); ret = 1; } strbuf_list_free(split); } if (!rewrite_cmd) { commit_notes(t, msg); free_notes(t); } else { finish_copy_notes_for_rewrite(c, msg); } strbuf_release(&buf); return ret; }
void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c) { int i; for (i = 0; c->trees[i]; i++) { commit_notes(c->trees[i], "Notes added by 'git notes copy'"); free_notes(c->trees[i]); } free(c->trees); free(c); }
void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c, const char *msg) { int i; for (i = 0; c->trees[i]; i++) { commit_notes(c->trees[i], msg); free_notes(c->trees[i]); } free(c->trees); free(c); }
int notes_copy_from_stdin(int force, const char *rewrite_cmd) { struct strbuf buf = STRBUF_INIT; struct notes_rewrite_cfg *c = NULL; struct notes_tree *t = NULL; int ret = 0; if (rewrite_cmd) { c = init_copy_notes_for_rewrite(rewrite_cmd); if (!c) return 0; } else { init_notes(NULL, NULL, NULL, 0); t = &default_notes_tree; } while (strbuf_getline(&buf, stdin, '\n') != EOF) { unsigned char from_obj[20], to_obj[20]; struct strbuf **split; int err; split = strbuf_split(&buf, ' '); if (!split[0] || !split[1]) die("Malformed input line: '%s'.", buf.buf); strbuf_rtrim(split[0]); strbuf_rtrim(split[1]); if (get_sha1(split[0]->buf, from_obj)) die("Failed to resolve '%s' as a valid ref.", split[0]->buf); if (get_sha1(split[1]->buf, to_obj)) die("Failed to resolve '%s' as a valid ref.", split[1]->buf); if (rewrite_cmd) err = copy_note_for_rewrite(c, from_obj, to_obj); else err = copy_note(t, from_obj, to_obj, force, combine_notes_overwrite); if (err) { error("Failed to copy notes from '%s' to '%s'", split[0]->buf, split[1]->buf); ret = 1; } strbuf_list_free(split); } if (!rewrite_cmd) { commit_notes(t, "Notes added by 'git notes copy'"); free_notes(t); } else { finish_copy_notes_for_rewrite(c); } return ret; }
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, N_("attempt to remove non-existent note is not an error"), IGNORE_MISSING), OPT_BOOL(0, "stdin", &from_stdin, N_("read object names from the standard input")), OPT_END() }; struct notes_tree *t; int retval = 0; argc = parse_options(argc, argv, prefix, options, git_notes_remove_usage, 0); t = init_notes_check("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; }
static int append_edit(int argc, const char **argv, const char *prefix) { const char *object_ref; struct notes_tree *t; unsigned char object[20], new_note[20]; const unsigned char *note; char logmsg[100]; const char * const *usage; struct msg_arg msg = { 0, 0, STRBUF_INIT }; struct option options[] = { { OPTION_CALLBACK, 'm', "message", &msg, "MSG", "note contents as a string", PARSE_OPT_NONEG, parse_msg_arg}, { OPTION_CALLBACK, 'F', "file", &msg, "FILE", "note contents in a file", PARSE_OPT_NONEG, parse_file_arg}, { OPTION_CALLBACK, 'c', "reedit-message", &msg, "OBJECT", "reuse and edit specified note object", PARSE_OPT_NONEG, parse_reedit_arg}, { OPTION_CALLBACK, 'C', "reuse-message", &msg, "OBJECT", "reuse specified note object", PARSE_OPT_NONEG, parse_reuse_arg}, OPT_END() }; int edit = !strcmp(argv[0], "edit"); usage = edit ? git_notes_edit_usage : git_notes_append_usage; argc = parse_options(argc, argv, prefix, options, usage, PARSE_OPT_KEEP_ARGV0); if (2 < argc) { error("too many parameters"); usage_with_options(usage, options); } if (msg.given && edit) 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"); object_ref = 1 < argc ? argv[1] : "HEAD"; if (get_sha1(object_ref, object)) die("Failed to resolve '%s' as a valid ref.", object_ref); t = init_notes_check(argv[0]); note = get_note(t, object); create_note(object, &msg, !edit, note, new_note); if (is_null_sha1(new_note)) remove_note(t, object); else add_note(t, object, new_note, combine_notes_overwrite); snprintf(logmsg, sizeof(logmsg), "Notes %s by 'git notes %s'", is_null_sha1(new_note) ? "removed" : "added", argv[0]); commit_notes(t, logmsg); free_notes(t); strbuf_release(&(msg.buf)); return 0; }
static int copy(int argc, const char **argv, const char *prefix) { int retval = 0, force = 0, from_stdin = 0; const unsigned char *from_note, *note; const char *object_ref; unsigned char object[20], from_obj[20]; struct notes_tree *t; const char *rewrite_cmd = NULL; struct option options[] = { OPT_BOOLEAN('f', "force", &force, "replace existing notes"), OPT_BOOLEAN(0, "stdin", &from_stdin, "read objects from stdin"), OPT_STRING(0, "for-rewrite", &rewrite_cmd, "command", "load rewriting config for <command> (implies " "--stdin)"), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_notes_copy_usage, 0); if (from_stdin || rewrite_cmd) { if (argc) { error("too many parameters"); usage_with_options(git_notes_copy_usage, options); } else { return notes_copy_from_stdin(force, rewrite_cmd); } } if (argc < 2) { error("too few parameters"); usage_with_options(git_notes_copy_usage, options); } if (2 < argc) { error("too many parameters"); usage_with_options(git_notes_copy_usage, options); } if (get_sha1(argv[0], from_obj)) die("Failed to resolve '%s' as a valid ref.", argv[0]); object_ref = 1 < argc ? argv[1] : "HEAD"; if (get_sha1(object_ref, object)) die("Failed to resolve '%s' as a valid ref.", object_ref); t = init_notes_check("copy"); note = get_note(t, object); if (note) { if (!force) { retval = error("Cannot copy notes. Found existing " "notes for object %s. Use '-f' to " "overwrite existing notes", sha1_to_hex(object)); goto out; } fprintf(stderr, "Overwriting existing notes for object %s\n", sha1_to_hex(object)); } from_note = get_note(t, from_obj); if (!from_note) { retval = error("Missing notes on source object %s. Cannot " "copy.", sha1_to_hex(from_obj)); goto out; } add_note(t, object, from_note, combine_notes_overwrite); commit_notes(t, "Notes added by 'git notes copy'"); out: free_notes(t); return retval; }
static int add(int argc, const char **argv, const char *prefix) { int retval = 0, force = 0; const char *object_ref; struct notes_tree *t; unsigned char object[20], new_note[20]; char logmsg[100]; const unsigned char *note; struct msg_arg msg = { 0, 0, STRBUF_INIT }; struct option options[] = { { OPTION_CALLBACK, 'm', "message", &msg, "MSG", "note contents as a string", PARSE_OPT_NONEG, parse_msg_arg}, { OPTION_CALLBACK, 'F', "file", &msg, "FILE", "note contents in a file", PARSE_OPT_NONEG, parse_file_arg}, { OPTION_CALLBACK, 'c', "reedit-message", &msg, "OBJECT", "reuse and edit specified note object", PARSE_OPT_NONEG, parse_reedit_arg}, { OPTION_CALLBACK, 'C', "reuse-message", &msg, "OBJECT", "reuse specified note object", PARSE_OPT_NONEG, parse_reuse_arg}, OPT_BOOLEAN('f', "force", &force, "replace existing notes"), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_notes_add_usage, 0); if (1 < argc) { error("too many parameters"); usage_with_options(git_notes_add_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("add"); note = get_note(t, object); if (note) { if (!force) { retval = error("Cannot add notes. Found existing notes " "for object %s. Use '-f' to overwrite " "existing notes", sha1_to_hex(object)); goto out; } fprintf(stderr, "Overwriting existing notes for object %s\n", sha1_to_hex(object)); } create_note(object, &msg, 0, note, new_note); if (is_null_sha1(new_note)) remove_note(t, object); else add_note(t, object, new_note, combine_notes_overwrite); snprintf(logmsg, sizeof(logmsg), "Notes %s by 'git notes %s'", is_null_sha1(new_note) ? "removed" : "added", "add"); commit_notes(t, logmsg); out: free_notes(t); strbuf_release(&(msg.buf)); return retval; }
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]; const unsigned char *note; char logmsg[100]; const char * const *usage; struct note_data d = { 0, 0, NULL, STRBUF_INIT }; struct option options[] = { { OPTION_CALLBACK, 'm', "message", &d, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, parse_msg_arg}, { OPTION_CALLBACK, 'F', "file", &d, N_("file"), N_("note contents in a file"), PARSE_OPT_NONEG, parse_file_arg}, { OPTION_CALLBACK, 'c', "reedit-message", &d, N_("object"), N_("reuse and edit specified note object"), PARSE_OPT_NONEG, parse_reedit_arg}, { 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"); usage = edit ? git_notes_edit_usage : git_notes_append_usage; argc = parse_options(argc, argv, prefix, options, usage, PARSE_OPT_KEEP_ARGV0); if (2 < argc) { error(_("too many parameters")); usage_with_options(usage, options); } if (d.given && edit) 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")); object_ref = 1 < argc ? argv[1] : "HEAD"; if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); t = init_notes_check(argv[0]); note = get_note(t, object); prepare_note_data(object, &d, edit ? note : NULL); if (note && !edit) { /* Append buf to previous note contents */ unsigned long size; enum object_type type; char *prev_buf = read_sha1_file(note, &type, &size); strbuf_grow(&d.buf, size + 1); if (d.buf.len && prev_buf && size) strbuf_insert(&d.buf, 0, "\n", 1); if (prev_buf && size) strbuf_insert(&d.buf, 0, prev_buf, size); free(prev_buf); } 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"); snprintf(logmsg, sizeof(logmsg), "Notes added by 'git notes %s'", argv[0]); } else { fprintf(stderr, _("Removing note for object %s\n"), sha1_to_hex(object)); remove_note(t, object); snprintf(logmsg, sizeof(logmsg), "Notes removed by 'git notes %s'", argv[0]); } commit_notes(t, logmsg); free_note_data(&d); free_notes(t); return 0; }
static int add(int argc, const char **argv, const char *prefix) { int force = 0, allow_empty = 0; const char *object_ref; struct notes_tree *t; unsigned char object[20], new_note[20]; const unsigned char *note; struct note_data d = { 0, 0, NULL, STRBUF_INIT }; struct option options[] = { { OPTION_CALLBACK, 'm', "message", &d, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, parse_msg_arg}, { OPTION_CALLBACK, 'F', "file", &d, N_("file"), N_("note contents in a file"), PARSE_OPT_NONEG, parse_file_arg}, { OPTION_CALLBACK, 'c', "reedit-message", &d, N_("object"), N_("reuse and edit specified note object"), PARSE_OPT_NONEG, parse_reedit_arg}, { 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() }; argc = parse_options(argc, argv, prefix, options, git_notes_add_usage, PARSE_OPT_KEEP_ARGV0); if (2 < argc) { error(_("too many parameters")); usage_with_options(git_notes_add_usage, options); } object_ref = argc > 1 ? argv[1] : "HEAD"; if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); t = init_notes_check("add"); note = get_note(t, object); if (note) { if (!force) { free_notes(t); if (d.given) { free_note_data(&d); return error(_("Cannot add notes. " "Found existing notes for object %s. " "Use '-f' to overwrite existing notes"), sha1_to_hex(object)); } /* * Redirect to "edit" subcommand. * * We only end up here if none of -m/-F/-c/-C or -f are * given. The original args are therefore still in * argv[0-1]. */ argv[0] = "edit"; return append_edit(argc, argv, prefix); } fprintf(stderr, _("Overwriting existing notes for object %s\n"), sha1_to_hex(object)); } prepare_note_data(object, &d, note); 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"); commit_notes(t, "Notes added by 'git notes add'"); } else { fprintf(stderr, _("Removing note for object %s\n"), sha1_to_hex(object)); remove_note(t, object); commit_notes(t, "Notes removed by 'git notes add'"); } free_note_data(&d); free_notes(t); return 0; }
static int add(int argc, const char **argv, const char *prefix) { int retval = 0, force = 0; const char *object_ref; struct notes_tree *t; unsigned char object[20], new_note[20]; char logmsg[100]; const unsigned char *note; struct msg_arg msg = { 0, 0, STRBUF_INIT }; struct option options[] = { { OPTION_CALLBACK, 'm', "message", &msg, N_("message"), N_("note contents as a string"), PARSE_OPT_NONEG, parse_msg_arg}, { OPTION_CALLBACK, 'F', "file", &msg, N_("file"), N_("note contents in a file"), PARSE_OPT_NONEG, parse_file_arg}, { OPTION_CALLBACK, 'c', "reedit-message", &msg, N_("object"), N_("reuse and edit specified note object"), PARSE_OPT_NONEG, parse_reedit_arg}, { OPTION_CALLBACK, 'C', "reuse-message", &msg, N_("object"), N_("reuse specified note object"), PARSE_OPT_NONEG, parse_reuse_arg}, OPT__FORCE(&force, N_("replace existing notes")), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_notes_add_usage, PARSE_OPT_KEEP_ARGV0); if (2 < argc) { error(_("too many parameters")); usage_with_options(git_notes_add_usage, options); } object_ref = argc > 1 ? argv[1] : "HEAD"; if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); t = init_notes_check("add"); note = get_note(t, object); if (note) { if (!force) { if (!msg.given) { /* * Redirect to "edit" subcommand. * * We only end up here if none of -m/-F/-c/-C * or -f are given. The original args are * therefore still in argv[0-1]. */ argv[0] = "edit"; free_notes(t); return append_edit(argc, argv, prefix); } retval = error(_("Cannot add notes. Found existing notes " "for object %s. Use '-f' to overwrite " "existing notes"), sha1_to_hex(object)); goto out; } fprintf(stderr, _("Overwriting existing notes for object %s\n"), sha1_to_hex(object)); } create_note(object, &msg, 0, note, new_note); if (is_null_sha1(new_note)) remove_note(t, object); else if (add_note(t, object, new_note, combine_notes_overwrite)) die("BUG: combine_notes_overwrite failed"); snprintf(logmsg, sizeof(logmsg), "Notes %s by 'git notes %s'", is_null_sha1(new_note) ? "removed" : "added", "add"); commit_notes(t, logmsg); out: free_notes(t); strbuf_release(&(msg.buf)); return retval; }
static int copy(int argc, const char **argv, const char *prefix) { int retval = 0, force = 0, from_stdin = 0; const struct object_id *from_note, *note; const char *object_ref; struct object_id object, from_obj; struct notes_tree *t; const char *rewrite_cmd = NULL; struct option options[] = { OPT__FORCE(&force, N_("replace existing notes")), OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")), OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"), N_("load rewriting config for <command> (implies " "--stdin)")), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_notes_copy_usage, 0); if (from_stdin || rewrite_cmd) { if (argc) { error(_("too many parameters")); usage_with_options(git_notes_copy_usage, options); } else { return notes_copy_from_stdin(force, rewrite_cmd); } } if (argc < 2) { error(_("too few parameters")); usage_with_options(git_notes_copy_usage, options); } if (2 < argc) { error(_("too many parameters")); usage_with_options(git_notes_copy_usage, options); } if (get_oid(argv[0], &from_obj)) die(_("failed to resolve '%s' as a valid ref."), argv[0]); object_ref = 1 < argc ? argv[1] : "HEAD"; if (get_oid(object_ref, &object)) die(_("failed to resolve '%s' as a valid ref."), object_ref); t = init_notes_check("copy", NOTES_INIT_WRITABLE); note = get_note(t, &object); if (note) { if (!force) { retval = error(_("Cannot copy notes. Found existing " "notes for object %s. Use '-f' to " "overwrite existing notes"), oid_to_hex(&object)); goto out; } fprintf(stderr, _("Overwriting existing notes for object %s\n"), oid_to_hex(&object)); } from_note = get_note(t, &from_obj); if (!from_note) { retval = error(_("missing notes on source object %s. Cannot " "copy."), oid_to_hex(&from_obj)); goto out; } if (add_note(t, &object, from_note, combine_notes_overwrite)) die("BUG: combine_notes_overwrite failed"); commit_notes(t, "Notes added by 'git notes copy'"); out: free_notes(t); return retval; }