3
3
#include "tree-walk.h"
4
4
#include "xdiff-interface.h"
5
5
#include "help.h"
6
+ #include "commit.h"
6
7
#include "commit-reach.h"
7
8
#include "merge-ort.h"
8
9
#include "object-store.h"
@@ -406,6 +407,7 @@ struct merge_tree_options {
406
407
};
407
408
408
409
static int real_merge (struct merge_tree_options * o ,
410
+ const char * merge_base ,
409
411
const char * branch1 , const char * branch2 ,
410
412
const char * prefix )
411
413
{
@@ -432,16 +434,31 @@ static int real_merge(struct merge_tree_options *o,
432
434
opt .branch1 = branch1 ;
433
435
opt .branch2 = branch2 ;
434
436
435
- /*
436
- * Get the merge bases, in reverse order; see comment above
437
- * merge_incore_recursive in merge-ort.h
438
- */
439
- merge_bases = get_merge_bases (parent1 , parent2 );
440
- if (!merge_bases && !o -> allow_unrelated_histories )
441
- die (_ ("refusing to merge unrelated histories" ));
442
- merge_bases = reverse_commit_list (merge_bases );
437
+ if (merge_base ) {
438
+ struct commit * base_commit ;
439
+ struct tree * base_tree , * parent1_tree , * parent2_tree ;
440
+
441
+ base_commit = lookup_commit_reference_by_name (merge_base );
442
+ if (!base_commit )
443
+ die (_ ("could not lookup commit %s" ), merge_base );
444
+
445
+ opt .ancestor = merge_base ;
446
+ base_tree = get_commit_tree (base_commit );
447
+ parent1_tree = get_commit_tree (parent1 );
448
+ parent2_tree = get_commit_tree (parent2 );
449
+ merge_incore_nonrecursive (& opt , base_tree , parent1_tree , parent2_tree , & result );
450
+ } else {
451
+ /*
452
+ * Get the merge bases, in reverse order; see comment above
453
+ * merge_incore_recursive in merge-ort.h
454
+ */
455
+ merge_bases = get_merge_bases (parent1 , parent2 );
456
+ if (!merge_bases && !o -> allow_unrelated_histories )
457
+ die (_ ("refusing to merge unrelated histories" ));
458
+ merge_bases = reverse_commit_list (merge_bases );
459
+ merge_incore_recursive (& opt , merge_bases , parent1 , parent2 , & result );
460
+ }
443
461
444
- merge_incore_recursive (& opt , merge_bases , parent1 , parent2 , & result );
445
462
if (result .clean < 0 )
446
463
die (_ ("failure to merge" ));
447
464
@@ -487,6 +504,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
487
504
struct merge_tree_options o = { .show_messages = -1 };
488
505
int expected_remaining_argc ;
489
506
int original_argc ;
507
+ const char * merge_base = NULL ;
490
508
491
509
const char * const merge_tree_usage [] = {
492
510
N_ ("git merge-tree [--write-tree] [<options>] <branch1> <branch2>" ),
@@ -515,6 +533,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
515
533
& o .use_stdin ,
516
534
N_ ("perform multiple merges, one per line of input" ),
517
535
PARSE_OPT_NONEG ),
536
+ OPT_STRING (0 , "merge-base" ,
537
+ & merge_base ,
538
+ N_ ("commit" ),
539
+ N_ ("specify a merge-base for the merge" )),
518
540
OPT_END ()
519
541
};
520
542
@@ -529,6 +551,8 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
529
551
530
552
if (o .mode == MODE_TRIVIAL )
531
553
die (_ ("--trivial-merge is incompatible with all other options" ));
554
+ if (merge_base )
555
+ die (_ ("--merge-base is incompatible with --stdin" ));
532
556
line_termination = '\0' ;
533
557
while (strbuf_getline_lf (& buf , stdin ) != EOF ) {
534
558
struct strbuf * * split ;
@@ -538,7 +562,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
538
562
if (!split [0 ] || !split [1 ] || split [2 ])
539
563
die (_ ("malformed input line: '%s'." ), buf .buf );
540
564
strbuf_rtrim (split [0 ]);
541
- result = real_merge (& o , split [0 ]-> buf , split [1 ]-> buf , prefix );
565
+ result = real_merge (& o , merge_base , split [0 ]-> buf , split [1 ]-> buf , prefix );
542
566
if (result < 0 )
543
567
die (_ ("merging cannot continue; got unclean result of %d" ), result );
544
568
strbuf_list_free (split );
@@ -581,7 +605,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
581
605
582
606
/* Do the relevant type of merge */
583
607
if (o .mode == MODE_REAL )
584
- return real_merge (& o , argv [0 ], argv [1 ], prefix );
608
+ return real_merge (& o , merge_base , argv [0 ], argv [1 ], prefix );
585
609
else
586
610
return trivial_merge (argv [0 ], argv [1 ], argv [2 ]);
587
611
}
0 commit comments