10
10
#include <git2/sys/odb_backend.h>
11
11
#include <git2/sys/refdb_backend.h>
12
12
#include <git2/refs.h>
13
+ #include <git2/apply.h>
13
14
14
15
extern VALUE rb_mRugged ;
15
16
extern VALUE rb_eRuggedError ;
@@ -18,6 +19,7 @@ extern VALUE rb_cRuggedConfig;
18
19
extern VALUE rb_cRuggedBackend ;
19
20
extern VALUE rb_cRuggedRemote ;
20
21
extern VALUE rb_cRuggedCommit ;
22
+ extern VALUE rb_cRuggedDiff ;
21
23
extern VALUE rb_cRuggedTag ;
22
24
extern VALUE rb_cRuggedTree ;
23
25
extern VALUE rb_cRuggedReference ;
@@ -868,6 +870,42 @@ static VALUE rb_git_repo_revert_commit(int argc, VALUE *argv, VALUE self)
868
870
return rugged_index_new (rb_cRuggedIndex , self , index );
869
871
}
870
872
873
+ /*
874
+ * call-seq:
875
+ * repo.apply(diff, options = {}) -> true or false
876
+ *
877
+ * Applies the given diff to the repository.
878
+ */
879
+ static VALUE rb_git_repo_apply (int argc , VALUE * argv , VALUE self )
880
+ {
881
+ VALUE rb_diff , rb_options ;
882
+ git_diff * diff ;
883
+ git_repository * repo ;
884
+ git_apply_options opts = GIT_APPLY_OPTIONS_INIT ;
885
+ git_apply_location_t location = GIT_APPLY_LOCATION_BOTH ;
886
+ int error ;
887
+
888
+ rb_scan_args (argc , argv , "11" , & rb_diff , & rb_options );
889
+
890
+ if (!rb_obj_is_kind_of (rb_diff , rb_cRuggedDiff )) {
891
+ rb_raise (rb_eArgError , "Expected a Rugged::Diff." );
892
+ }
893
+
894
+ if (!NIL_P (rb_options )) {
895
+ Check_Type (rb_options , T_HASH );
896
+ rugged_parse_apply_options (& opts , & location , rb_options );
897
+ }
898
+
899
+ Data_Get_Struct (self , git_repository , repo );
900
+ Data_Get_Struct (rb_diff , git_diff , diff );
901
+
902
+ error = git_apply (repo , diff , location , & opts );
903
+
904
+ rugged_exception_check (error );
905
+
906
+ return Qtrue ;
907
+ }
908
+
871
909
/*
872
910
* call-seq:
873
911
* repo.merge_commits(our_commit, their_commit, options = {}) -> index
@@ -2543,6 +2581,33 @@ static VALUE rb_git_repo_cherrypick_commit(int argc, VALUE *argv, VALUE self)
2543
2581
return rugged_index_new (rb_cRuggedIndex , self , index );
2544
2582
}
2545
2583
2584
+ void rugged_parse_apply_options (git_apply_options * opts , git_apply_location_t * location , VALUE rb_options )
2585
+ {
2586
+ if (!NIL_P (rb_options )) {
2587
+ VALUE rb_value ;
2588
+ Check_Type (rb_options , T_HASH );
2589
+
2590
+ rb_value = rb_hash_aref (rb_options , CSTR2SYM ("location" ));
2591
+ if (!NIL_P (rb_value )) {
2592
+ ID id_location ;
2593
+
2594
+ Check_Type (rb_value , T_SYMBOL );
2595
+ id_location = SYM2ID (rb_value );
2596
+
2597
+ if (id_location == rb_intern ("both" )) {
2598
+ * location = GIT_APPLY_LOCATION_BOTH ;
2599
+ } else if (id_location == rb_intern ("index" )) {
2600
+ * location = GIT_APPLY_LOCATION_INDEX ;
2601
+ } else if (id_location == rb_intern ("workdir" )) {
2602
+ * location = GIT_APPLY_LOCATION_WORKDIR ;
2603
+ } else {
2604
+ rb_raise (rb_eTypeError ,
2605
+ "Invalid location. Expected `:both`, `:index`, or `:workdir`" );
2606
+ }
2607
+ }
2608
+ }
2609
+ }
2610
+
2546
2611
void Init_rugged_repo (void )
2547
2612
{
2548
2613
id_call = rb_intern ("call" );
@@ -2598,6 +2663,8 @@ void Init_rugged_repo(void)
2598
2663
rb_define_method (rb_cRuggedRepo , "merge_analysis" , rb_git_repo_merge_analysis , -1 );
2599
2664
rb_define_method (rb_cRuggedRepo , "merge_commits" , rb_git_repo_merge_commits , -1 );
2600
2665
2666
+ rb_define_method (rb_cRuggedRepo , "apply" , rb_git_repo_apply , -1 );
2667
+
2601
2668
rb_define_method (rb_cRuggedRepo , "revert_commit" , rb_git_repo_revert_commit , -1 );
2602
2669
2603
2670
rb_define_method (rb_cRuggedRepo , "path_ignored?" , rb_git_repo_is_path_ignored , 1 );
0 commit comments