@@ -670,21 +670,59 @@ int git_remote_set_pushurl(git_repository *repo, const char *remote, const char*
670
670
return set_url (repo , remote , CONFIG_PUSHURL_FMT , url );
671
671
}
672
672
673
- const char * git_remote__urlfordirection ( git_remote * remote , int direction )
673
+ static int resolve_url ( git_buf * resolved_url , const char * url , int direction , const git_remote_callbacks * callbacks )
674
674
{
675
- assert ( remote ) ;
675
+ int status ;
676
676
677
- assert (direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH );
677
+ if (!callbacks || !callbacks -> resolve_url ) {
678
+ git_buf_sets (resolved_url , url );
679
+ return 0 ;
680
+ }
681
+
682
+ /* Allocate a generous buffer to cater for most */
683
+ git_buf_clear (resolved_url );
684
+ git_buf_grow (resolved_url , 256 );
685
+ GIT_ERROR_CHECK_ALLOC_BUF (resolved_url );
686
+
687
+ do {
688
+ status = callbacks -> resolve_url (resolved_url , url , direction , callbacks -> payload );
689
+ if (status == GIT_PASSTHROUGH ) {
690
+ git_buf_sets (resolved_url , url );
691
+ return 0 ;
692
+ }
693
+ if (status <= 0 )
694
+ return status ;
695
+
696
+ /* A positive value tells us what's actually needed */
697
+ git_buf_grow (resolved_url , status );
698
+ GIT_ERROR_CHECK_ALLOC_BUF (resolved_url );
699
+ } while (status > 0 );
700
+
701
+ return 0 ;
702
+ }
703
+
704
+ int git_remote__urlfordirection (git_buf * url_out , struct git_remote * remote , int direction , const git_remote_callbacks * callbacks )
705
+ {
706
+ const char * url = NULL ;
707
+
708
+ assert (remote );
678
709
679
710
if (direction == GIT_DIRECTION_FETCH ) {
680
- return remote -> url ;
711
+ url = remote -> url ;
712
+ } else if (direction == GIT_DIRECTION_PUSH ) {
713
+ url = remote -> pushurl ? remote -> pushurl : remote -> url ;
714
+ } else {
715
+ assert (direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH );
681
716
}
682
717
683
- if (direction == GIT_DIRECTION_PUSH ) {
684
- return remote -> pushurl ? remote -> pushurl : remote -> url ;
718
+ if (!url ) {
719
+ git_error_set (GIT_ERROR_INVALID ,
720
+ "Malformed remote '%s' - missing %s URL" ,
721
+ remote -> name ? remote -> name : "(anonymous)" ,
722
+ direction == GIT_DIRECTION_FETCH ? "fetch" : "push" );
723
+ return GIT_ERROR_INVALID ;
685
724
}
686
-
687
- return NULL ;
725
+ return resolve_url (url_out , url , direction , callbacks );
688
726
}
689
727
690
728
int set_transport_callbacks (git_transport * t , const git_remote_callbacks * cbs )
@@ -704,10 +742,34 @@ static int set_transport_custom_headers(git_transport *t, const git_strarray *cu
704
742
return t -> set_custom_headers (t , custom_headers );
705
743
}
706
744
707
- int git_remote__connect (git_remote * remote , git_direction direction , const git_remote_callbacks * callbacks , const git_remote_connection_opts * conn )
745
+ int git_struct__upgrade_remote_callbacks (
746
+ git_remote_callbacks * new ,
747
+ const git_struct__version * old ,
748
+ const char * name )
749
+ {
750
+ unsigned int latest = old -> version ;
751
+ size_t size ;
752
+
753
+ GIT_UNUSED (name );
754
+
755
+ switch (old -> version ) {
756
+ case 1 :
757
+ size = sizeof (new ) - sizeof (git_resolve_url_cb );
758
+ memcpy (new , old , size );
759
+ new -> version = latest ;
760
+ break ;
761
+
762
+ default :
763
+ break ;
764
+ }
765
+ return 0 ;
766
+ }
767
+
768
+ int git_remote__connect (git_remote * remote , git_direction direction , const git_remote_callbacks * given_callbacks , const git_remote_connection_opts * conn )
708
769
{
709
- git_transport * t ;
710
- const char * url ;
770
+ git_transport * t = NULL ;
771
+ git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT ;
772
+ git_buf url = GIT_BUF_INIT ;
711
773
int flags = GIT_TRANSPORTFLAGS_NONE ;
712
774
int error ;
713
775
void * payload = NULL ;
@@ -716,51 +778,48 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r
716
778
717
779
assert (remote );
718
780
719
- if (callbacks ) {
720
- GIT_ERROR_CHECK_VERSION (callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" );
721
- credentials = callbacks -> credentials ;
722
- transport = callbacks -> transport ;
723
- payload = callbacks -> payload ;
724
- }
781
+ GIT_STRUCT_UPGRADE (& callbacks , sizeof (callbacks ), given_callbacks , "git_remote_callbacks" , git_struct__upgrade_remote_callbacks );
782
+ credentials = callbacks .credentials ;
783
+ transport = callbacks .transport ;
784
+ payload = callbacks .payload ;
725
785
726
786
if (conn -> proxy )
727
787
GIT_ERROR_CHECK_VERSION (conn -> proxy , GIT_PROXY_OPTIONS_VERSION , "git_proxy_options" );
728
788
729
789
t = remote -> transport ;
730
790
731
- url = git_remote__urlfordirection (remote , direction );
732
- if (url == NULL ) {
733
- git_error_set (GIT_ERROR_INVALID ,
734
- "Malformed remote '%s' - missing %s URL" ,
735
- remote -> name ? remote -> name : "(anonymous)" ,
736
- direction == GIT_DIRECTION_FETCH ? "fetch" : "push" );
737
- return -1 ;
738
- }
791
+ if ((error = git_remote__urlfordirection (& url , remote , direction , & callbacks )))
792
+ goto on_error ;
739
793
740
794
/* If we don't have a transport object yet, and the caller specified a
741
795
* custom transport factory, use that */
742
796
if (!t && transport &&
743
797
(error = transport (& t , remote , payload )) < 0 )
744
- return error ;
798
+ goto on_error ;
745
799
746
800
/* If we still don't have a transport, then use the global
747
801
* transport registrations which map URI schemes to transport factories */
748
- if (!t && (error = git_transport_new (& t , remote , url )) < 0 )
749
- return error ;
802
+ if (!t && (error = git_transport_new (& t , remote , url . ptr )) < 0 )
803
+ goto on_error ;
750
804
751
805
if ((error = set_transport_custom_headers (t , conn -> custom_headers )) != 0 )
752
806
goto on_error ;
753
807
754
- if ((error = set_transport_callbacks (t , callbacks )) < 0 ||
755
- (error = t -> connect (t , url , credentials , payload , conn -> proxy , direction , flags )) != 0 )
808
+ if ((error = set_transport_callbacks (t , & callbacks )) < 0 ||
809
+ (error = t -> connect (t , url . ptr , credentials , payload , conn -> proxy , direction , flags )) != 0 )
756
810
goto on_error ;
757
811
758
812
remote -> transport = t ;
759
813
814
+ git_buf_dispose (& url );
815
+
760
816
return 0 ;
761
817
762
818
on_error :
763
- t -> free (t );
819
+ if (t )
820
+ t -> free (t );
821
+
822
+ git_buf_dispose (& url );
764
823
765
824
if (t == remote -> transport )
766
825
remote -> transport = NULL ;
@@ -922,7 +981,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
922
981
int error = -1 ;
923
982
size_t i ;
924
983
git_vector * to_active , specs = GIT_VECTOR_INIT , refs = GIT_VECTOR_INIT ;
925
- const git_remote_callbacks * cbs = NULL ;
984
+ git_remote_callbacks cbs = GIT_REMOTE_CALLBACKS_INIT ;
926
985
const git_strarray * custom_headers = NULL ;
927
986
const git_proxy_options * proxy = NULL ;
928
987
@@ -934,15 +993,14 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
934
993
}
935
994
936
995
if (opts ) {
937
- GIT_ERROR_CHECK_VERSION (& opts -> callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" );
938
- cbs = & opts -> callbacks ;
996
+ GIT_STRUCT_UPGRADE (& cbs , sizeof (cbs ), & opts -> callbacks , "git_remote_callbacks" , git_struct__upgrade_remote_callbacks );
939
997
custom_headers = & opts -> custom_headers ;
940
998
GIT_ERROR_CHECK_VERSION (& opts -> proxy_opts , GIT_PROXY_OPTIONS_VERSION , "git_proxy_options" );
941
999
proxy = & opts -> proxy_opts ;
942
1000
}
943
1001
944
1002
if (!git_remote_connected (remote ) &&
945
- (error = git_remote_connect (remote , GIT_DIRECTION_FETCH , cbs , proxy , custom_headers )) < 0 )
1003
+ (error = git_remote_connect (remote , GIT_DIRECTION_FETCH , & cbs , proxy , custom_headers )) < 0 )
946
1004
goto on_error ;
947
1005
948
1006
if (ls_to_vector (& refs , remote ) < 0 )
@@ -986,7 +1044,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
986
1044
if ((error = git_fetch_negotiate (remote , opts )) < 0 )
987
1045
return error ;
988
1046
989
- return git_fetch_download_pack (remote , cbs );
1047
+ return git_fetch_download_pack (remote , & cbs );
990
1048
991
1049
on_error :
992
1050
git_vector_free (& refs );
@@ -1005,12 +1063,11 @@ int git_remote_fetch(
1005
1063
git_remote_autotag_option_t tagopt = remote -> download_tags ;
1006
1064
bool prune = false;
1007
1065
git_buf reflog_msg_buf = GIT_BUF_INIT ;
1008
- const git_remote_callbacks * cbs = NULL ;
1066
+ git_remote_callbacks cbs = GIT_REMOTE_CALLBACKS_INIT ;
1009
1067
git_remote_connection_opts conn = GIT_REMOTE_CONNECTION_OPTIONS_INIT ;
1010
1068
1011
1069
if (opts ) {
1012
- GIT_ERROR_CHECK_VERSION (& opts -> callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" );
1013
- cbs = & opts -> callbacks ;
1070
+ GIT_STRUCT_UPGRADE (& cbs , sizeof (cbs ), & opts -> callbacks , "git_remote_callbacks" , git_struct__upgrade_remote_callbacks );
1014
1071
conn .custom_headers = & opts -> custom_headers ;
1015
1072
update_fetchhead = opts -> update_fetchhead ;
1016
1073
tagopt = opts -> download_tags ;
@@ -1019,7 +1076,7 @@ int git_remote_fetch(
1019
1076
}
1020
1077
1021
1078
/* Connect and download everything */
1022
- if ((error = git_remote__connect (remote , GIT_DIRECTION_FETCH , cbs , & conn )) != 0 )
1079
+ if ((error = git_remote__connect (remote , GIT_DIRECTION_FETCH , & cbs , & conn )) != 0 )
1023
1080
return error ;
1024
1081
1025
1082
error = git_remote_download (remote , refspecs , opts );
@@ -1040,7 +1097,7 @@ int git_remote_fetch(
1040
1097
}
1041
1098
1042
1099
/* Create "remote/foo" branches for all remote branches */
1043
- error = git_remote_update_tips (remote , cbs , update_fetchhead , tagopt , git_buf_cstr (& reflog_msg_buf ));
1100
+ error = git_remote_update_tips (remote , & cbs , update_fetchhead , tagopt , git_buf_cstr (& reflog_msg_buf ));
1044
1101
git_buf_dispose (& reflog_msg_buf );
1045
1102
if (error < 0 )
1046
1103
return error ;
@@ -1055,7 +1112,7 @@ int git_remote_fetch(
1055
1112
prune = remote -> prune_refs ;
1056
1113
1057
1114
if (prune )
1058
- error = git_remote_prune (remote , cbs );
1115
+ error = git_remote_prune (remote , & cbs );
1059
1116
1060
1117
return error ;
1061
1118
}
@@ -1258,11 +1315,11 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks)
1258
1315
git_vector candidates = GIT_VECTOR_INIT ;
1259
1316
const git_refspec * spec ;
1260
1317
const char * refname ;
1318
+ git_remote_callbacks cbs = GIT_REMOTE_CALLBACKS_INIT ;
1261
1319
int error ;
1262
1320
git_oid zero_id = {{ 0 }};
1263
1321
1264
- if (callbacks )
1265
- GIT_ERROR_CHECK_VERSION (callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" );
1322
+ GIT_STRUCT_UPGRADE (& cbs , sizeof (cbs ), callbacks , "git_remote_callbacks" , git_struct__upgrade_remote_callbacks );
1266
1323
1267
1324
if ((error = ls_to_vector (& remote_refs , remote )) < 0 )
1268
1325
goto cleanup ;
@@ -2491,7 +2548,7 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
2491
2548
int git_remote_push (git_remote * remote , const git_strarray * refspecs , const git_push_options * opts )
2492
2549
{
2493
2550
int error ;
2494
- const git_remote_callbacks * cbs = NULL ;
2551
+ git_remote_callbacks cbs = GIT_REMOTE_CALLBACKS_INIT ;
2495
2552
const git_strarray * custom_headers = NULL ;
2496
2553
const git_proxy_options * proxy = NULL ;
2497
2554
@@ -2503,22 +2560,21 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
2503
2560
}
2504
2561
2505
2562
if (opts ) {
2506
- GIT_ERROR_CHECK_VERSION (& opts -> callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" );
2507
- cbs = & opts -> callbacks ;
2563
+ GIT_STRUCT_UPGRADE (& cbs , sizeof (cbs ), & opts -> callbacks , "git_remote_callbacks" , git_struct__upgrade_remote_callbacks );
2508
2564
custom_headers = & opts -> custom_headers ;
2509
2565
GIT_ERROR_CHECK_VERSION (& opts -> proxy_opts , GIT_PROXY_OPTIONS_VERSION , "git_proxy_options" );
2510
2566
proxy = & opts -> proxy_opts ;
2511
2567
}
2512
2568
2513
2569
assert (remote );
2514
2570
2515
- if ((error = git_remote_connect (remote , GIT_DIRECTION_PUSH , cbs , proxy , custom_headers )) < 0 )
2571
+ if ((error = git_remote_connect (remote , GIT_DIRECTION_PUSH , & cbs , proxy , custom_headers )) < 0 )
2516
2572
return error ;
2517
2573
2518
2574
if ((error = git_remote_upload (remote , refspecs , opts )) < 0 )
2519
2575
return error ;
2520
2576
2521
- error = git_remote_update_tips (remote , cbs , 0 , 0 , NULL );
2577
+ error = git_remote_update_tips (remote , & cbs , 0 , 0 , NULL );
2522
2578
2523
2579
git_remote_disconnect (remote );
2524
2580
return error ;
0 commit comments