diff options
Diffstat (limited to 'builtin/notes.c')
-rw-r--r-- | builtin/notes.c | 186 |
1 files changed, 27 insertions, 159 deletions
diff --git a/builtin/notes.c b/builtin/notes.c index 453457adb9..2b24d059b5 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -4,7 +4,7 @@ * Copyright (c) 2010 Johan Herland <johan@herland.net> * * Based on git-notes.sh by Johannes Schindelin, - * and builtin-tag.c by Kristian Høgsberg and Carlos Rica. + * and builtin/tag.c by Kristian Høgsberg and Carlos Rica. */ #include "cache.h" @@ -18,9 +18,7 @@ #include "parse-options.h" #include "string-list.h" #include "notes-merge.h" - -static void commit_notes(struct notes_tree *t, const char *msg); -static combine_notes_fn parse_combine_notes_fn(const char *v); +#include "notes-utils.h" static const char * const git_notes_usage[] = { N_("git notes [--ref <notes_ref>] [list [<object>]]"), @@ -92,10 +90,7 @@ static const char * const git_notes_get_ref_usage[] = { }; static const char note_template[] = - "\n" - "#\n" - "# Write/edit the notes for the following object:\n" - "#\n"; + "\nWrite/edit the notes for the following object:\n"; struct msg_arg { int given; @@ -129,7 +124,7 @@ static void write_commented_object(int fd, const unsigned char *object) {"show", "--stat", "--no-notes", sha1_to_hex(object), NULL}; struct child_process show; struct strbuf buf = STRBUF_INIT; - FILE *show_out; + struct strbuf cbuf = STRBUF_INIT; /* Invoke "git show --stat --no-notes $object" */ memset(&show, 0, sizeof(show)); @@ -142,21 +137,14 @@ static void write_commented_object(int fd, const unsigned char *object) die(_("unable to start 'show' for object '%s'"), sha1_to_hex(object)); - /* Open the output as FILE* so strbuf_getline() can be used. */ - show_out = xfdopen(show.out, "r"); - if (show_out == NULL) - die_errno(_("can't fdopen 'show' output fd")); + if (strbuf_read(&buf, show.out, 0) < 0) + die_errno(_("could not read 'show' output")); + strbuf_add_commented_lines(&cbuf, buf.buf, buf.len); + write_or_die(fd, cbuf.buf, cbuf.len); - /* Prepend "# " to each output line and write result to 'fd' */ - while (strbuf_getline(&buf, show_out, '\n') != EOF) { - write_or_die(fd, "# ", 2); - write_or_die(fd, buf.buf, buf.len); - write_or_die(fd, "\n", 1); - } + strbuf_release(&cbuf); strbuf_release(&buf); - if (fclose(show_out)) - die_errno(_("failed to close pipe to 'show' for object '%s'"), - sha1_to_hex(object)); + if (finish_command(&show)) die(_("failed to finish 'show' for object '%s'"), sha1_to_hex(object)); @@ -170,6 +158,7 @@ static void create_note(const unsigned char *object, struct msg_arg *msg, if (msg->use_editor || !msg->given) { int fd; + struct strbuf buf = STRBUF_INIT; /* write the template message before editing: */ path = git_pathdup("NOTES_EDITMSG"); @@ -181,11 +170,16 @@ static void create_note(const unsigned char *object, struct msg_arg *msg, 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)); + + strbuf_addch(&buf, '\n'); + strbuf_add_commented_lines(&buf, note_template, strlen(note_template)); + strbuf_addch(&buf, '\n'); + write_or_die(fd, buf.buf, buf.len); write_commented_object(fd, object); close(fd); + strbuf_release(&buf); strbuf_reset(&(msg->buf)); if (launch_editor(path, &(msg->buf), NULL)) { @@ -291,139 +285,13 @@ static int parse_reedit_arg(const struct option *opt, const char *arg, int unset return parse_reuse_arg(opt, arg, unset); } -static void commit_notes(struct notes_tree *t, const char *msg) -{ - struct strbuf buf = STRBUF_INIT; - unsigned char commit_sha1[20]; - - if (!t) - t = &default_notes_tree; - if (!t->initialized || !t->ref || !*t->ref) - die(_("Cannot commit uninitialized/unreferenced notes tree")); - if (!t->dirty) - return; /* don't have to commit an unchanged tree */ - - /* Prepare commit message and reflog message */ - 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, 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); -} - -static combine_notes_fn parse_combine_notes_fn(const char *v) -{ - if (!strcasecmp(v, "overwrite")) - return combine_notes_overwrite; - else if (!strcasecmp(v, "ignore")) - return combine_notes_ignore; - else if (!strcasecmp(v, "concatenate")) - return combine_notes_concatenate; - else if (!strcasecmp(v, "cat_sort_uniq")) - return combine_notes_cat_sort_uniq; - else - return NULL; -} - -static int notes_rewrite_config(const char *k, const char *v, void *cb) -{ - struct notes_rewrite_cfg *c = cb; - if (!prefixcmp(k, "notes.rewrite.") && !strcmp(k+14, c->cmd)) { - c->enabled = git_config_bool(k, v); - return 0; - } else if (!c->mode_from_env && !strcmp(k, "notes.rewritemode")) { - if (!v) - config_error_nonbool(k); - c->combine = parse_combine_notes_fn(v); - if (!c->combine) { - error(_("Bad notes.rewriteMode value: '%s'"), v); - return 1; - } - return 0; - } else if (!c->refs_from_env && !strcmp(k, "notes.rewriteref")) { - /* note that a refs/ prefix is implied in the - * underlying for_each_glob_ref */ - if (!prefixcmp(v, "refs/notes/")) - string_list_add_refs_by_glob(c->refs, v); - else - warning(_("Refusing to rewrite notes in %s" - " (outside of refs/notes/)"), v); - return 0; - } - - return 0; -} - - -struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd) -{ - struct notes_rewrite_cfg *c = xmalloc(sizeof(struct notes_rewrite_cfg)); - const char *rewrite_mode_env = getenv(GIT_NOTES_REWRITE_MODE_ENVIRONMENT); - const char *rewrite_refs_env = getenv(GIT_NOTES_REWRITE_REF_ENVIRONMENT); - c->cmd = cmd; - c->enabled = 1; - c->combine = combine_notes_concatenate; - c->refs = xcalloc(1, sizeof(struct string_list)); - c->refs->strdup_strings = 1; - c->refs_from_env = 0; - c->mode_from_env = 0; - if (rewrite_mode_env) { - c->mode_from_env = 1; - c->combine = parse_combine_notes_fn(rewrite_mode_env); - if (!c->combine) - /* TRANSLATORS: The first %s is the name of the - environment variable, the second %s is its value */ - error(_("Bad %s value: '%s'"), GIT_NOTES_REWRITE_MODE_ENVIRONMENT, - rewrite_mode_env); - } - if (rewrite_refs_env) { - c->refs_from_env = 1; - string_list_add_refs_from_colon_sep(c->refs, rewrite_refs_env); - } - git_config(notes_rewrite_config, c); - if (!c->enabled || !c->refs->nr) { - string_list_clear(c->refs, 0); - free(c->refs); - free(c); - return NULL; - } - c->trees = load_notes_trees(c->refs); - string_list_clear(c->refs, 0); - free(c->refs); - return c; -} - -int copy_note_for_rewrite(struct notes_rewrite_cfg *c, - const unsigned char *from_obj, const unsigned char *to_obj) -{ - int ret = 0; - int i; - for (i = 0; c->trees[i]; i++) - ret = copy_note(c->trees[i], from_obj, to_obj, 1, c->combine) || ret; - 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); -} - 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); @@ -465,10 +333,10 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) } if (!rewrite_cmd) { - commit_notes(t, "Notes added by 'git notes copy'"); + commit_notes(t, msg); free_notes(t); } else { - finish_copy_notes_for_rewrite(c); + finish_copy_notes_for_rewrite(c, msg); } return ret; } @@ -479,7 +347,7 @@ static struct notes_tree *init_notes_check(const char *subcommand) init_notes(NULL, NULL, NULL, 0); t = &default_notes_tree; - if (prefixcmp(t->ref, "refs/notes/")) + if (!starts_with(t->ref, "refs/notes/")) die("Refusing to %s notes in %s (outside of refs/notes/)", subcommand, t->ref); return t; @@ -615,7 +483,7 @@ static int copy(int argc, const char **argv, const char *prefix) const char *rewrite_cmd = NULL; struct option options[] = { OPT__FORCE(&force, N_("replace existing notes")), - OPT_BOOLEAN(0, "stdin", &from_stdin, N_("read objects from stdin")), + 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)")), @@ -871,13 +739,13 @@ static int merge(int argc, const char **argv, const char *prefix) N_("resolve notes conflicts using the given strategy " "(manual/ours/theirs/union/cat_sort_uniq)")), OPT_GROUP(N_("Committing unmerged notes")), - { OPTION_BOOLEAN, 0, "commit", &do_commit, NULL, + { OPTION_SET_INT, 0, "commit", &do_commit, NULL, N_("finalize notes merge by committing unmerged notes"), - PARSE_OPT_NOARG | PARSE_OPT_NONEG }, + PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1}, OPT_GROUP(N_("Aborting notes merge resolution")), - { OPTION_BOOLEAN, 0, "abort", &do_abort, NULL, + { OPTION_SET_INT, 0, "abort", &do_abort, NULL, N_("abort notes merge"), - PARSE_OPT_NOARG | PARSE_OPT_NONEG }, + PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1}, OPT_END() }; @@ -985,7 +853,7 @@ static int remove_cmd(int argc, const char **argv, const char *prefix) OPT_BIT(0, "ignore-missing", &flag, N_("attempt to remove non-existent note is not an error"), IGNORE_MISSING), - OPT_BOOLEAN(0, "stdin", &from_stdin, + OPT_BOOL(0, "stdin", &from_stdin, N_("read object names from the standard input")), OPT_END() }; |