diff options
Diffstat (limited to 'builtin/merge.c')
-rw-r--r-- | builtin/merge.c | 84 |
1 files changed, 38 insertions, 46 deletions
diff --git a/builtin/merge.c b/builtin/merge.c index aad5a9504c..062e911441 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -81,7 +81,7 @@ static int show_progress = -1; static int default_to_upstream = 1; static int signoff; static const char *sign_commit; -static int verify_msg = 1; +static int no_verify; static struct strategy all_strategy[] = { { "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL }, @@ -287,7 +287,7 @@ static struct option builtin_merge_options[] = { N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")), OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")), - OPT_BOOL(0, "verify", &verify_msg, N_("verify commit-msg hook")), + OPT_BOOL(0, "no-verify", &no_verify, N_("bypass pre-merge-commit and commit-msg hooks")), OPT_END() }; @@ -688,16 +688,13 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, struct commit_list *remoteheads, struct commit *head) { - struct lock_file lock = LOCK_INIT; const char *head_arg = "HEAD"; - hold_locked_index(&lock, LOCK_DIE_ON_ERROR); - refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, &lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) + if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0) return error(_("Unable to write index.")); if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) { + struct lock_file lock = LOCK_INIT; int clean, x; struct commit *result; struct commit_list *reversed = NULL; @@ -816,6 +813,18 @@ static void write_merge_heads(struct commit_list *); static void prepare_to_commit(struct commit_list *remoteheads) { struct strbuf msg = STRBUF_INIT; + const char *index_file = get_index_file(); + + if (!no_verify && run_commit_hook(0 < option_edit, index_file, "pre-merge-commit", NULL)) + abort_commit(remoteheads, NULL); + /* + * Re-read the index as pre-merge-commit hook could have updated it, + * and write it out as a tree. We must do this before we invoke + * the editor and after we invoke run_status above. + */ + if (find_hook("pre-merge-commit")) + discard_cache(); + read_cache_from(index_file); strbuf_addbuf(&msg, &merge_msg); if (squash) BUG("the control must not reach here under --squash"); @@ -842,7 +851,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); } - if (verify_msg && run_commit_hook(0 < option_edit, get_index_file(), + if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(), "commit-msg", git_path_merge_msg(the_repository), NULL)) abort_commit(remoteheads, NULL); @@ -860,12 +869,8 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads) { struct object_id result_tree, result_commit; struct commit_list *parents, **pptr = &parents; - struct lock_file lock = LOCK_INIT; - hold_locked_index(&lock, LOCK_DIE_ON_ERROR); - refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, &lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) + if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0) return error(_("Unable to write index.")); write_tree_trivial(&result_tree); @@ -892,6 +897,7 @@ static int finish_automerge(struct commit *head, struct strbuf buf = STRBUF_INIT; struct object_id result_commit; + write_tree_trivial(result_tree); free_commit_list(common); parents = remoteheads; if (!head_subsumed || fast_forward == FF_NO) @@ -1586,8 +1592,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) save_state(&stash)) oidclr(&stash); - for (i = 0; i < use_strategies_nr; i++) { - int ret; + for (i = 0; !merge_was_ok && i < use_strategies_nr; i++) { + int ret, cnt; if (i) { printf(_("Rewinding the tree to pristine...\n")); restore_state(&head_commit->object.oid, &stash); @@ -1604,40 +1610,26 @@ int cmd_merge(int argc, const char **argv, const char *prefix) ret = try_merge_strategy(use_strategies[i]->name, common, remoteheads, head_commit); - if (!option_commit && !ret) { - merge_was_ok = 1; - /* - * This is necessary here just to avoid writing - * the tree, but later we will *not* exit with - * status code 1 because merge_was_ok is set. - */ - ret = 1; - } - - if (ret) { - /* - * The backend exits with 1 when conflicts are - * left to be resolved, with 2 when it does not - * handle the given merge at all. - */ - if (ret == 1) { - int cnt = evaluate_result(); - - if (best_cnt <= 0 || cnt <= best_cnt) { - best_strategy = use_strategies[i]->name; - best_cnt = cnt; + /* + * The backend exits with 1 when conflicts are + * left to be resolved, with 2 when it does not + * handle the given merge at all. + */ + if (ret < 2) { + if (!ret) { + if (option_commit) { + /* Automerge succeeded. */ + automerge_was_ok = 1; + break; } + merge_was_ok = 1; + } + cnt = evaluate_result(); + if (best_cnt <= 0 || cnt <= best_cnt) { + best_strategy = use_strategies[i]->name; + best_cnt = cnt; } - if (merge_was_ok) - break; - else - continue; } - - /* Automerge succeeded. */ - write_tree_trivial(&result_tree); - automerge_was_ok = 1; - break; } /* |