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,16 +551,35 @@ 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 ;
535
559
int result ;
560
+ const char * input_merge_base = NULL ;
536
561
537
562
split = strbuf_split (& buf , ' ' );
538
- if (!split [0 ] || !split [1 ] || split [ 2 ] )
563
+ if (!split [0 ] || !split [1 ])
539
564
die (_ ("malformed input line: '%s'." ), buf .buf );
540
565
strbuf_rtrim (split [0 ]);
541
- result = real_merge (& o , split [0 ]-> buf , split [1 ]-> buf , prefix );
566
+ strbuf_rtrim (split [1 ]);
567
+
568
+ /* parse the merge-base */
569
+ if (!strcmp (split [1 ]-> buf , "--" )) {
570
+ input_merge_base = split [0 ]-> buf ;
571
+ }
572
+
573
+ if (input_merge_base && split [2 ] && split [3 ] && !split [4 ]) {
574
+ strbuf_rtrim (split [2 ]);
575
+ strbuf_rtrim (split [3 ]);
576
+ result = real_merge (& o , input_merge_base , split [2 ]-> buf , split [3 ]-> buf , prefix );
577
+ } else if (!input_merge_base && !split [2 ]) {
578
+ result = real_merge (& o , NULL , split [0 ]-> buf , split [1 ]-> buf , prefix );
579
+ } else {
580
+ die (_ ("malformed input line: '%s'." ), buf .buf );
581
+ }
582
+
542
583
if (result < 0 )
543
584
die (_ ("merging cannot continue; got unclean result of %d" ), result );
544
585
strbuf_list_free (split );
@@ -581,7 +622,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
581
622
582
623
/* Do the relevant type of merge */
583
624
if (o .mode == MODE_REAL )
584
- return real_merge (& o , argv [0 ], argv [1 ], prefix );
625
+ return real_merge (& o , merge_base , argv [0 ], argv [1 ], prefix );
585
626
else
586
627
return trivial_merge (argv [0 ], argv [1 ], argv [2 ]);
587
628
}
0 commit comments