@@ -551,55 +551,105 @@ static VALUE rb_git_blob_to_buffer(int argc, VALUE *argv, VALUE self)
551
551
return rb_ret ;
552
552
}
553
553
554
- static void rugged_parse_merge_file_input (git_merge_file_input * input , VALUE rb_input )
554
+ #define RUGGED_MERGE_FILE_INPUT_INIT { GIT_MERGE_FILE_INPUT_INIT }
555
+
556
+ typedef struct {
557
+ git_merge_file_input parent ;
558
+ int has_id ;
559
+ git_oid id ;
560
+ } rugged_merge_file_input ;
561
+
562
+ static void rugged_parse_merge_file_input (rugged_merge_file_input * input , git_repository * repo , VALUE rb_input )
555
563
{
556
564
VALUE rb_value ;
557
565
558
566
Check_Type (rb_input , T_HASH );
559
567
560
- rb_value = rb_hash_aref (rb_input , CSTR2SYM ("content" ));
561
- if (NIL_P (rb_value ))
562
- rb_raise (rb_eArgError , "File input must have `:content`." );
568
+ if (!NIL_P (rb_value = rb_hash_aref (rb_input , CSTR2SYM ("content" )))) {
569
+ input -> parent .ptr = RSTRING_PTR (rb_value );
570
+ input -> parent .size = RSTRING_LEN (rb_value );
571
+ } else if (!NIL_P (rb_value = rb_hash_aref (rb_input , CSTR2SYM ("oid" )))) {
572
+ if (!repo )
573
+ rb_raise (rb_eArgError , "Rugged repository is required when file input is `:oid`." );
563
574
564
- input -> ptr = RSTRING_PTR (rb_value );
565
- input -> size = RSTRING_LEN (rb_value );
575
+ rugged_exception_check (git_oid_fromstr (& input -> id , RSTRING_PTR (rb_value )));
576
+ input -> has_id = 1 ;
577
+ } else {
578
+ rb_raise (rb_eArgError , "File input must have `:content` or `:oid`." );
579
+ }
566
580
567
581
rb_value = rb_hash_aref (rb_input , CSTR2SYM ("filemode" ));
568
582
if (!NIL_P (rb_value ))
569
- input -> mode = FIX2UINT (rb_value );
583
+ input -> parent . mode = FIX2UINT (rb_value );
570
584
571
585
rb_value = rb_hash_aref (rb_input , CSTR2SYM ("path" ));
572
586
if (!NIL_P (rb_value )) {
573
587
Check_Type (rb_value , T_STRING );
574
- input -> path = RSTRING_PTR (rb_value );
588
+ input -> parent . path = RSTRING_PTR (rb_value );
575
589
}
576
590
}
577
591
592
+ static int rugged_load_merge_file_input (git_blob * * out , git_repository * repo , rugged_merge_file_input * input )
593
+ {
594
+ int error ;
595
+
596
+ if (!input -> has_id )
597
+ return 0 ;
598
+
599
+ if ((error = git_blob_lookup (out , repo , & input -> id )) < 0 )
600
+ return error ;
601
+
602
+ input -> parent .ptr = git_blob_rawcontent (* out );
603
+ input -> parent .size = git_blob_rawsize (* out );
604
+
605
+ return 0 ;
606
+ }
607
+
578
608
static VALUE rb_git_blob_merge_files (int argc , VALUE * argv , VALUE klass )
579
609
{
580
- VALUE rb_ancestor , rb_ours , rb_theirs , rb_options , rb_result ;
610
+ VALUE rb_repo , rb_ancestor , rb_ours , rb_theirs , rb_options , rb_result ;
581
611
582
- git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT ,
583
- ours = GIT_MERGE_FILE_INPUT_INIT ,
584
- theirs = GIT_MERGE_FILE_INPUT_INIT ;
612
+ git_repository * repo = NULL ;
613
+ rugged_merge_file_input ancestor = RUGGED_MERGE_FILE_INPUT_INIT ,
614
+ ours = RUGGED_MERGE_FILE_INPUT_INIT ,
615
+ theirs = RUGGED_MERGE_FILE_INPUT_INIT ;
616
+ git_blob * ancestor_blob = NULL , * our_blob = NULL , * their_blob = NULL ;
585
617
git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT ;
586
618
git_merge_file_result result = {0 };
587
619
int error ;
588
620
589
- rb_scan_args (argc , argv , "31" , & rb_ancestor , & rb_ours , & rb_theirs , & rb_options );
621
+ rb_scan_args (argc , argv , "41" , & rb_repo , & rb_ancestor , & rb_ours , & rb_theirs , & rb_options );
590
622
591
- rugged_parse_merge_file_input (& ancestor , rb_ancestor );
592
- rugged_parse_merge_file_input (& ours , rb_ours );
593
- rugged_parse_merge_file_input (& theirs , rb_theirs );
623
+ if (!NIL_P (rb_repo )) {
624
+ rugged_check_repo (rb_repo );
625
+ Data_Get_Struct (rb_repo , git_repository , repo );
626
+ }
594
627
595
628
if (!NIL_P (rb_options ))
596
629
rugged_parse_merge_file_options (& opts , rb_options );
597
630
598
- rugged_exception_check (git_merge_file (& result , & ancestor , & ours , & theirs , & opts ));
631
+ if (!NIL_P (rb_ancestor ))
632
+ rugged_parse_merge_file_input (& ancestor , repo , rb_ancestor );
633
+ if (!NIL_P (rb_ours ))
634
+ rugged_parse_merge_file_input (& ours , repo , rb_ours );
635
+ if (!NIL_P (rb_theirs ))
636
+ rugged_parse_merge_file_input (& theirs , repo , rb_theirs );
637
+
638
+ if ((error = rugged_load_merge_file_input (& ancestor_blob , repo , & ancestor )) < 0 ||
639
+ (error = rugged_load_merge_file_input (& our_blob , repo , & ours )) < 0 ||
640
+ (error = rugged_load_merge_file_input (& their_blob , repo , & theirs )) < 0 ||
641
+ (error = git_merge_file (& result , & ancestor .parent , & ours .parent , & theirs .parent , & opts )) < 0 )
642
+ goto done ;
599
643
600
644
rb_result = rb_merge_file_result_fromC (& result );
645
+
646
+ done :
647
+ git_blob_free (ancestor_blob );
648
+ git_blob_free (our_blob );
649
+ git_blob_free (their_blob );
601
650
git_merge_file_result_free (& result );
602
651
652
+ rugged_exception_check (error );
603
653
return rb_result ;
604
654
}
605
655
0 commit comments