Merge branch 'jk/gitweb-with-newer-cgi-multi-param' into maint
[gitweb.git] / builtin / merge.c
index b11a528ce5580d5e5b9b61f291e0d829a735ae6a..bebbe5b3081ebe2602abaf0dc9508a1342f01086 100644 (file)
@@ -9,6 +9,7 @@
 #include "cache.h"
 #include "parse-options.h"
 #include "builtin.h"
+#include "lockfile.h"
 #include "run-command.h"
 #include "diff.h"
 #include "refs.h"
@@ -63,7 +64,7 @@ static int verbosity;
 static int allow_rerere_auto;
 static int abort_current_merge;
 static int show_progress = -1;
-static int default_to_upstream;
+static int default_to_upstream = 1;
 static const char *sign_commit;
 
 static struct strategy all_strategy[] = {
@@ -220,7 +221,7 @@ static struct option builtin_merge_options[] = {
        OPT_BOOL(0, "abort", &abort_current_merge,
                N_("abort the current in-progress merge")),
        OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1),
-       { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
+       { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
          N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
        OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
        OPT_END()
@@ -237,11 +238,10 @@ static void drop_save(void)
 static int save_state(unsigned char *stash)
 {
        int len;
-       struct child_process cp;
+       struct child_process cp = CHILD_PROCESS_INIT;
        struct strbuf buffer = STRBUF_INIT;
        const char *argv[] = {"stash", "create", NULL};
 
-       memset(&cp, 0, sizeof(cp));
        cp.argv = argv;
        cp.out = -1;
        cp.git_cmd = 1;
@@ -398,7 +398,7 @@ static void finish(struct commit *head_commit,
                        const char *argv_gc_auto[] = { "gc", "--auto", NULL };
                        update_ref(reflog_message.buf, "HEAD",
                                new_head, head, 0,
-                               DIE_ON_ERR);
+                               UPDATE_REFS_DIE_ON_ERR);
                        /*
                         * We ignore errors in 'gc --auto', since the
                         * user should see them.
@@ -557,7 +557,7 @@ static void parse_branch_merge_options(char *bmo)
        if (argc < 0)
                die(_("Bad branch.%s.mergeoptions string: %s"), branch,
                    split_cmdline_strerror(argc));
-       argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
+       REALLOC_ARRAY(argv, argc + 2);
        memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
        argc++;
        argv[0] = "branch.*.mergeoptions";
@@ -597,6 +597,9 @@ static int git_merge_config(const char *k, const char *v, void *cb)
        } else if (!strcmp(k, "merge.defaulttoupstream")) {
                default_to_upstream = git_config_bool(k, v);
                return 0;
+       } else if (!strcmp(k, "commit.gpgsign")) {
+               sign_commit = git_config_bool(k, v) ? "" : NULL;
+               return 0;
        }
 
        status = fmt_merge_msg_config(k, v, cb);
@@ -654,22 +657,18 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
                              struct commit_list *remoteheads,
                              struct commit *head, const char *head_arg)
 {
-       int index_fd;
-       struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+       static struct lock_file lock;
 
-       index_fd = hold_locked_index(lock, 1);
+       hold_locked_index(&lock, 1);
        refresh_cache(REFRESH_QUIET);
        if (active_cache_changed &&
-                       (write_cache(index_fd, active_cache, active_nr) ||
-                        commit_locked_index(lock)))
+           write_locked_index(&the_index, &lock, COMMIT_LOCK))
                return error(_("Unable to write index."));
-       rollback_lock_file(lock);
+       rollback_lock_file(&lock);
 
        if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) {
                int clean, x;
                struct commit *result;
-               struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
-               int index_fd;
                struct commit_list *reversed = NULL;
                struct merge_options o;
                struct commit_list *j;
@@ -697,14 +696,13 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
                for (j = common; j; j = j->next)
                        commit_list_insert(j->item, &reversed);
 
-               index_fd = hold_locked_index(lock, 1);
+               hold_locked_index(&lock, 1);
                clean = merge_recursive(&o, head,
                                remoteheads->item, reversed, &result);
                if (active_cache_changed &&
-                               (write_cache(index_fd, active_cache, active_nr) ||
-                                commit_locked_index(lock)))
+                   write_locked_index(&the_index, &lock, COMMIT_LOCK))
                        die (_("unable to write %s"), get_index_file());
-               rollback_lock_file(lock);
+               rollback_lock_file(&lock);
                return clean ? 0 : 1;
        } else {
                return try_merge_command(strategy, xopts_nr, xopts,
@@ -840,17 +838,15 @@ static void prepare_to_commit(struct commit_list *remoteheads)
 static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
 {
        unsigned char result_tree[20], result_commit[20];
-       struct commit_list *parent = xmalloc(sizeof(*parent));
+       struct commit_list *parents, **pptr = &parents;
 
        write_tree_trivial(result_tree);
        printf(_("Wonderful.\n"));
-       parent->item = head;
-       parent->next = xmalloc(sizeof(*parent->next));
-       parent->next->item = remoteheads->item;
-       parent->next->next = NULL;
+       pptr = commit_list_append(head, pptr);
+       pptr = commit_list_append(remoteheads->item, pptr);
        prepare_to_commit(remoteheads);
-       if (commit_tree(&merge_msg, result_tree, parent, result_commit, NULL,
-                       sign_commit))
+       if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,
+                       result_commit, NULL, sign_commit))
                die(_("failed to write commit object"));
        finish(head, remoteheads, result_commit, "In-index merge");
        drop_save();
@@ -874,8 +870,8 @@ static int finish_automerge(struct commit *head,
                commit_list_insert(head, &parents);
        strbuf_addch(&merge_msg, '\n');
        prepare_to_commit(remoteheads);
-       if (commit_tree(&merge_msg, result_tree, parents, result_commit,
-                       NULL, sign_commit))
+       if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,
+                       result_commit, NULL, sign_commit))
                die(_("failed to write commit object"));
        strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy);
        finish(head, remoteheads, result_commit, buf.buf);
@@ -1105,7 +1101,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
         * Check if we are _not_ on a detached HEAD, i.e. if there is a
         * current branch.
         */
-       branch = branch_to_free = resolve_refdup("HEAD", head_sha1, 0, &flag);
+       branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, &flag);
        if (branch && starts_with(branch, "refs/heads/"))
                branch += 11;
        if (!branch || is_null_sha1(head_sha1))
@@ -1147,14 +1143,14 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                 */
                if (advice_resolve_conflict)
                        die(_("You have not concluded your merge (MERGE_HEAD exists).\n"
-                                 "Please, commit your changes before you can merge."));
+                                 "Please, commit your changes before you merge."));
                else
                        die(_("You have not concluded your merge (MERGE_HEAD exists)."));
        }
        if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
                if (advice_resolve_conflict)
                        die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
-                           "Please, commit your changes before you can merge."));
+                           "Please, commit your changes before you merge."));
                else
                        die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."));
        }
@@ -1219,7 +1215,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        die(_("%s - not something we can merge"), argv[0]);
                read_empty(remote_head->object.sha1, 0);
                update_ref("initial pull", "HEAD", remote_head->object.sha1,
-                          NULL, 0, DIE_ON_ERR);
+                          NULL, 0, UPDATE_REFS_DIE_ON_ERR);
                goto done;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
@@ -1279,10 +1275,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                                printf(_("Commit %s has a good GPG signature by %s\n"),
                                       hex, signature_check.signer);
 
-                       free(signature_check.gpg_output);
-                       free(signature_check.gpg_status);
-                       free(signature_check.signer);
-                       free(signature_check.key);
+                       signature_check_clear(&signature_check);
                }
        }
 
@@ -1336,7 +1329,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
        }
 
        update_ref("updating ORIG_HEAD", "ORIG_HEAD", head_commit->object.sha1,
-                  NULL, 0, DIE_ON_ERR);
+                  NULL, 0, UPDATE_REFS_DIE_ON_ERR);
 
        if (remoteheads && !common)
                ; /* No common ancestors found. We need a real merge. */