diff options
Diffstat (limited to 'builtin/commit.c')
-rw-r--r-- | builtin/commit.c | 298 |
1 files changed, 159 insertions, 139 deletions
diff --git a/builtin/commit.c b/builtin/commit.c index 7c9b1e7be3..a91197245f 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -5,45 +5,54 @@ * Based on git-commit.sh by Junio C Hamano and Linus Torvalds */ -#define USE_THE_INDEX_COMPATIBILITY_MACROS -#include "cache.h" +#define USE_THE_INDEX_VARIABLE +#include "builtin.h" +#include "advice.h" #include "config.h" #include "lockfile.h" #include "cache-tree.h" #include "color.h" #include "dir.h" -#include "builtin.h" +#include "editor.h" +#include "environment.h" #include "diff.h" -#include "diffcore.h" #include "commit.h" +#include "gettext.h" #include "revision.h" #include "wt-status.h" #include "run-command.h" -#include "refs.h" -#include "log-tree.h" #include "strbuf.h" -#include "utf8.h" +#include "object-name.h" #include "parse-options.h" +#include "path.h" +#include "preload-index.h" +#include "read-cache.h" #include "string-list.h" #include "rerere.h" #include "unpack-trees.h" -#include "quote.h" -#include "submodule.h" -#include "gpg-interface.h" #include "column.h" #include "sequencer.h" +#include "sparse-index.h" #include "mailmap.h" #include "help.h" #include "commit-reach.h" #include "commit-graph.h" +#include "pretty.h" static const char * const builtin_commit_usage[] = { - N_("git commit [<options>] [--] <pathspec>..."), + N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" + " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)]\n" + " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" + " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" + " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" + " [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" + " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" + " [--] [<pathspec>...]"), NULL }; static const char * const builtin_status_usage[] = { - N_("git status [<options>] [--] <pathspec>..."), + N_("git status [<options>] [--] [<pathspec>...]"), NULL }; @@ -137,7 +146,7 @@ static int opt_pass_trailer(const struct option *opt, const char *arg, int unset { BUG_ON_OPT_NEG(unset); - strvec_pushl(&trailer_args, "--trailer", arg, NULL); + strvec_pushl(opt->value, "--trailer", arg, NULL); return 0; } @@ -203,7 +212,7 @@ static void status_init_config(struct wt_status *s, config_fn_t fn) init_diff_ui_defaults(); git_config(fn, s); determine_whence(s); - s->hints = advice_status_hints; /* must come after git_config() */ + s->hints = advice_enabled(ADVICE_STATUS_HINTS); /* must come after git_config() */ } static void rollback_index_files(void) @@ -263,8 +272,8 @@ static int list_paths(struct string_list *list, const char *with_tree, /* TODO: audit for interaction with sparse-index. */ ensure_full_index(&the_index); - for (i = 0; i < active_nr; i++) { - const struct cache_entry *ce = active_cache[i]; + for (i = 0; i < the_index.cache_nr; i++) { + const struct cache_entry *ce = the_index.cache[i]; struct string_list_item *item; if (ce->ce_flags & CE_UPDATE) @@ -293,10 +302,10 @@ static void add_remove_files(struct string_list *list) continue; if (!lstat(p->string, &st)) { - if (add_to_cache(p->string, &st, 0)) + if (add_to_index(&the_index, p->string, &st, 0)) die(_("updating files failed")); } else - remove_file_from_cache(p->string); + remove_file_from_index(&the_index, p->string); } } @@ -307,7 +316,7 @@ static void create_base_index(const struct commit *current_head) struct tree_desc t; if (!current_head) { - discard_cache(); + discard_index(&the_index); return; } @@ -322,7 +331,8 @@ static void create_base_index(const struct commit *current_head) tree = parse_tree_indirect(¤t_head->object.oid); if (!tree) die(_("failed to unpack HEAD tree object")); - parse_tree(tree); + if (parse_tree(tree) < 0) + exit(128); init_tree_desc(&t, tree->buffer, tree->size); if (unpack_trees(1, &t, &opts)) exit(128); /* We've already reported the error, finish dying */ @@ -334,7 +344,7 @@ static void refresh_cache_or_die(int refresh_flags) * refresh_flags contains REFRESH_QUIET, so the only errors * are for unmerged entries. */ - if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN)) + if (refresh_index(&the_index, refresh_flags | REFRESH_IN_PORCELAIN, NULL, NULL, NULL)) die_resolve_conflict("commit"); } @@ -354,31 +364,32 @@ static const char *prepare_index(const char **argv, const char *prefix, if (pathspec_from_file) { if (interactive) - die(_("--pathspec-from-file is incompatible with --interactive/--patch")); + die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch"); if (all) - die(_("--pathspec-from-file with -a does not make sense")); + die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "-a"); if (pathspec.nr) - die(_("--pathspec-from-file is incompatible with pathspec arguments")); + die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file"); parse_pathspec_file(&pathspec, 0, PATHSPEC_PREFER_FULL, prefix, pathspec_from_file, pathspec_file_nul); } else if (pathspec_file_nul) { - die(_("--pathspec-file-nul requires --pathspec-from-file")); + die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file"); } if (!pathspec.nr && (also || (only && !allow_empty && (!amend || (fixup_message && strcmp(fixup_prefix, "amend")))))) die(_("No paths with --include/--only does not make sense.")); - if (read_cache_preload(&pathspec) < 0) + if (repo_read_index_preload(the_repository, &pathspec, 0) < 0) die(_("index file corrupt")); if (interactive) { char *old_index_env = NULL, *old_repo_index_file; - hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); + repo_hold_locked_index(the_repository, &index_lock, + LOCK_DIE_ON_ERROR); refresh_cache_or_die(refresh_flags); @@ -401,9 +412,10 @@ static const char *prepare_index(const char **argv, const char *prefix, unsetenv(INDEX_ENVIRONMENT); FREE_AND_NULL(old_index_env); - discard_cache(); - read_cache_from(get_lock_file_path(&index_lock)); - if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) { + discard_index(&the_index); + read_index_from(&the_index, get_lock_file_path(&index_lock), + get_git_dir()); + if (cache_tree_update(&the_index, WRITE_TREE_SILENT) == 0) { if (reopen_lock_file(&index_lock) < 0) die(_("unable to write index file")); if (write_locked_index(&the_index, &index_lock, 0)) @@ -429,12 +441,14 @@ static const char *prepare_index(const char **argv, const char *prefix, * (B) on failure, rollback the real index. */ if (all || (also && pathspec.nr)) { - hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); - add_files_to_cache(also ? prefix : NULL, &pathspec, 0); + repo_hold_locked_index(the_repository, &index_lock, + LOCK_DIE_ON_ERROR); + add_files_to_cache(the_repository, also ? prefix : NULL, + &pathspec, 0, 0); refresh_cache_or_die(refresh_flags); - update_main_cache_tree(WRITE_TREE_SILENT); + cache_tree_update(&the_index, WRITE_TREE_SILENT); if (write_locked_index(&the_index, &index_lock, 0)) - die(_("unable to write new_index file")); + die(_("unable to write new index file")); commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); goto out; @@ -450,14 +464,15 @@ static const char *prepare_index(const char **argv, const char *prefix, * We still need to refresh the index here. */ if (!only && !pathspec.nr) { - hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); + repo_hold_locked_index(the_repository, &index_lock, + LOCK_DIE_ON_ERROR); refresh_cache_or_die(refresh_flags); - if (active_cache_changed - || !cache_tree_fully_valid(active_cache_tree)) - update_main_cache_tree(WRITE_TREE_SILENT); + if (the_index.cache_changed + || !cache_tree_fully_valid(the_index.cache_tree)) + cache_tree_update(&the_index, WRITE_TREE_SILENT); if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("unable to write new_index file")); + die(_("unable to write new index file")); commit_style = COMMIT_AS_IS; ret = get_index_file(); goto out; @@ -496,16 +511,16 @@ static const char *prepare_index(const char **argv, const char *prefix, if (list_paths(&partial, !current_head ? NULL : "HEAD", &pathspec)) exit(1); - discard_cache(); - if (read_cache() < 0) + discard_index(&the_index); + if (repo_read_index(the_repository) < 0) die(_("cannot read the index")); - hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); + repo_hold_locked_index(the_repository, &index_lock, LOCK_DIE_ON_ERROR); add_remove_files(&partial); - refresh_cache(REFRESH_QUIET); - update_main_cache_tree(WRITE_TREE_SILENT); + refresh_index(&the_index, REFRESH_QUIET, NULL, NULL, NULL); + cache_tree_update(&the_index, WRITE_TREE_SILENT); if (write_locked_index(&the_index, &index_lock, 0)) - die(_("unable to write new_index file")); + die(_("unable to write new index file")); hold_lock_file_for_update(&false_lock, git_path("next-index-%"PRIuMAX, @@ -514,14 +529,14 @@ static const char *prepare_index(const char **argv, const char *prefix, create_base_index(current_head); add_remove_files(&partial); - refresh_cache(REFRESH_QUIET); + refresh_index(&the_index, REFRESH_QUIET, NULL, NULL, NULL); if (write_locked_index(&the_index, &false_lock, 0)) die(_("unable to write temporary index file")); - discard_cache(); + discard_index(&the_index); ret = get_lock_file_path(&false_lock); - read_cache_from(ret); + read_index_from(&the_index, ret, get_git_dir()); out: string_list_clear(&partial, 0); clear_pathspec(&pathspec); @@ -544,7 +559,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int s->index_file = index_file; s->fp = fp; s->nowarn = nowarn; - s->is_initial = get_oid(s->reference, &oid) ? 1 : 0; + s->is_initial = repo_get_oid(the_repository, s->reference, &oid) ? 1 : 0; if (!s->is_initial) oidcpy(&s->oid_commit, &oid); s->status_format = status_format; @@ -699,15 +714,15 @@ static void prepare_amend_commit(struct commit *commit, struct strbuf *sb, { const char *buffer, *subject, *fmt; - buffer = get_commit_buffer(commit, NULL); + buffer = repo_get_commit_buffer(the_repository, commit, NULL); find_commit_subject(buffer, &subject); /* * If we amend the 'amend!' commit then we don't want to * duplicate the subject line. */ fmt = starts_with(subject, "amend!") ? "%b" : "%B"; - format_commit_message(commit, fmt, sb, ctx); - unuse_commit_buffer(commit, buffer); + repo_format_commit_message(the_repository, commit, fmt, sb, ctx); + repo_unuse_commit_buffer(the_repository, commit, buffer); } static int prepare_to_commit(const char *index_file, const char *prefix, @@ -723,12 +738,13 @@ static int prepare_to_commit(const char *index_file, const char *prefix, const char *hook_arg2 = NULL; int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE); int old_display_comment_prefix; - int merge_contains_scissors = 0; + int invoked_hook; /* This checks and barfs if author is badly specified */ determine_author_info(author_ident); - if (!no_verify && run_commit_hook(use_editor, index_file, "pre-commit", NULL)) + if (!no_verify && run_commit_hook(use_editor, index_file, &invoked_hook, + "pre-commit", NULL)) return 0; if (squash_message) { @@ -743,10 +759,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix, struct commit *c; c = lookup_commit_reference_by_name(squash_message); if (!c) - die(_("could not lookup commit %s"), squash_message); + die(_("could not lookup commit '%s'"), squash_message); ctx.output_encoding = get_commit_output_encoding(); - format_commit_message(c, "squash! %s\n\n", &sb, - &ctx); + repo_format_commit_message(the_repository, c, + "squash! %s\n\n", &sb, + &ctx); } } @@ -777,10 +794,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix, char *fmt; commit = lookup_commit_reference_by_name(fixup_commit); if (!commit) - die(_("could not lookup commit %s"), fixup_commit); + die(_("could not lookup commit '%s'"), fixup_commit); ctx.output_encoding = get_commit_output_encoding(); fmt = xstrfmt("%s! %%s\n\n", fixup_prefix); - format_commit_message(commit, fmt, &sb, &ctx); + repo_format_commit_message(the_repository, commit, fmt, &sb, + &ctx); free(fmt); hook_arg1 = "message"; @@ -798,7 +816,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (!strcmp(fixup_prefix, "amend")) { if (have_option_m) - die(_("cannot combine -m with --fixup:%s"), fixup_message); + die(_("options '%s' and '%s:%s' cannot be used together"), "-m", "--fixup", fixup_message); prepare_amend_commit(commit, &sb, &ctx); } } else if (!stat(git_path_merge_msg(the_repository), &statbuf)) { @@ -823,7 +841,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, wt_status_locate_end(sb.buf + merge_msg_start, sb.len - merge_msg_start) < sb.len - merge_msg_start) - merge_contains_scissors = 1; + s->added_cut_line = 1; } else if (!stat(git_path_squash_msg(the_repository), &statbuf)) { if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0) die_errno(_("could not read SQUASH_MSG")); @@ -857,7 +875,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, } s->fp = fopen_for_writing(git_path_commit_editmsg()); - if (s->fp == NULL) + if (!s->fp) die_errno(_("could not open '%s'"), git_path_commit_editmsg()); /* Ignore status.displayCommentPrefix: we do need comments in COMMIT_EDITMSG. */ @@ -871,10 +889,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix, s->hints = 0; if (clean_message_contents) - strbuf_stripspace(&sb, 0); + strbuf_stripspace(&sb, '\0'); if (signoff) - append_signoff(&sb, ignore_non_trailer(sb.buf, sb.len), 0); + append_signoff(&sb, ignored_log_message_bytes(sb.buf, sb.len), 0); if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) die_errno(_("could not write commit template")); @@ -906,9 +924,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, " yourself if you want to.\n" "An empty message aborts the commit.\n"); if (whence != FROM_COMMIT) { - if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS && - !merge_contains_scissors) - wt_status_add_cut_line(s->fp); + if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) + wt_status_add_cut_line(s); status_printf_ln( s, GIT_COLOR_NORMAL, whence == FROM_MERGE ? @@ -928,8 +945,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (cleanup_mode == COMMIT_MSG_CLEANUP_ALL) status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_all, comment_line_char); else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) { - if (whence == FROM_COMMIT && !merge_contains_scissors) - wt_status_add_cut_line(s->fp); + if (whence == FROM_COMMIT) + wt_status_add_cut_line(s); } else /* COMMIT_MSG_CLEANUP_SPACE, that is. */ status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_space, comment_line_char); @@ -976,21 +993,21 @@ static int prepare_to_commit(const char *index_file, const char *prefix, struct object_id oid; const char *parent = "HEAD"; - if (!active_nr && read_cache() < 0) + if (!the_index.initialized && repo_read_index(the_repository) < 0) die(_("Cannot read index")); if (amend) parent = "HEAD^1"; - if (get_oid(parent, &oid)) { + if (repo_get_oid(the_repository, parent, &oid)) { int i, ita_nr = 0; /* TODO: audit for interaction with sparse-index. */ ensure_full_index(&the_index); - for (i = 0; i < active_nr; i++) - if (ce_intent_to_add(active_cache[i])) + for (i = 0; i < the_index.cache_nr; i++) + if (ce_intent_to_add(the_index.cache[i])) ita_nr++; - committable = active_nr - ita_nr > 0; + committable = the_index.cache_nr - ita_nr > 0; } else { /* * Unless the user did explicitly request a submodule @@ -1018,7 +1035,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, struct child_process run_trailer = CHILD_PROCESS_INIT; strvec_pushl(&run_trailer.args, "interpret-trailers", - "--in-place", git_path_commit_editmsg(), NULL); + "--in-place", "--no-divider", + git_path_commit_editmsg(), NULL); strvec_pushv(&run_trailer.args, trailer_args.v); run_trailer.git_cmd = 1; if (run_command(&run_trailer)) @@ -1033,7 +1051,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, */ if (!committable && whence != FROM_MERGE && !allow_empty && !(amend && is_a_merge(current_head))) { - s->hints = advice_status_hints; + s->hints = advice_enabled(ADVICE_STATUS_HINTS); s->display_comment_prefix = old_display_comment_prefix; run_status(stdout, index_file, prefix, 0, s); if (amend) @@ -1051,22 +1069,22 @@ static int prepare_to_commit(const char *index_file, const char *prefix, return 0; } - if (!no_verify && find_hook("pre-commit")) { + if (!no_verify && invoked_hook) { /* - * Re-read the index as pre-commit hook could have updated it, - * and write it out as a tree. We must do this before we invoke + * Re-read the index as the pre-commit-commit hook was invoked + * and could have updated it. We must do this before we invoke * the editor and after we invoke run_status above. */ - discard_cache(); + discard_index(&the_index); } - read_cache_from(index_file); + read_index_from(&the_index, index_file, get_git_dir()); - if (update_main_cache_tree(0)) { + if (cache_tree_update(&the_index, 0)) { error(_("Error building trees")); return 0; } - if (run_commit_hook(use_editor, index_file, "prepare-commit-msg", + if (run_commit_hook(use_editor, index_file, NULL, "prepare-commit-msg", git_path_commit_editmsg(), hook_arg1, hook_arg2, NULL)) return 0; @@ -1083,7 +1101,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, } if (!no_verify && - run_commit_hook(use_editor, index_file, "commit-msg", git_path_commit_editmsg(), NULL)) { + run_commit_hook(use_editor, index_file, NULL, "commit-msg", + git_path_commit_editmsg(), NULL)) { return 0; } @@ -1095,7 +1114,6 @@ static const char *find_author_by_nickname(const char *name) struct rev_info revs; struct commit *commit; struct strbuf buf = STRBUF_INIT; - struct string_list mailmap = STRING_LIST_INIT_NODUP; const char *av[20]; int ac = 0; @@ -1106,7 +1124,8 @@ static const char *find_author_by_nickname(const char *name) av[++ac] = buf.buf; av[++ac] = NULL; setup_revisions(ac, av, &revs, NULL); - revs.mailmap = &mailmap; + revs.mailmap = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(revs.mailmap); read_mailmap(revs.mailmap); if (prepare_revision_walk(&revs)) @@ -1116,8 +1135,9 @@ static const char *find_author_by_nickname(const char *name) struct pretty_print_context ctx = {0}; ctx.date_mode.type = DATE_NORMAL; strbuf_release(&buf); - format_commit_message(commit, "%aN <%aE>", &buf, &ctx); - clear_mailmap(&mailmap); + repo_format_commit_message(the_repository, commit, + "%aN <%aE>", &buf, &ctx); + release_revisions(&revs); return strbuf_detach(&buf, NULL); } die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name); @@ -1162,9 +1182,9 @@ static const char *read_commit_message(const char *name) commit = lookup_commit_reference_by_name(name); if (!commit) - die(_("could not lookup commit %s"), name); + die(_("could not lookup commit '%s'"), name); out_enc = get_commit_output_encoding(); - return logmsg_reencode(commit, NULL, out_enc); + return repo_logmsg_reencode(the_repository, commit, NULL, out_enc); } /* @@ -1192,7 +1212,7 @@ static void finalize_deferred_config(struct wt_status *s) status_format == STATUS_FORMAT_UNSPECIFIED) status_format = STATUS_FORMAT_PORCELAIN; else if (status_format == STATUS_FORMAT_LONG) - die(_("--long and -z are incompatible")); + die(_("options '%s' and '%s' cannot be used together"), "--long", "-z"); } if (use_deferred_config && status_format == STATUS_FORMAT_UNSPECIFIED) @@ -1228,9 +1248,10 @@ static void check_fixup_reword_options(int argc, const char *argv[]) { die(_("You are in the middle of a cherry-pick -- cannot reword.")); } if (argc) - die(_("cannot combine reword option of --fixup with path '%s'"), *argv); + die(_("reword option of '%s' and path '%s' cannot be used together"), "--fixup", *argv); if (patch_interactive || interactive || all || also || only) - die(_("reword option of --fixup is mutually exclusive with --patch/--interactive/--all/--include/--only")); + die(_("reword option of '%s' and '%s' cannot be used together"), + "--fixup", "--patch/--interactive/--all/--include/--only"); } static int parse_and_validate_options(int argc, const char *argv[], @@ -1240,8 +1261,6 @@ static int parse_and_validate_options(int argc, const char *argv[], struct commit *current_head, struct wt_status *s) { - int f = 0; - argc = parse_options(argc, argv, prefix, options, usage, 0); finalize_deferred_config(s); @@ -1249,7 +1268,7 @@ static int parse_and_validate_options(int argc, const char *argv[], force_author = find_author_by_nickname(force_author); if (force_author && renew_authorship) - die(_("Using both --reset-author and --author does not make sense")); + die(_("options '%s' and '%s' cannot be used together"), "--reset-author", "--author"); if (logfile || have_option_m || use_message) use_editor = 0; @@ -1266,20 +1285,16 @@ static int parse_and_validate_options(int argc, const char *argv[], die(_("You are in the middle of a rebase -- cannot amend.")); } if (fixup_message && squash_message) - die(_("Options --squash and --fixup cannot be used together")); - if (use_message) - f++; - if (edit_message) - f++; - if (fixup_message) - f++; - if (logfile) - f++; - if (f > 1) - die(_("Only one of -c/-C/-F/--fixup can be used.")); - if (have_option_m && (edit_message || use_message || logfile)) - die((_("Option -m cannot be combined with -c/-C/-F."))); - if (f || have_option_m) + die(_("options '%s' and '%s' cannot be used together"), "--squash", "--fixup"); + die_for_incompatible_opt4(!!use_message, "-C", + !!edit_message, "-c", + !!logfile, "-F", + !!fixup_message, "--fixup"); + die_for_incompatible_opt4(have_option_m, "-m", + !!edit_message, "-c", + !!use_message, "-C", + !!logfile, "-F"); + if (use_message || edit_message || logfile ||fixup_message || have_option_m) template_file = NULL; if (edit_message) use_message = edit_message; @@ -1304,9 +1319,10 @@ static int parse_and_validate_options(int argc, const char *argv[], if (patch_interactive) interactive = 1; - if (also + only + all + interactive > 1) - die(_("Only one of --include/--only/--all/--interactive/--patch can be used.")); - + die_for_incompatible_opt4(also, "-i/--include", + only, "-o/--only", + all, "-a/--all", + interactive, "--interactive/-p/--patch"); if (fixup_message) { /* * We limit --fixup's suboptions to only alpha characters. @@ -1382,7 +1398,8 @@ static int parse_status_slot(const char *slot) return LOOKUP_CONFIG(color_status_slots, slot); } -static int git_status_config(const char *k, const char *v, void *cb) +static int git_status_config(const char *k, const char *v, + const struct config_context *ctx, void *cb) { struct wt_status *s = cb; const char *slot_name; @@ -1391,7 +1408,8 @@ static int git_status_config(const char *k, const char *v, void *cb) return git_column_config(k, v, "status", &s->colopts); if (!strcmp(k, "status.submodulesummary")) { int is_bool; - s->submodule_summary = git_config_bool_or_int(k, v, &is_bool); + s->submodule_summary = git_config_bool_or_int(k, v, ctx->kvi, + &is_bool); if (is_bool && s->submodule_summary) s->submodule_summary = -1; return 0; @@ -1451,11 +1469,11 @@ static int git_status_config(const char *k, const char *v, void *cb) } if (!strcmp(k, "diff.renamelimit")) { if (s->rename_limit == -1) - s->rename_limit = git_config_int(k, v); + s->rename_limit = git_config_int(k, v, ctx->kvi); return 0; } if (!strcmp(k, "status.renamelimit")) { - s->rename_limit = git_config_int(k, v); + s->rename_limit = git_config_int(k, v, ctx->kvi); return 0; } if (!strcmp(k, "diff.renames")) { @@ -1467,7 +1485,7 @@ static int git_status_config(const char *k, const char *v, void *cb) s->detect_rename = git_config_rename(k, v); return 0; } - return git_diff_ui_config(k, v, NULL); + return git_diff_ui_config(k, v, ctx, NULL); } int cmd_status(int argc, const char **argv, const char *prefix) @@ -1548,11 +1566,11 @@ int cmd_status(int argc, const char **argv, const char *prefix) &s.pathspec, NULL, NULL); if (use_optional_locks()) - fd = hold_locked_index(&index_lock, 0); + fd = repo_hold_locked_index(the_repository, &index_lock, 0); else fd = -1; - s.is_initial = get_oid(s.reference, &oid) ? 1 : 0; + s.is_initial = repo_get_oid(the_repository, s.reference, &oid) ? 1 : 0; if (!s.is_initial) oidcpy(&s.oid_commit, &oid); @@ -1582,10 +1600,10 @@ int cmd_status(int argc, const char **argv, const char *prefix) return 0; } -static int git_commit_config(const char *k, const char *v, void *cb) +static int git_commit_config(const char *k, const char *v, + const struct config_context *ctx, void *cb) { struct wt_status *s = cb; - int status; if (!strcmp(k, "commit.template")) return git_config_pathname(&template_file, k, v); @@ -1601,14 +1619,12 @@ static int git_commit_config(const char *k, const char *v, void *cb) } if (!strcmp(k, "commit.verbose")) { int is_bool; - config_commit_verbose = git_config_bool_or_int(k, v, &is_bool); + config_commit_verbose = git_config_bool_or_int(k, v, ctx->kvi, + &is_bool); return 0; } - status = git_gpg_config(k, v, NULL); - if (status) - return status; - return git_status_config(k, v, s); + return git_status_config(k, v, ctx, s); } int cmd_commit(int argc, const char **argv, const char *prefix) @@ -1632,7 +1648,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) OPT_STRING(0, "fixup", &fixup_message, N_("[(amend|reword):]commit"), N_("use autosquash formatted message to fixup or amend/reword specified commit")), OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")), OPT_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")), - OPT_CALLBACK_F(0, "trailer", NULL, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG, opt_pass_trailer), + OPT_CALLBACK_F(0, "trailer", &trailer_args, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG, opt_pass_trailer), OPT_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")), OPT_FILENAME('t', "template", &template_file, N_("use specified template file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")), @@ -1686,6 +1702,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) struct commit *current_head = NULL; struct commit_extra_header *extra = NULL; struct strbuf err = STRBUF_INIT; + int ret = 0; if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_commit_usage, builtin_commit_options); @@ -1698,11 +1715,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) status_format = STATUS_FORMAT_NONE; /* Ignore status.short */ s.colopts = 0; - if (get_oid("HEAD", &oid)) + if (repo_get_oid(the_repository, "HEAD", &oid)) current_head = NULL; else { current_head = lookup_commit_or_die(&oid, "HEAD"); - if (parse_commit(current_head)) + if (repo_parse_commit(the_repository, current_head)) die(_("could not parse HEAD commit")); } verbose = -1; /* unspecified */ @@ -1720,8 +1737,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix) running hooks, writing the trees, and interacting with the user. */ if (!prepare_to_commit(index_file, prefix, current_head, &s, &author_ident)) { + ret = 1; rollback_index_files(); - return 1; + goto cleanup; } /* Determine parents */ @@ -1813,13 +1831,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix) append_merge_tag_headers(parents, &tail); } - if (commit_tree_extended(sb.buf, sb.len, &active_cache_tree->oid, + if (commit_tree_extended(sb.buf, sb.len, &the_index.cache_tree->oid, parents, &oid, author_ident.buf, NULL, sign_commit, extra)) { rollback_index_files(); die(_("failed to write commit object")); } - strbuf_release(&author_ident); free_commit_extra_headers(extra); if (update_head_with_reflog(current_head, &oid, reflog_msg, &sb, @@ -1836,14 +1853,15 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (commit_index_files()) die(_("repository has been updated, but unable to write\n" - "new_index file. Check that disk is not full and quota is\n" + "new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover.")); git_test_write_commit_graph_or_die(); repo_rerere(the_repository, 0); run_auto_maintenance(quiet); - run_commit_hook(use_editor, get_index_file(), "post-commit", NULL); + run_commit_hook(use_editor, get_index_file(), NULL, "post-commit", + NULL); if (amend && !no_post_rewrite) { commit_post_rewrite(the_repository, current_head, &oid); } @@ -1858,9 +1876,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) &oid, flags); } - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); - UNLEAK(err); - UNLEAK(sb); - return 0; +cleanup: + strbuf_release(&author_ident); + strbuf_release(&err); + strbuf_release(&sb); + return ret; } |