@@ -858,25 +858,70 @@ static int validate_custom_headers(const git_strarray *custom_headers)
858858 return 0 ;
859859}
860860
861+ static int lookup_redirect_config (
862+ git_remote_redirect_t * out ,
863+ git_repository * repo )
864+ {
865+ git_config * config ;
866+ const char * value ;
867+ int bool_value , error = 0 ;
868+
869+ if (!repo ) {
870+ * out = GIT_REMOTE_REDIRECT_INITIAL ;
871+ return 0 ;
872+ }
873+
874+ if ((error = git_repository_config_snapshot (& config , repo )) < 0 )
875+ goto done ;
876+
877+ if ((error = git_config_get_string (& value , config , "http.followRedirects" )) < 0 ) {
878+ if (error == GIT_ENOTFOUND ) {
879+ * out = GIT_REMOTE_REDIRECT_INITIAL ;
880+ error = 0 ;
881+ }
882+
883+ goto done ;
884+ }
885+
886+ if (git_config_parse_bool (& bool_value , value ) == 0 ) {
887+ * out = bool_value ? GIT_REMOTE_REDIRECT_ALL :
888+ GIT_REMOTE_REDIRECT_NONE ;
889+ } else if (strcasecmp (value , "initial" ) == 0 ) {
890+ * out = GIT_REMOTE_REDIRECT_INITIAL ;
891+ } else {
892+ git_error_set (GIT_ERROR_CONFIG , "invalid configuration setting '%s' for 'http.followRedirects'" , value );
893+ error = -1 ;
894+ }
895+
896+ done :
897+ git_config_free (config );
898+ return error ;
899+ }
900+
861901int git_remote_connect_options_normalize (
862902 git_remote_connect_options * dst ,
903+ git_repository * repo ,
863904 const git_remote_connect_options * src )
864905{
865906 git_remote_connect_options_dispose (dst );
907+ git_remote_connect_options_init (dst , GIT_REMOTE_CONNECT_OPTIONS_VERSION );
866908
867- if (! src ) {
868- git_remote_connect_options_init ( dst , GIT_REMOTE_CONNECT_OPTIONS_VERSION );
869- return 0 ;
870- }
909+ if (src ) {
910+ GIT_ERROR_CHECK_VERSION ( src , GIT_REMOTE_CONNECT_OPTIONS_VERSION , "git_remote_connect_options" );
911+ GIT_ERROR_CHECK_VERSION ( & src -> callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" ) ;
912+ GIT_ERROR_CHECK_VERSION ( & src -> proxy_opts , GIT_PROXY_OPTIONS_VERSION , "git_proxy_options" );
871913
872- GIT_ERROR_CHECK_VERSION (src , GIT_REMOTE_CONNECT_OPTIONS_VERSION , "git_remote_connect_options" );
873- GIT_ERROR_CHECK_VERSION (& src -> callbacks , GIT_REMOTE_CALLBACKS_VERSION , "git_remote_callbacks" );
874- GIT_ERROR_CHECK_VERSION (& src -> proxy_opts , GIT_PROXY_OPTIONS_VERSION , "git_proxy_options" );
914+ if (validate_custom_headers (& src -> custom_headers ) < 0 ||
915+ git_remote_connect_options_dup (dst , src ) < 0 )
916+ return -1 ;
917+ }
875918
876- if (validate_custom_headers (& src -> custom_headers ))
877- return -1 ;
919+ if (dst -> follow_redirects == 0 ) {
920+ if (lookup_redirect_config (& dst -> follow_redirects , repo ) < 0 )
921+ return -1 ;
922+ }
878923
879- return git_remote_connect_options_dup ( dst , src ) ;
924+ return 0 ;
880925}
881926
882927int git_remote_connect_ext (
@@ -1176,11 +1221,12 @@ static int ls_to_vector(git_vector *out, git_remote *remote)
11761221
11771222GIT_INLINE (int ) connect_opts_from_fetch_opts (
11781223 git_remote_connect_options * out ,
1224+ git_remote * remote ,
11791225 const git_fetch_options * fetch_opts )
11801226{
11811227 git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT ;
11821228 copy_opts (& tmp , fetch_opts );
1183- return git_remote_connect_options_normalize (out , & tmp );
1229+ return git_remote_connect_options_normalize (out , remote -> repo , & tmp );
11841230}
11851231
11861232static int connect_or_reset_options (
@@ -1270,7 +1316,7 @@ int git_remote_download(
12701316 return -1 ;
12711317 }
12721318
1273- if (connect_opts_from_fetch_opts (& connect_opts , opts ) < 0 )
1319+ if (connect_opts_from_fetch_opts (& connect_opts , remote , opts ) < 0 )
12741320 return -1 ;
12751321
12761322 if ((error = connect_or_reset_options (remote , GIT_DIRECTION_FETCH , & connect_opts )) < 0 )
@@ -1298,7 +1344,7 @@ int git_remote_fetch(
12981344 return -1 ;
12991345 }
13001346
1301- if (connect_opts_from_fetch_opts (& connect_opts , opts ) < 0 )
1347+ if (connect_opts_from_fetch_opts (& connect_opts , remote , opts ) < 0 )
13021348 return -1 ;
13031349
13041350 if ((error = connect_or_reset_options (remote , GIT_DIRECTION_FETCH , & connect_opts )) < 0 )
@@ -2771,11 +2817,12 @@ int git_remote__default_branch(git_str *out, git_remote *remote)
27712817
27722818GIT_INLINE (int ) connect_opts_from_push_opts (
27732819 git_remote_connect_options * out ,
2820+ git_remote * remote ,
27742821 const git_push_options * push_opts )
27752822{
27762823 git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT ;
27772824 copy_opts (& tmp , push_opts );
2778- return git_remote_connect_options_normalize (out , & tmp );
2825+ return git_remote_connect_options_normalize (out , remote -> repo , & tmp );
27792826}
27802827
27812828int git_remote_upload (
@@ -2796,7 +2843,7 @@ int git_remote_upload(
27962843 return -1 ;
27972844 }
27982845
2799- if ((error = connect_opts_from_push_opts (& connect_opts , opts )) < 0 )
2846+ if ((error = connect_opts_from_push_opts (& connect_opts , remote , opts )) < 0 )
28002847 goto cleanup ;
28012848
28022849 if ((error = connect_or_reset_options (remote , GIT_DIRECTION_PUSH , & connect_opts )) < 0 )
@@ -2857,7 +2904,7 @@ int git_remote_push(
28572904 return -1 ;
28582905 }
28592906
2860- if (connect_opts_from_push_opts (& connect_opts , opts ) < 0 )
2907+ if (connect_opts_from_push_opts (& connect_opts , remote , opts ) < 0 )
28612908 return -1 ;
28622909
28632910 if ((error = git_remote_upload (remote , refspecs , opts )) < 0 )
0 commit comments