@@ -4,6 +4,9 @@ use crate::{
4
4
config:: { cache:: util:: ApplyLeniency , Cache } ,
5
5
repository,
6
6
} ;
7
+ use git_config:: File ;
8
+ use git_sec:: Permission ;
9
+ use std:: borrow:: Cow ;
7
10
8
11
/// Initialization
9
12
impl Cache {
@@ -27,7 +30,7 @@ impl Cache {
27
30
home : home_env,
28
31
xdg_config_home : xdg_config_home_env,
29
32
ssh_prefix : _,
30
- http_transport : _ ,
33
+ http_transport,
31
34
} : repository:: permissions:: Environment ,
32
35
repository:: permissions:: Config {
33
36
git_binary : use_installation,
@@ -56,82 +59,82 @@ impl Cache {
56
59
..util:: base_options ( lossy)
57
60
} ;
58
61
59
- let config =
60
- {
61
- let home_env = & home_env;
62
- let xdg_config_home_env = & xdg_config_home_env;
63
- let git_prefix = & git_prefix;
64
- let metas = [
65
- git_config:: source:: Kind :: GitInstallation ,
66
- git_config:: source:: Kind :: System ,
67
- git_config:: source:: Kind :: Global ,
68
- ]
69
- . iter ( )
70
- . flat_map ( |kind| kind. sources ( ) )
71
- . filter_map ( |source| {
72
- match source {
73
- git_config:: Source :: GitInstallation if !use_installation => return None ,
74
- git_config:: Source :: System if !use_system => return None ,
75
- git_config:: Source :: Git if !use_git => return None ,
76
- git_config:: Source :: User if !use_user => return None ,
77
- _ => { }
78
- }
79
- source
80
- . storage_location ( & mut |name| {
81
- match name {
82
- git_ if git_. starts_with ( "GIT_" ) => Some ( git_prefix) ,
83
- "XDG_CONFIG_HOME" => Some ( xdg_config_home_env) ,
84
- "HOME" => Some ( home_env) ,
85
- _ => None ,
86
- }
87
- . and_then ( |perm| std:: env:: var_os ( name) . and_then ( |val| perm. check_opt ( val) ) )
88
- } )
89
- . map ( |p| ( source, p. into_owned ( ) ) )
90
- } )
91
- . map ( |( source, path) | git_config:: file:: Metadata {
92
- path : Some ( path) ,
93
- source : * source,
94
- level : 0 ,
95
- trust : git_sec:: Trust :: Full ,
96
- } ) ;
97
-
98
- let err_on_nonexisting_paths = false ;
99
- let mut globals = git_config:: File :: from_paths_metadata_buf (
100
- metas,
101
- & mut buf,
102
- err_on_nonexisting_paths,
103
- git_config:: file:: init:: Options {
104
- includes : git_config:: file:: includes:: Options :: no_follow ( ) ,
105
- ..options
106
- } ,
107
- )
108
- . map_err ( |err| match err {
109
- git_config:: file:: init:: from_paths:: Error :: Init ( err) => Error :: from ( err) ,
110
- git_config:: file:: init:: from_paths:: Error :: Io ( err) => err. into ( ) ,
111
- } ) ?
112
- . unwrap_or_default ( ) ;
113
-
114
- globals. append ( git_dir_config) ;
115
- globals. resolve_includes ( options) ?;
116
- if use_env {
117
- globals. append ( git_config:: File :: from_env ( options) ?. unwrap_or_default ( ) ) ;
118
- }
119
- if !cli_config_overrides. is_empty ( ) {
120
- crate :: config:: overrides:: append ( & mut globals, cli_config_overrides, git_config:: Source :: Cli )
121
- . map_err ( |err| Error :: ConfigOverrides {
122
- err,
123
- source : git_config:: Source :: Cli ,
124
- } ) ?;
125
- }
126
- if !api_config_overrides. is_empty ( ) {
127
- crate :: config:: overrides:: append ( & mut globals, api_config_overrides, git_config:: Source :: Api )
128
- . map_err ( |err| Error :: ConfigOverrides {
129
- err,
130
- source : git_config:: Source :: Api ,
131
- } ) ?;
62
+ let config = {
63
+ let home_env = & home_env;
64
+ let xdg_config_home_env = & xdg_config_home_env;
65
+ let git_prefix = & git_prefix;
66
+ let metas = [
67
+ git_config:: source:: Kind :: GitInstallation ,
68
+ git_config:: source:: Kind :: System ,
69
+ git_config:: source:: Kind :: Global ,
70
+ ]
71
+ . iter ( )
72
+ . flat_map ( |kind| kind. sources ( ) )
73
+ . filter_map ( |source| {
74
+ match source {
75
+ git_config:: Source :: GitInstallation if !use_installation => return None ,
76
+ git_config:: Source :: System if !use_system => return None ,
77
+ git_config:: Source :: Git if !use_git => return None ,
78
+ git_config:: Source :: User if !use_user => return None ,
79
+ _ => { }
132
80
}
133
- globals
134
- } ;
81
+ source
82
+ . storage_location ( & mut |name| {
83
+ match name {
84
+ git_ if git_. starts_with ( "GIT_" ) => Some ( git_prefix) ,
85
+ "XDG_CONFIG_HOME" => Some ( xdg_config_home_env) ,
86
+ "HOME" => Some ( home_env) ,
87
+ _ => None ,
88
+ }
89
+ . and_then ( |perm| std:: env:: var_os ( name) . and_then ( |val| perm. check_opt ( val) ) )
90
+ } )
91
+ . map ( |p| ( source, p. into_owned ( ) ) )
92
+ } )
93
+ . map ( |( source, path) | git_config:: file:: Metadata {
94
+ path : Some ( path) ,
95
+ source : * source,
96
+ level : 0 ,
97
+ trust : git_sec:: Trust :: Full ,
98
+ } ) ;
99
+
100
+ let err_on_nonexisting_paths = false ;
101
+ let mut globals = git_config:: File :: from_paths_metadata_buf (
102
+ metas,
103
+ & mut buf,
104
+ err_on_nonexisting_paths,
105
+ git_config:: file:: init:: Options {
106
+ includes : git_config:: file:: includes:: Options :: no_follow ( ) ,
107
+ ..options
108
+ } ,
109
+ )
110
+ . map_err ( |err| match err {
111
+ git_config:: file:: init:: from_paths:: Error :: Init ( err) => Error :: from ( err) ,
112
+ git_config:: file:: init:: from_paths:: Error :: Io ( err) => err. into ( ) ,
113
+ } ) ?
114
+ . unwrap_or_default ( ) ;
115
+
116
+ globals. append ( git_dir_config) ;
117
+ globals. resolve_includes ( options) ?;
118
+ if use_env {
119
+ globals. append ( git_config:: File :: from_env ( options) ?. unwrap_or_default ( ) ) ;
120
+ }
121
+ if !cli_config_overrides. is_empty ( ) {
122
+ crate :: config:: overrides:: append ( & mut globals, cli_config_overrides, git_config:: Source :: Cli , |_| None )
123
+ . map_err ( |err| Error :: ConfigOverrides {
124
+ err,
125
+ source : git_config:: Source :: Cli ,
126
+ } ) ?;
127
+ }
128
+ if !api_config_overrides. is_empty ( ) {
129
+ crate :: config:: overrides:: append ( & mut globals, api_config_overrides, git_config:: Source :: Api , |_| None )
130
+ . map_err ( |err| Error :: ConfigOverrides {
131
+ err,
132
+ source : git_config:: Source :: Api ,
133
+ } ) ?;
134
+ }
135
+ apply_environment_overrides ( & mut globals, * git_prefix, http_transport) ?;
136
+ globals
137
+ } ;
135
138
136
139
let hex_len = util:: parse_core_abbrev ( & config, object_hash) . with_leniency ( lenient_config) ?;
137
140
@@ -208,3 +211,144 @@ impl Cache {
208
211
Ok ( ( ) )
209
212
}
210
213
}
214
+
215
+ impl crate :: Repository {
216
+ /// Causes our configuration to re-read cached values which will also be applied to the repository in-memory state if applicable.
217
+ ///
218
+ /// Similar to `reread_values_and_clear_caches_replacing_config()`, but works on the existing instance instead of a passed
219
+ /// in one that it them makes the default.
220
+ #[ cfg( feature = "blocking-network-client" ) ]
221
+ pub ( crate ) fn reread_values_and_clear_caches ( & mut self ) -> Result < ( ) , Error > {
222
+ self . config . reread_values_and_clear_caches ( ) ?;
223
+ self . apply_changed_values ( ) ;
224
+ Ok ( ( ) )
225
+ }
226
+
227
+ /// Replace our own configuration with `config` and re-read all cached values, and apply them to select in-memory instances.
228
+ pub ( crate ) fn reread_values_and_clear_caches_replacing_config (
229
+ & mut self ,
230
+ config : crate :: Config ,
231
+ ) -> Result < ( ) , Error > {
232
+ self . config . reread_values_and_clear_caches_replacing_config ( config) ?;
233
+ self . apply_changed_values ( ) ;
234
+ Ok ( ( ) )
235
+ }
236
+
237
+ fn apply_changed_values ( & mut self ) {
238
+ self . refs . write_reflog = util:: reflog_or_default ( self . config . reflog , self . work_dir ( ) . is_some ( ) ) ;
239
+ }
240
+ }
241
+
242
+ fn apply_environment_overrides (
243
+ config : & mut File < ' static > ,
244
+ git_prefix : Permission ,
245
+ http_transport : Permission ,
246
+ ) -> Result < ( ) , Error > {
247
+ fn var_as_bstring ( var : & str , perm : Permission ) -> Option < BString > {
248
+ perm. check_opt ( var)
249
+ . and_then ( std:: env:: var_os)
250
+ . and_then ( |val| git_path:: os_string_into_bstring ( val) . ok ( ) )
251
+ }
252
+
253
+ let mut env_override = git_config:: File :: new ( git_config:: file:: Metadata :: from ( git_config:: Source :: EnvOverride ) ) ;
254
+ {
255
+ let mut section = env_override
256
+ . new_section ( "http" , None )
257
+ . expect ( "statically known valid section name" ) ;
258
+ for ( var, key, permission) in [
259
+ ( "GIT_HTTP_LOW_SPEED_LIMIT" , "lowSpeedLimit" , git_prefix) ,
260
+ ( "GIT_HTTP_LOW_SPEED_TIME" , "lowSpeedTime" , git_prefix) ,
261
+ ( "GIT_HTTP_USER_AGENT" , "userAgent" , git_prefix) ,
262
+ ( "GIT_HTTP_PROXY_AUTHMETHOD" , "proxyAuthMethod" , git_prefix) ,
263
+ ( "all_proxy" , "all-proxy-lower" , http_transport) ,
264
+ ( "ALL_PROXY" , "all-proxy" , http_transport) ,
265
+ ] {
266
+ if let Some ( value) = var_as_bstring ( var, permission) {
267
+ section. push_with_comment (
268
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
269
+ Some ( value. as_ref ( ) ) ,
270
+ format ! ( "from {var}" ) . as_str ( ) ,
271
+ ) ;
272
+ }
273
+ }
274
+ if section. num_values ( ) == 0 {
275
+ let id = section. id ( ) ;
276
+ env_override. remove_section_by_id ( id) ;
277
+ }
278
+ }
279
+
280
+ {
281
+ let mut section = env_override
282
+ . new_section ( "gitoxide" , Some ( Cow :: Borrowed ( "https" . into ( ) ) ) )
283
+ . expect ( "statically known valid section name" ) ;
284
+
285
+ for ( var, key) in [ ( "HTTPS_PROXY" , "proxy" ) , ( "https_proxy" , "proxy" ) ] {
286
+ if let Some ( value) = var_as_bstring ( var, http_transport) {
287
+ section. push_with_comment (
288
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
289
+ Some ( value. as_ref ( ) ) ,
290
+ format ! ( "from {var}" ) . as_str ( ) ,
291
+ ) ;
292
+ }
293
+ }
294
+
295
+ if section. num_values ( ) == 0 {
296
+ let id = section. id ( ) ;
297
+ env_override. remove_section_by_id ( id) ;
298
+ }
299
+ }
300
+
301
+ {
302
+ let mut section = env_override
303
+ . new_section ( "gitoxide" , Some ( Cow :: Borrowed ( "allow" . into ( ) ) ) )
304
+ . expect ( "statically known valid section name" ) ;
305
+
306
+ for ( var, key) in [ ( "GIT_PROTOCOL_FROM_USER" , "protocolFromUser" ) ] {
307
+ if let Some ( value) = var_as_bstring ( var, http_transport) {
308
+ section. push_with_comment (
309
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
310
+ Some ( value. as_ref ( ) ) ,
311
+ format ! ( "from {var}" ) . as_str ( ) ,
312
+ ) ;
313
+ }
314
+ }
315
+
316
+ if section. num_values ( ) == 0 {
317
+ let id = section. id ( ) ;
318
+ env_override. remove_section_by_id ( id) ;
319
+ }
320
+ }
321
+
322
+ {
323
+ let mut section = env_override
324
+ . new_section ( "gitoxide" , Some ( Cow :: Borrowed ( "http" . into ( ) ) ) )
325
+ . expect ( "statically known valid section name" ) ;
326
+
327
+ for ( var, key, permission) in [
328
+ ( "ALL_PROXY" , "allProxy" , http_transport) ,
329
+ ( "all_proxy" , "allProxy" , http_transport) ,
330
+ ( "NO_PROXY" , "noProxy" , http_transport) ,
331
+ ( "no_proxy" , "noProxy" , http_transport) ,
332
+ ( "http_proxy" , "proxy" , http_transport) ,
333
+ ( "GIT_CURL_VERBOSE" , "verbose" , git_prefix) ,
334
+ ] {
335
+ if let Some ( value) = var_as_bstring ( var, permission) {
336
+ section. push_with_comment (
337
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
338
+ Some ( value. as_ref ( ) ) ,
339
+ format ! ( "from {var}" ) . as_str ( ) ,
340
+ ) ;
341
+ }
342
+ }
343
+
344
+ if section. num_values ( ) == 0 {
345
+ let id = section. id ( ) ;
346
+ env_override. remove_section_by_id ( id) ;
347
+ }
348
+ }
349
+
350
+ if !env_override. is_void ( ) {
351
+ config. append ( env_override) ;
352
+ }
353
+ Ok ( ( ) )
354
+ }
0 commit comments