3
#include "tree-walk.h"
4
#include "xdiff-interface.h"
5
#include "object-store.h"
6
+#include "parse-options.h"
7
#include "repository.h"
8
#include "blob.h"
9
#include "exec-cmd.h"
10
#include "merge-blobs.h"
11
11
-static const char merge_tree_usage[] = "git merge-tree <base-tree> <branch1> <branch2>";
12
-
12
struct merge_list {
13
struct merge_list *next;
14
struct merge_list *link; /* other stages for this object */
365
return buf;
366
}
367
369
-static int trivial_merge(int argc, const char **argv)
368
+static int trivial_merge(const char *base,
369
+ const char *branch1,
370
+ const char *branch2)
371
{
372
struct repository *r = the_repository;
373
struct tree_desc t[3];
374
void *buf1, *buf2, *buf3;
375
375
- buf1 = get_tree_descriptor(r, t+0, argv[1]);
376
- buf2 = get_tree_descriptor(r, t+1, argv[2]);
377
- buf3 = get_tree_descriptor(r, t+2, argv[3]);
376
+ buf1 = get_tree_descriptor(r, t+0, base);
377
+ buf2 = get_tree_descriptor(r, t+1, branch1);
378
+ buf3 = get_tree_descriptor(r, t+2, branch2);
379
trivial_merge_trees(t, "");
380
free(buf1);
381
free(buf2);
385
return 0;
386
}
387
388
+enum mode {
389
+ MODE_UNKNOWN,
390
+ MODE_TRIVIAL,
391
+ MODE_REAL,
392
+};
393
+
394
+struct merge_tree_options {
395
+ int mode;
396
+};
397
+
398
+static int real_merge(struct merge_tree_options *o,
399
+ const char *branch1, const char *branch2)
400
+{
401
+ die(_("real merges are not yet implemented"));
402
+}
403
+
404
int cmd_merge_tree(int argc, const char **argv, const char *prefix)
405
{
389
- if (argc != 4)
390
- usage(merge_tree_usage);
391
- return trivial_merge(argc, argv);
406
+ struct merge_tree_options o = { 0 };
407
+ int expected_remaining_argc;
408
+
409
+ const char * const merge_tree_usage[] = {
410
+ N_("git merge-tree [--write-tree] <branch1> <branch2>"),
411
+ N_("git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"),
412
+ NULL
413
+ };
414
+ struct option mt_options[] = {
415
+ OPT_CMDMODE(0, "write-tree", &o.mode,
416
+ N_("do a real merge instead of a trivial merge"),
417
+ MODE_REAL),
418
+ OPT_CMDMODE(0, "trivial-merge", &o.mode,
419
+ N_("do a trivial merge only"), MODE_TRIVIAL),
420
+ OPT_END()
421
+ };
422
+
423
+ /* Parse arguments */
424
+ argc = parse_options(argc, argv, prefix, mt_options,
425
+ merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION);
426
+ switch (o.mode) {
427
+ default:
428
+ BUG("unexpected command mode %d", o.mode);
429
+ case MODE_UNKNOWN:
430
+ switch (argc) {
431
+ default:
432
+ usage_with_options(merge_tree_usage, mt_options);
433
+ case 2:
434
+ o.mode = MODE_REAL;
435
+ break;
436
+ case 3:
437
+ o.mode = MODE_TRIVIAL;
438
+ break;
439
+ }
440
+ expected_remaining_argc = argc;
441
+ break;
442
+ case MODE_REAL:
443
+ expected_remaining_argc = 2;
444
+ break;
445
+ case MODE_TRIVIAL:
446
+ expected_remaining_argc = 3;
447
+ break;
448
+ }
449
+
450
+ if (argc != expected_remaining_argc)
451
+ usage_with_options(merge_tree_usage, mt_options);
452
+
453
+ /* Do the relevant type of merge */
454
+ if (o.mode == MODE_REAL)
455
+ return real_merge(&o, argv[0], argv[1]);
456
+ else
457
+ return trivial_merge(argv[0], argv[1], argv[2]);
458
}