@@ -3,13 +3,12 @@
#include "tree-walk.h"
#include "xdiff-interface.h"
#include "object-store.h"
+#include "parse-options.h"
#include "repository.h"
#include "blob.h"
#include "exec-cmd.h"
#include "merge-blobs.h"
-static const char merge_tree_usage[] = "git merge-tree <base-tree> <branch1> <branch2>";
-
struct merge_list {
struct merge_list *next;
struct merge_list *link; /* other stages for this object */
@@ -366,15 +365,17 @@ static void *get_tree_descriptor(struct repository *r,
return buf;
}
-static int trivial_merge(int argc, const char **argv)
+static int trivial_merge(const char *base,
+ const char *branch1,
+ const char *branch2)
{
struct repository *r = the_repository;
struct tree_desc t[3];
void *buf1, *buf2, *buf3;
- buf1 = get_tree_descriptor(r, t+0, argv[1]);
- buf2 = get_tree_descriptor(r, t+1, argv[2]);
- buf3 = get_tree_descriptor(r, t+2, argv[3]);
+ buf1 = get_tree_descriptor(r, t+0, base);
+ buf2 = get_tree_descriptor(r, t+1, branch1);
+ buf3 = get_tree_descriptor(r, t+2, branch2);
trivial_merge_trees(t, "");
free(buf1);
free(buf2);
@@ -384,9 +385,74 @@ static int trivial_merge(int argc, const char **argv)
return 0;
}
+enum mode {
+ MODE_UNKNOWN,
+ MODE_TRIVIAL,
+ MODE_REAL,
+};
+
+struct merge_tree_options {
+ int mode;
+};
+
+static int real_merge(struct merge_tree_options *o,
+ const char *branch1, const char *branch2)
+{
+ die(_("real merges are not yet implemented"));
+}
+
int cmd_merge_tree(int argc, const char **argv, const char *prefix)
{
- if (argc != 4)
- usage(merge_tree_usage);
- return trivial_merge(argc, argv);
+ struct merge_tree_options o = { 0 };
+ int expected_remaining_argc;
+
+ const char * const merge_tree_usage[] = {
+ N_("git merge-tree [--write-tree] <branch1> <branch2>"),
+ N_("git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"),
+ NULL
+ };
+ struct option mt_options[] = {
+ OPT_CMDMODE(0, "write-tree", &o.mode,
+ N_("do a real merge instead of a trivial merge"),
+ MODE_REAL),
+ OPT_CMDMODE(0, "trivial-merge", &o.mode,
+ N_("do a trivial merge only"), MODE_TRIVIAL),
+ OPT_END()
+ };
+
+ /* Parse arguments */
+ argc = parse_options(argc, argv, prefix, mt_options,
+ merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+ switch (o.mode) {
+ default:
+ BUG("unexpected command mode %d", o.mode);
+ case MODE_UNKNOWN:
+ switch (argc) {
+ default:
+ usage_with_options(merge_tree_usage, mt_options);
+ case 2:
+ o.mode = MODE_REAL;
+ break;
+ case 3:
+ o.mode = MODE_TRIVIAL;
+ break;
+ }
+ expected_remaining_argc = argc;
+ break;
+ case MODE_REAL:
+ expected_remaining_argc = 2;
+ break;
+ case MODE_TRIVIAL:
+ expected_remaining_argc = 3;
+ break;
+ }
+
+ if (argc != expected_remaining_argc)
+ usage_with_options(merge_tree_usage, mt_options);
+
+ /* Do the relevant type of merge */
+ if (o.mode == MODE_REAL)
+ return real_merge(&o, argv[0], argv[1]);
+ else
+ return trivial_merge(argv[0], argv[1], argv[2]);
}
@@ -558,7 +558,7 @@ static struct cmd_struct commands[] = {
{ "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
- { "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT },
+ { "merge-tree", cmd_merge_tree, RUN_SETUP },
{ "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
{ "mktree", cmd_mktree, RUN_SETUP },
{ "multi-pack-index", cmd_multi_pack_index, RUN_SETUP },