diff options
Diffstat (limited to 'builtin/merge-tree.c')
-rw-r--r-- | builtin/merge-tree.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 828dc81c42..3bdec53fbe 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -3,16 +3,21 @@ #include "tree-walk.h" #include "xdiff-interface.h" #include "help.h" +#include "gettext.h" +#include "hex.h" #include "commit.h" #include "commit-reach.h" #include "merge-ort.h" -#include "object-store.h" +#include "object-name.h" +#include "object-store-ll.h" #include "parse-options.h" #include "repository.h" #include "blob.h" -#include "exec-cmd.h" #include "merge-blobs.h" #include "quote.h" +#include "tree.h" +#include "config.h" +#include "strvec.h" static int line_termination = '\n'; @@ -69,7 +74,9 @@ static void *result(struct merge_list *entry, unsigned long *size) const char *path = entry->path; if (!entry->stage) - return read_object_file(&entry->blob->object.oid, &type, size); + return repo_read_object_file(the_repository, + &entry->blob->object.oid, &type, + size); base = NULL; if (entry->stage == 1) { base = entry->blob; @@ -92,8 +99,9 @@ static void *origin(struct merge_list *entry, unsigned long *size) enum object_type type; while (entry) { if (entry->stage == 2) - return read_object_file(&entry->blob->object.oid, - &type, size); + return repo_read_object_file(the_repository, + &entry->blob->object.oid, + &type, size); entry = entry->link; } return NULL; @@ -316,7 +324,9 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3]) * The successful merge rules are the same as for the three-way merge * in git-read-tree. */ -static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *info) +static int threeway_callback(int n UNUSED, unsigned long mask, + unsigned long dirmask UNUSED, + struct name_entry *entry, struct traverse_info *info) { /* Same in both? */ if (same_entry(entry+1, entry+2) || both_empty(entry+1, entry+2)) { @@ -404,6 +414,7 @@ struct merge_tree_options { int show_messages; int name_only; int use_stdin; + struct merge_options merge_options; }; static int real_merge(struct merge_tree_options *o, @@ -413,10 +424,11 @@ static int real_merge(struct merge_tree_options *o, { struct commit *parent1, *parent2; struct commit_list *merge_bases = NULL; - struct merge_options opt; struct merge_result result = { 0 }; int show_messages = o->show_messages; + struct merge_options opt; + copy_merge_options(&opt, &o->merge_options); parent1 = get_merge_parent(branch1); if (!parent1) help_unknown_ref(branch1, "merge-tree", @@ -427,8 +439,6 @@ static int real_merge(struct merge_tree_options *o, help_unknown_ref(branch2, "merge-tree", _("not something we can merge")); - init_merge_options(&opt, the_repository); - opt.show_rename_progress = 0; opt.branch1 = branch1; @@ -440,19 +450,20 @@ static int real_merge(struct merge_tree_options *o, base_commit = lookup_commit_reference_by_name(merge_base); if (!base_commit) - die(_("could not lookup commit %s"), merge_base); + die(_("could not lookup commit '%s'"), merge_base); opt.ancestor = merge_base; - base_tree = get_commit_tree(base_commit); - parent1_tree = get_commit_tree(parent1); - parent2_tree = get_commit_tree(parent2); + base_tree = repo_get_commit_tree(the_repository, base_commit); + parent1_tree = repo_get_commit_tree(the_repository, parent1); + parent2_tree = repo_get_commit_tree(the_repository, parent2); merge_incore_nonrecursive(&opt, base_tree, parent1_tree, parent2_tree, &result); } else { /* * Get the merge bases, in reverse order; see comment above * merge_incore_recursive in merge-ort.h */ - merge_bases = get_merge_bases(parent1, parent2); + merge_bases = repo_get_merge_bases(the_repository, parent1, + parent2); if (!merge_bases && !o->allow_unrelated_histories) die(_("refusing to merge unrelated histories")); merge_bases = reverse_commit_list(merge_bases); @@ -496,12 +507,14 @@ static int real_merge(struct merge_tree_options *o, if (o->use_stdin) putchar(line_termination); merge_finalize(&opt, &result); + clear_merge_options(&opt); return !result.clean; /* result.clean < 0 handled above */ } int cmd_merge_tree(int argc, const char **argv, const char *prefix) { struct merge_tree_options o = { .show_messages = -1 }; + struct strvec xopts = STRVEC_INIT; int expected_remaining_argc; int original_argc; const char *merge_base = NULL; @@ -537,14 +550,25 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) &merge_base, N_("commit"), N_("specify a merge-base for the merge")), + OPT_STRVEC('X', "strategy-option", &xopts, N_("option=value"), + N_("option for selected merge strategy")), OPT_END() }; + /* Init merge options */ + init_merge_options(&o.merge_options, the_repository); + /* Parse arguments */ original_argc = argc - 1; /* ignoring argv[0] */ argc = parse_options(argc, argv, prefix, mt_options, merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (xopts.nr && o.mode == MODE_TRIVIAL) + die(_("--trivial-merge is incompatible with all other options")); + for (int x = 0; x < xopts.nr; x++) + if (parse_merge_opt(&o.merge_options, xopts.v[x])) + die(_("unknown strategy option: -X%s"), xopts.v[x]); + /* Handle --stdin */ if (o.use_stdin) { struct strbuf buf = STRBUF_INIT; @@ -552,7 +576,8 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) if (o.mode == MODE_TRIVIAL) die(_("--trivial-merge is incompatible with all other options")); if (merge_base) - die(_("--merge-base is incompatible with --stdin")); + die(_("options '%s' and '%s' cannot be used together"), + "--merge-base", "--stdin"); line_termination = '\0'; while (strbuf_getline_lf(&buf, stdin) != EOF) { struct strbuf **split; @@ -620,6 +645,8 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) if (argc != expected_remaining_argc) usage_with_options(merge_tree_usage, mt_options); + git_config(git_default_config, NULL); + /* Do the relevant type of merge */ if (o.mode == MODE_REAL) return real_merge(&o, merge_base, argv[0], argv[1], prefix); |