general improvements
[gitweb.git] / builtin / merge.c
index aad5a9504c8546db0adfd36c59cb1ad1918a56e9..c9746e37b86fa15963ae862ad1aaea5ece92562b 100644 (file)
@@ -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()
 };
 
@@ -816,6 +816,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 +854,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);
@@ -892,6 +904,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 +1599,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 +1617,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;
        }
 
        /*