diff options
Diffstat (limited to 'builtin/merge.c')
-rw-r--r-- | builtin/merge.c | 269 |
1 files changed, 143 insertions, 126 deletions
diff --git a/builtin/merge.c b/builtin/merge.c index de68910177..51038eaca8 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -5,9 +5,9 @@ * * Based on git-merge.sh by Junio C Hamano. */ - -#define USE_THE_INDEX_VARIABLE +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "advice.h" #include "config.h" @@ -18,6 +18,7 @@ #include "object-name.h" #include "parse-options.h" #include "lockfile.h" +#include "repository.h" #include "run-command.h" #include "hook.h" #include "diff.h" @@ -31,8 +32,6 @@ #include "unpack-trees.h" #include "cache-tree.h" #include "dir.h" -#include "utf8.h" -#include "log-tree.h" #include "color.h" #include "rerere.h" #include "help.h" @@ -42,10 +41,8 @@ #include "resolve-undo.h" #include "remote.h" #include "fmt-merge-msg.h" -#include "gpg-interface.h" #include "sequencer.h" #include "string-list.h" -#include "packfile.h" #include "tag.h" #include "alias.h" #include "branch.h" @@ -79,8 +76,7 @@ static int overwrite_ignore = 1; static struct strbuf merge_msg = STRBUF_INIT; static struct strategy **use_strategies; static size_t use_strategies_nr, use_strategies_alloc; -static const char **xopts; -static size_t xopts_nr, xopts_alloc; +static struct strvec xopts = STRVEC_INIT; static const char *branch; static char *branch_mergeoptions; static int verbosity; @@ -106,7 +102,7 @@ static struct strategy all_strategy[] = { { "subtree", NO_FAST_FORWARD | NO_TRIVIAL }, }; -static const char *pull_twohead, *pull_octopus; +static char *pull_twohead, *pull_octopus; enum ff_type { FF_NO, @@ -116,7 +112,7 @@ enum ff_type { static enum ff_type fast_forward = FF_ALLOW; -static const char *cleanup_arg; +static char *cleanup_arg; static enum commit_msg_cleanup_mode cleanup_mode; static int option_parse_message(const struct option *opt, @@ -170,7 +166,7 @@ static struct strategy *get_strategy(const char *name) { int i; struct strategy *ret; - static struct cmdnames main_cmds, other_cmds; + static struct cmdnames main_cmds = {0}, other_cmds = {0}; static int loaded; char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM"); @@ -188,22 +184,22 @@ static struct strategy *get_strategy(const char *name) return &all_strategy[i]; if (!loaded) { - struct cmdnames not_strategies; + struct cmdnames not_strategies = {0}; loaded = 1; - memset(¬_strategies, 0, sizeof(struct cmdnames)); load_command_list("git-merge-", &main_cmds, &other_cmds); for (i = 0; i < main_cmds.cnt; i++) { int j, found = 0; struct cmdname *ent = main_cmds.names[i]; for (j = 0; !found && j < ARRAY_SIZE(all_strategy); j++) - if (!strncmp(ent->name, all_strategy[j].name, ent->len) - && !all_strategy[j].name[ent->len]) + if (!xstrncmpz(all_strategy[j].name, ent->name, ent->len)) found = 1; if (!found) add_cmdname(¬_strategies, ent->name, ent->len); } exclude_cmds(&main_cmds, ¬_strategies); + + cmdnames_release(¬_strategies); } if (!is_in_cmdlist(&main_cmds, name) && !is_in_cmdlist(&other_cmds, name)) { fprintf(stderr, _("Could not find merge strategy '%s'.\n"), name); @@ -223,6 +219,9 @@ static struct strategy *get_strategy(const char *name) CALLOC_ARRAY(ret, 1); ret->name = xstrdup(name); ret->attr = NO_TRIVIAL; + + cmdnames_release(&main_cmds); + cmdnames_release(&other_cmds); return ret; } @@ -232,7 +231,7 @@ static void append_strategy(struct strategy *s) use_strategies[use_strategies_nr++] = s; } -static int option_parse_strategy(const struct option *opt, +static int option_parse_strategy(const struct option *opt UNUSED, const char *name, int unset) { if (unset) @@ -242,29 +241,9 @@ static int option_parse_strategy(const struct option *opt, return 0; } -static int option_parse_x(const struct option *opt, - const char *arg, int unset) -{ - if (unset) - return 0; - - ALLOC_GROW(xopts, xopts_nr + 1, xopts_alloc); - xopts[xopts_nr++] = xstrdup(arg); - return 0; -} - -static int option_parse_n(const struct option *opt, - const char *arg, int unset) -{ - BUG_ON_OPT_ARG(arg); - show_diffstat = unset; - return 0; -} - static struct option builtin_merge_options[] = { - OPT_CALLBACK_F('n', NULL, NULL, NULL, - N_("do not show a diffstat at the end of the merge"), - PARSE_OPT_NOARG, option_parse_n), + OPT_SET_INT('n', NULL, &show_diffstat, + N_("do not show a diffstat at the end of the merge"), 0), OPT_BOOL(0, "stat", &show_diffstat, N_("show a diffstat at the end of the merge")), OPT_BOOL(0, "summary", &show_diffstat, N_("(synonym to --stat)")), @@ -285,10 +264,10 @@ static struct option builtin_merge_options[] = { OPT_RERERE_AUTOUPDATE(&allow_rerere_auto), OPT_BOOL(0, "verify-signatures", &verify_signatures, N_("verify that the named commit has a valid GPG signature")), - OPT_CALLBACK('s', "strategy", &use_strategies, N_("strategy"), + OPT_CALLBACK('s', "strategy", NULL, N_("strategy"), N_("merge strategy to use"), option_parse_strategy), - OPT_CALLBACK('X', "strategy-option", &xopts, N_("option=value"), - N_("option for selected merge strategy"), option_parse_x), + OPT_STRVEC('X', "strategy-option", &xopts, N_("option=value"), + N_("option for selected merge strategy")), OPT_CALLBACK('m', "message", &merge_msg, N_("message"), N_("merge commit message (for a non-fast-forward merge)"), option_parse_message), @@ -326,7 +305,7 @@ static int save_state(struct object_id *stash) int rc = -1; fd = repo_hold_locked_index(the_repository, &lock_file, 0); - refresh_index(&the_index, REFRESH_QUIET, NULL, NULL, NULL); + refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL, NULL); if (0 <= fd) repo_update_index_if_able(the_repository, &lock_file); rollback_lock_file(&lock_file); @@ -357,7 +336,8 @@ static void read_empty(const struct object_id *oid) { struct child_process cmd = CHILD_PROCESS_INIT; - strvec_pushl(&cmd.args, "read-tree", "-m", "-u", empty_tree_oid_hex(), + strvec_pushl(&cmd.args, "read-tree", "-m", "-u", + empty_tree_oid_hex(the_repository->hash_algo), oid_to_hex(oid), NULL); cmd.git_cmd = 1; @@ -398,7 +378,7 @@ static void restore_state(const struct object_id *head, run_command(&cmd); refresh_cache: - discard_index(&the_index); + discard_index(the_repository->index); if (repo_read_index(the_repository) < 0) die(_("could not read index")); } @@ -475,8 +455,10 @@ static void finish(struct commit *head_commit, if (verbosity >= 0 && !merge_msg.len) printf(_("No merge message -- not updating HEAD\n")); else { - update_ref(reflog_message.buf, "HEAD", new_head, head, - 0, UPDATE_REFS_DIE_ON_ERR); + refs_update_ref(get_main_ref_store(the_repository), + reflog_message.buf, "HEAD", new_head, + head, + 0, UPDATE_REFS_DIE_ON_ERR); /* * We ignore errors in 'gc --auto', since the * user should see them. @@ -487,8 +469,7 @@ static void finish(struct commit *head_commit, if (new_head && show_diffstat) { struct diff_options opts; repo_diff_setup(the_repository, &opts); - opts.stat_width = -1; /* use full terminal width */ - opts.stat_graph_width = -1; /* respect statGraphWidth config */ + init_diffstat_widths(&opts); opts.output_format |= DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT; opts.detect_rename = DIFF_DETECT_RENAME; @@ -499,10 +480,10 @@ static void finish(struct commit *head_commit, } /* Run a post-merge hook */ - run_hooks_l("post-merge", squash ? "1" : "0", NULL); + run_hooks_l(the_repository, "post-merge", squash ? "1" : "0", NULL); if (new_head) - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); strbuf_release(&reflog_message); } @@ -520,7 +501,7 @@ static void merge_name(const char *remote, struct strbuf *msg) strbuf_branchname(&bname, remote, 0); remote = bname.buf; - oidclr(&branch_head); + oidclr(&branch_head, the_repository->hash_algo); remote_head = get_merge_parent(remote); if (!remote_head) die(_("'%s' does not point to a commit"), remote); @@ -574,7 +555,7 @@ static void merge_name(const char *remote, struct strbuf *msg) struct strbuf truname = STRBUF_INIT; strbuf_addf(&truname, "refs/heads/%s", remote); strbuf_setlen(&truname, truname.len - len); - if (ref_exists(truname.buf)) { + if (refs_ref_exists(get_main_ref_store(the_repository), truname.buf)) { strbuf_addf(msg, "%s\t\tbranch '%s'%s of .\n", oid_to_hex(&remote_head->object.oid), @@ -637,17 +618,19 @@ static int git_merge_config(const char *k, const char *v, return 0; } - if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat")) + if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat")) { show_diffstat = git_config_bool(k, v); - else if (!strcmp(k, "merge.verifysignatures")) + } else if (!strcmp(k, "merge.verifysignatures")) { verify_signatures = git_config_bool(k, v); - else if (!strcmp(k, "pull.twohead")) + } else if (!strcmp(k, "pull.twohead")) { + FREE_AND_NULL(pull_twohead); return git_config_string(&pull_twohead, k, v); - else if (!strcmp(k, "pull.octopus")) + } else if (!strcmp(k, "pull.octopus")) { + FREE_AND_NULL(pull_octopus); return git_config_string(&pull_octopus, k, v); - else if (!strcmp(k, "commit.cleanup")) + } else if (!strcmp(k, "commit.cleanup")) { return git_config_string(&cleanup_arg, k, v); - else if (!strcmp(k, "merge.ff")) { + } else if (!strcmp(k, "merge.ff")) { int boolval = git_parse_maybe_bool(v); if (0 <= boolval) { fast_forward = boolval ? FF_ALLOW : FF_NO; @@ -684,8 +667,8 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, memset(&opts, 0, sizeof(opts)); opts.head_idx = 2; - opts.src_index = &the_index; - opts.dst_index = &the_index; + opts.src_index = the_repository->index; + opts.dst_index = the_repository->index; opts.update = 1; opts.verbose_update = 1; opts.trivial_merges_only = 1; @@ -701,10 +684,11 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, if (!trees[nr_trees++]) return -1; opts.fn = threeway_merge; - cache_tree_free(&the_index.cache_tree); + cache_tree_free(&the_repository->index->cache_tree); for (i = 0; i < nr_trees; i++) { parse_tree(trees[i]); - init_tree_desc(t+i, trees[i]->buffer, trees[i]->size); + init_tree_desc(t+i, &trees[i]->object.oid, + trees[i]->buffer, trees[i]->size); } if (unpack_trees(nr_trees, t, &opts)) return -1; @@ -713,7 +697,9 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, static void write_tree_trivial(struct object_id *oid) { - if (write_index_as_tree(oid, &the_index, get_index_file(), 0, NULL)) + if (write_index_as_tree(oid, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) die(_("git write-tree failed to write a tree")); } @@ -726,7 +712,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, SKIP_IF_UNCHANGED, 0, NULL, NULL, NULL) < 0) - return error(_("Unable to write index.")); + die(_("Unable to write index.")); if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree") || !strcmp(strategy, "ort")) { @@ -742,16 +728,16 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, return 2; } - init_merge_options(&o, the_repository); + init_ui_merge_options(&o, the_repository); if (!strcmp(strategy, "subtree")) o.subtree_shift = ""; o.show_rename_progress = show_progress == -1 ? isatty(2) : show_progress; - for (x = 0; x < xopts_nr; x++) - if (parse_merge_opt(&o, xopts[x])) - die(_("unknown strategy option: -X%s"), xopts[x]); + for (x = 0; x < xopts.nr; x++) + if (parse_merge_opt(&o, xopts.v[x])) + die(_("unknown strategy option: -X%s"), xopts.v[x]); o.branch1 = head_arg; o.branch2 = merge_remote_util(remoteheads->item)->name; @@ -767,17 +753,20 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, else clean = merge_recursive(&o, head, remoteheads->item, reversed, &result); + free_commit_list(reversed); + strbuf_release(&o.obuf); + if (clean < 0) { rollback_lock_file(&lock); return 2; } - if (write_locked_index(&the_index, &lock, + if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("unable to write %s"), get_index_file()); + die(_("unable to write %s"), repo_get_index_file(the_repository)); return clean ? 0 : 1; } else { return try_merge_command(the_repository, - strategy, xopts_nr, xopts, + strategy, xopts.nr, xopts.v, common, head_arg, remoteheads); } } @@ -794,8 +783,8 @@ static int count_unmerged_entries(void) { int i, ret = 0; - for (i = 0; i < the_index.cache_nr; i++) - if (ce_stage(the_index.cache[i])) + for (i = 0; i < the_repository->index->cache_nr; i++) + if (ce_stage(the_repository->index->cache[i])) ret++; return ret; @@ -848,14 +837,14 @@ static const char scissors_editor_comment[] = N_("An empty message aborts the commit.\n"); static const char no_scissors_editor_comment[] = -N_("Lines starting with '%c' will be ignored, and an empty message aborts\n" +N_("Lines starting with '%s' will be ignored, and an empty message aborts\n" "the commit.\n"); 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(); + const char *index_file = repo_get_index_file(the_repository); if (!no_verify) { int invoked_hook; @@ -869,9 +858,10 @@ static void prepare_to_commit(struct commit_list *remoteheads) * the editor and after we invoke run_status above. */ if (invoked_hook) - discard_index(&the_index); + discard_index(the_repository->index); } - read_index_from(&the_index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, + repo_get_git_dir(the_repository)); strbuf_addbuf(&msg, &merge_msg); if (squash) BUG("the control must not reach here under --squash"); @@ -879,23 +869,23 @@ static void prepare_to_commit(struct commit_list *remoteheads) strbuf_addch(&msg, '\n'); if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) { wt_status_append_cut_line(&msg); - strbuf_commented_addf(&msg, comment_line_char, "\n"); + strbuf_commented_addf(&msg, comment_line_str, "\n"); } - strbuf_commented_addf(&msg, comment_line_char, + strbuf_commented_addf(&msg, comment_line_str, _(merge_editor_comment)); if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) - strbuf_commented_addf(&msg, comment_line_char, + strbuf_commented_addf(&msg, comment_line_str, _(scissors_editor_comment)); else - strbuf_commented_addf(&msg, comment_line_char, - _(no_scissors_editor_comment), comment_line_char); + strbuf_commented_addf(&msg, comment_line_str, + _(no_scissors_editor_comment), comment_line_str); } if (signoff) - append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0); + append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0); write_merge_heads(remoteheads); write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len); - if (run_commit_hook(0 < option_edit, get_index_file(), NULL, - "prepare-commit-msg", + if (run_commit_hook(0 < option_edit, repo_get_index_file(the_repository), + NULL, "prepare-commit-msg", git_path_merge_msg(the_repository), "merge", NULL)) abort_commit(remoteheads, NULL); if (0 < option_edit) { @@ -903,7 +893,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); } - if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(), + if (!no_verify && run_commit_hook(0 < option_edit, repo_get_index_file(the_repository), NULL, "commit-msg", git_path_merge_msg(the_repository), NULL)) abort_commit(remoteheads, NULL); @@ -920,7 +910,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) 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 commit_list *parents = NULL, **pptr = &parents; if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, SKIP_IF_UNCHANGED, 0, NULL, NULL, @@ -936,7 +926,9 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads) &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); finish(head, remoteheads, &result_commit, "In-index merge"); + remove_merge_branch_state(the_repository); + free_commit_list(parents); return 0; } @@ -962,8 +954,10 @@ static int finish_automerge(struct commit *head, die(_("failed to write commit object")); strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy); finish(head, remoteheads, &result_commit, buf.buf); + strbuf_release(&buf); remove_merge_branch_state(the_repository); + free_commit_list(parents); return 0; } @@ -983,7 +977,7 @@ static int suggest_conflicts(void) * Thus, we will get the cleanup mode which is returned when we _are_ * using an editor. */ - append_conflicts_hint(&the_index, &msgbuf, + append_conflicts_hint(the_repository->index, &msgbuf, get_cleanup_mode(cleanup_arg, 1)); fputs(msgbuf.buf, fp); strbuf_release(&msgbuf); @@ -1278,7 +1272,7 @@ static int merging_a_throwaway_tag(struct commit *commit) */ tag_ref = xstrfmt("refs/tags/%s", ((struct tag *)merge_remote_util(commit)->obj)->tag); - if (!read_ref(tag_ref, &oid) && + if (!refs_read_ref(get_main_ref_store(the_repository), tag_ref, &oid) && oideq(&oid, &merge_remote_util(commit)->obj->oid)) is_throwaway_tag = 0; else @@ -1287,7 +1281,10 @@ static int merging_a_throwaway_tag(struct commit *commit) return is_throwaway_tag; } -int cmd_merge(int argc, const char **argv, const char *prefix) +int cmd_merge(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct object_id result_tree, stash, head_oid; struct commit *head_commit; @@ -1310,14 +1307,16 @@ 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", 0, &head_oid, NULL); + branch = branch_to_free = refs_resolve_refdup(get_main_ref_store(the_repository), + "HEAD", 0, &head_oid, + NULL); if (branch) skip_prefix(branch, "refs/heads/", &branch); if (!pull_twohead) { char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM"); if (default_strategy && !strcmp(default_strategy, "ort")) - pull_twohead = "ort"; + pull_twohead = xstrdup("ort"); } init_diff_ui_defaults(); @@ -1341,7 +1340,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (abort_current_merge) { int nargc = 2; const char *nargv[] = {"reset", "--merge", NULL}; - struct strbuf stash_oid = STRBUF_INIT; + char stash_oid_hex[GIT_MAX_HEXSZ + 1]; + struct object_id stash_oid = {0}; if (orig_argc != 2) usage_msg_opt(_("--abort expects no arguments"), @@ -1350,17 +1350,19 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (!file_exists(git_path_merge_head(the_repository))) die(_("There is no merge to abort (MERGE_HEAD missing).")); - if (read_oneliner(&stash_oid, git_path_merge_autostash(the_repository), - READ_ONELINER_SKIP_IF_EMPTY)) - unlink(git_path_merge_autostash(the_repository)); + if (!refs_read_ref(get_main_ref_store(the_repository), "MERGE_AUTOSTASH", &stash_oid)) + refs_delete_ref(get_main_ref_store(the_repository), + "", "MERGE_AUTOSTASH", &stash_oid, + REF_NO_DEREF); /* Invoke 'git reset --merge' */ - ret = cmd_reset(nargc, nargv, prefix); + ret = cmd_reset(nargc, nargv, prefix, the_repository); - if (stash_oid.len) - apply_autostash_oid(stash_oid.buf); + if (!is_null_oid(&stash_oid)) { + oid_to_hex_r(stash_oid_hex, &stash_oid); + apply_autostash_oid(stash_oid_hex); + } - strbuf_release(&stash_oid); goto done; } @@ -1386,7 +1388,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die(_("There is no merge in progress (MERGE_HEAD missing).")); /* Invoke 'git commit' */ - ret = cmd_commit(nargc, nargv, prefix); + ret = cmd_commit(nargc, nargv, prefix, the_repository); goto done; } @@ -1404,14 +1406,14 @@ int cmd_merge(int argc, const char **argv, const char *prefix) else die(_("You have not concluded your merge (MERGE_HEAD exists).")); } - if (ref_exists("CHERRY_PICK_HEAD")) { + if (refs_ref_exists(get_main_ref_store(the_repository), "CHERRY_PICK_HEAD")) { if (advice_enabled(ADVICE_RESOLVE_CONFLICT)) die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge.")); else die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).")); } - resolve_undo_clear_index(&the_index); + resolve_undo_clear_index(the_repository->index); if (option_edit < 0) option_edit = default_edit_option(); @@ -1475,8 +1477,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix) remote_head_oid = &remoteheads->item->object.oid; read_empty(remote_head_oid); - update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0, - UPDATE_REFS_DIE_ON_ERR); + refs_update_ref(get_main_ref_store(the_repository), + "initial pull", "HEAD", remote_head_oid, NULL, + 0, + UPDATE_REFS_DIE_ON_ERR); goto done; } @@ -1539,18 +1543,27 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (!remoteheads) ; /* already up-to-date */ - else if (!remoteheads->next) - common = repo_get_merge_bases(the_repository, head_commit, - remoteheads->item); - else { + else if (!remoteheads->next) { + if (repo_get_merge_bases(the_repository, head_commit, + remoteheads->item, &common) < 0) { + ret = 2; + goto done; + } + } else { struct commit_list *list = remoteheads; commit_list_insert(head_commit, &list); - common = get_octopus_merge_bases(list); + if (get_octopus_merge_bases(list, &common) < 0) { + free(list); + ret = 2; + goto done; + } free(list); } - update_ref("updating ORIG_HEAD", "ORIG_HEAD", - &head_commit->object.oid, NULL, 0, UPDATE_REFS_DIE_ON_ERR); + refs_update_ref(get_main_ref_store(the_repository), + "updating ORIG_HEAD", "ORIG_HEAD", + &head_commit->object.oid, NULL, 0, + UPDATE_REFS_DIE_ON_ERR); if (remoteheads && !common) { /* No common ancestors found. */ @@ -1589,13 +1602,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } if (autostash) - create_autostash(the_repository, - git_path_merge_autostash(the_repository)); + create_autostash_ref(the_repository, "MERGE_AUTOSTASH"); if (checkout_fast_forward(the_repository, &head_commit->object.oid, &commit->object.oid, overwrite_ignore)) { - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); ret = 1; goto done; } @@ -1614,7 +1626,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * We are not doing octopus, not fast-forward, and have * only one common. */ - refresh_index(&the_index, REFRESH_QUIET, NULL, NULL, NULL); + refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL, NULL); if (allow_trivial && fast_forward != FF_ONLY) { /* * Must first ensure that index matches HEAD before @@ -1653,17 +1665,21 @@ int cmd_merge(int argc, const char **argv, const char *prefix) struct commit_list *j; for (j = remoteheads; j; j = j->next) { - struct commit_list *common_one; + struct commit_list *common_one = NULL; + struct commit *common_item; /* * Here we *have* to calculate the individual * merge_bases again, otherwise "git merge HEAD^ * HEAD^^" would be missed. */ - common_one = repo_get_merge_bases(the_repository, - head_commit, - j->item); - if (!oideq(&common_one->item->object.oid, &j->item->object.oid)) { + if (repo_get_merge_bases(the_repository, head_commit, + j->item, &common_one) < 0) + exit(128); + + common_item = common_one->item; + free_commit_list(common_one); + if (!oideq(&common_item->object.oid, &j->item->object.oid)) { up_to_date = 0; break; } @@ -1678,8 +1694,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die_ff_impossible(); if (autostash) - create_autostash(the_repository, - git_path_merge_autostash(the_repository)); + create_autostash_ref(the_repository, "MERGE_AUTOSTASH"); /* We are going to make a new commit. */ git_committer_info(IDENT_STRICT); @@ -1697,7 +1712,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * index and working tree polluted. */ if (save_state(&stash)) - oidclr(&stash); + oidclr(&stash, the_repository->hash_algo); for (i = 0; i < use_strategies_nr; i++) { int ret, cnt; @@ -1764,7 +1779,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) else fprintf(stderr, _("Merge with strategy %s failed.\n"), use_strategies[0]->name); - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); ret = 2; goto done; } else if (best_strategy == wt_strategy) @@ -1800,6 +1815,8 @@ done: } strbuf_release(&buf); free(branch_to_free); - discard_index(&the_index); + free(pull_twohead); + free(pull_octopus); + discard_index(the_repository->index); return ret; } |