@@ -29,7 +29,7 @@ extern VALUE rb_cRuggedRepo;
2929extern VALUE rb_eRuggedError ;
3030VALUE rb_cRuggedRemote ;
3131
32- #define RUGGED_REMOTE_CALLBACKS_INIT {1, progress_cb, NULL, credentials_cb, NULL, transfer_progress_cb, update_tips_cb, NULL}
32+ #define RUGGED_REMOTE_CALLBACKS_INIT {1, progress_cb, NULL, credentials_cb, NULL, transfer_progress_cb, update_tips_cb, NULL, NULL, push_update_reference_cb, NULL }
3333
3434static int progress_cb (const char * str , int len , void * data )
3535{
@@ -69,6 +69,15 @@ static int transfer_progress_cb(const git_transfer_progress *stats, void *data)
6969 return payload -> exception ? GIT_ERROR : GIT_OK ;
7070}
7171
72+ static int push_update_reference_cb (const char * refname , const char * status , void * data ) {
73+ struct rugged_remote_cb_payload * payload = data ;
74+
75+ if (status != NULL )
76+ rb_hash_aset (payload -> result , rb_str_new_utf8 (refname ), rb_str_new_utf8 (status ));
77+
78+ return GIT_OK ;
79+ }
80+
7281static int update_tips_cb (const char * refname , const git_oid * src , const git_oid * dest , void * data )
7382{
7483 struct rugged_remote_cb_payload * payload = data ;
@@ -164,10 +173,12 @@ void rugged_remote_init_callbacks_and_payload_from_options(
164173 prefilled .payload = payload ;
165174 memcpy (callbacks , & prefilled , sizeof (git_remote_callbacks ));
166175
167- CALLABLE_OR_RAISE (payload -> update_tips , rb_options , "update_tips" );
168- CALLABLE_OR_RAISE (payload -> progress , rb_options , "progress" );
169- CALLABLE_OR_RAISE (payload -> transfer_progress , rb_options , "transfer_progress" );
170- CALLABLE_OR_RAISE (payload -> credentials , rb_options , "credentials" );
176+ if (!NIL_P (rb_options )) {
177+ CALLABLE_OR_RAISE (payload -> update_tips , rb_options , "update_tips" );
178+ CALLABLE_OR_RAISE (payload -> progress , rb_options , "progress" );
179+ CALLABLE_OR_RAISE (payload -> transfer_progress , rb_options , "transfer_progress" );
180+ CALLABLE_OR_RAISE (payload -> credentials , rb_options , "credentials" );
181+ }
171182}
172183
173184static void rb_git_remote__free (git_remote * remote )
@@ -237,7 +248,7 @@ static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self)
237248 git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT ;
238249 const git_remote_head * * heads ;
239250
240- struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , 0 };
251+ struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , Qnil , 0 };
241252
242253 VALUE rb_options ;
243254
@@ -251,8 +262,7 @@ static VALUE rb_git_remote_ls(int argc, VALUE *argv, VALUE self)
251262 if (!rb_block_given_p ())
252263 return rb_funcall (self , rb_intern ("to_enum" ), 2 , CSTR2SYM ("ls" ), rb_options );
253264
254- if (!NIL_P (rb_options ))
255- rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
265+ rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
256266
257267 if ((error = git_remote_set_callbacks (remote , & callbacks )) ||
258268 (error = git_remote_connect (remote , GIT_DIRECTION_FETCH )) ||
@@ -527,7 +537,7 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
527537{
528538 git_remote * remote ;
529539 git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT ;
530- struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , 0 };
540+ struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , Qnil , 0 };
531541 VALUE rb_direction , rb_options ;
532542 ID id_direction ;
533543 int error , direction ;
@@ -544,8 +554,7 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
544554 else
545555 rb_raise (rb_eTypeError , "Invalid direction. Expected :fetch or :push" );
546556
547- if (!NIL_P (rb_options ))
548- rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
557+ rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
549558
550559 if ((error = git_remote_set_callbacks (remote , & callbacks )) < 0 )
551560 goto cleanup ;
@@ -618,7 +627,7 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
618627 git_signature * signature = NULL ;
619628 git_strarray refspecs ;
620629 git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT ;
621- struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , 0 };
630+ struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , Qnil , 0 };
622631
623632 char * log_message = NULL ;
624633 int error ;
@@ -633,6 +642,8 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
633642 rugged_check_repo (rb_repo );
634643 Data_Get_Struct (rb_repo , git_repository , repo );
635644
645+ rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
646+
636647 if (!NIL_P (rb_options )) {
637648 VALUE rb_val = rb_hash_aref (rb_options , CSTR2SYM ("signature" ));
638649 if (!NIL_P (rb_val ))
@@ -641,8 +652,6 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
641652 rb_val = rb_hash_aref (rb_options , CSTR2SYM ("message" ));
642653 if (!NIL_P (rb_val ))
643654 log_message = StringValueCStr (rb_val );
644-
645- rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
646655 }
647656
648657 if ((error = git_remote_set_callbacks (remote , & callbacks )))
@@ -674,15 +683,6 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
674683 return rb_result ;
675684}
676685
677- static int push_status_cb (const char * ref , const char * msg , void * payload )
678- {
679- VALUE rb_result_hash = (VALUE )payload ;
680- if (msg != NULL )
681- rb_hash_aset (rb_result_hash , rb_str_new_utf8 (ref ), rb_str_new_utf8 (msg ));
682-
683- return GIT_OK ;
684- }
685-
686686/*
687687 * call-seq:
688688 * remote.push(refspecs = nil, options = {}) -> hash
@@ -721,36 +721,30 @@ static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
721721{
722722 VALUE rb_refspecs , rb_options , rb_val ;
723723 VALUE rb_repo = rugged_owner (self );
724- VALUE rb_exception = Qnil , rb_result = rb_hash_new ();
725724
726725 git_repository * repo ;
727- git_remote * remote , * tmp_remote = NULL ;
726+ git_remote * remote ;
728727 git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT ;
729- git_push * push = NULL ;
730728 git_signature * signature = NULL ;
729+ git_strarray refspecs ;
730+ git_push_options opts = GIT_PUSH_OPTIONS_INIT ;
731731
732- int error = 0 , i = 0 ;
732+ int error = 0 ;
733733 char * log_message = NULL ;
734734
735- struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , 0 };
735+ struct rugged_remote_cb_payload payload = { Qnil , Qnil , Qnil , Qnil , Qnil , rb_hash_new (), 0 };
736736
737737 rb_scan_args (argc , argv , "01:" , & rb_refspecs , & rb_options );
738738
739- if (!NIL_P (rb_refspecs )) {
740- Check_Type (rb_refspecs , T_ARRAY );
741- for (i = 0 ; i < RARRAY_LEN (rb_refspecs ); ++ i ) {
742- VALUE rb_refspec = rb_ary_entry (rb_refspecs , i );
743- Check_Type (rb_refspec , T_STRING );
744- }
745- }
739+ rugged_rb_ary_to_strarray (rb_refspecs , & refspecs );
746740
747741 rugged_check_repo (rb_repo );
748742 Data_Get_Struct (rb_repo , git_repository , repo );
749743 Data_Get_Struct (self , git_remote , remote );
750744
751- if (!NIL_P (rb_options )) {
752- rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
745+ rugged_remote_init_callbacks_and_payload_from_options (rb_options , & callbacks , & payload );
753746
747+ if (!NIL_P (rb_options )) {
754748 rb_val = rb_hash_aref (rb_options , CSTR2SYM ("message" ));
755749 if (!NIL_P (rb_val ))
756750 log_message = StringValueCStr (rb_val );
@@ -760,64 +754,21 @@ static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
760754 signature = rugged_signature_get (rb_val , repo );
761755 }
762756
763- // Create a temporary remote that we use for pushing
764- if ((error = git_remote_dup (& tmp_remote , remote )) ||
765- (error = git_remote_set_callbacks (tmp_remote , & callbacks )))
757+ if ((error = git_remote_set_callbacks (remote , & callbacks )))
766758 goto cleanup ;
767759
768- if (!NIL_P (rb_refspecs )) {
769- git_remote_clear_refspecs (tmp_remote );
770-
771- for (i = 0 ; !error && i < RARRAY_LEN (rb_refspecs ); ++ i ) {
772- VALUE rb_refspec = rb_ary_entry (rb_refspecs , i );
773-
774- if ((error = git_remote_add_push (tmp_remote , StringValueCStr (rb_refspec ))))
775- goto cleanup ;
776- }
777- }
778-
779- if ((error = git_push_new (& push , tmp_remote )))
780- goto cleanup ;
781-
782- // TODO: Get rid of this once git_remote_push lands in libgit2.
783- {
784- git_strarray push_refspecs ;
785- size_t i ;
786-
787- if ((error = git_remote_get_push_refspecs (& push_refspecs , tmp_remote )))
788- goto cleanup ;
789-
790- if (push_refspecs .count == 0 ) {
791- rb_exception = rb_exc_new2 (rb_eRuggedError , "no pushspecs are configured for the given remote" );
792- goto cleanup ;
793- }
794-
795- for (i = 0 ; !error && i < push_refspecs .count ; ++ i ) {
796- error = git_push_add_refspec (push , push_refspecs .strings [i ]);
797- }
798-
799- git_strarray_free (& push_refspecs );
800- if (error ) goto cleanup ;
801- }
802-
803- if ((error = git_push_finish (push )))
804- goto cleanup ;
805-
806- if ((error = git_push_status_foreach (push , & push_status_cb , (void * )rb_result )) ||
807- (error = git_push_update_tips (push , signature , log_message )))
808- goto cleanup ;
760+ error = git_remote_push (remote , & refspecs , & opts , signature , log_message );
809761
810762cleanup :
811- git_push_free (push );
812- git_remote_free (tmp_remote );
763+ xfree (refspecs .strings );
813764 git_signature_free (signature );
814765
815- if (! NIL_P ( rb_exception ) )
816- rb_exc_raise ( rb_exception );
766+ if (payload . exception )
767+ rb_jump_tag ( payload . exception );
817768
818769 rugged_exception_check (error );
819770
820- return rb_result ;
771+ return payload . result ;
821772}
822773
823774void Init_rugged_remote (void )
0 commit comments