@@ -20,7 +20,12 @@ pub(crate) struct StageOne {
20
20
21
21
/// Initialization
22
22
impl StageOne {
23
- pub fn new ( git_dir : & std:: path:: Path , git_dir_trust : git_sec:: Trust , lossy : Option < bool > ) -> Result < Self , Error > {
23
+ pub fn new (
24
+ git_dir : & std:: path:: Path ,
25
+ git_dir_trust : git_sec:: Trust ,
26
+ lossy : Option < bool > ,
27
+ lenient : bool ,
28
+ ) -> Result < Self , Error > {
24
29
let mut buf = Vec :: with_capacity ( 512 ) ;
25
30
let config = {
26
31
let config_path = git_dir. join ( "config" ) ;
@@ -38,7 +43,7 @@ impl StageOne {
38
43
) ?
39
44
} ;
40
45
41
- let is_bare = config_bool ( & config, "core.bare" , false ) ?;
46
+ let is_bare = config_bool ( & config, "core.bare" , false , lenient ) ?;
42
47
let repo_format_version = config
43
48
. value :: < Integer > ( "core" , None , "repositoryFormatVersion" )
44
49
. map_or ( 0 , |v| v. to_decimal ( ) . unwrap_or_default ( ) ) ;
@@ -99,6 +104,7 @@ impl Cache {
99
104
env : use_env,
100
105
includes : use_includes,
101
106
} : repository:: permissions:: Config ,
107
+ lenient_config : bool ,
102
108
) -> Result < Self , Error > {
103
109
let options = git_config:: file:: init:: Options {
104
110
includes : if use_includes {
@@ -174,45 +180,25 @@ impl Cache {
174
180
globals
175
181
} ;
176
182
177
- let excludes_file = config
183
+ let excludes_file = match config
178
184
. path_filter ( "core" , None , "excludesFile" , & mut filter_config_section)
179
185
. map ( |p| p. interpolate ( options. includes . interpolate ) . map ( |p| p. into_owned ( ) ) )
180
- . transpose ( ) ?;
186
+ . transpose ( )
187
+ {
188
+ Ok ( f) => f,
189
+ Err ( _err) if lenient_config => None ,
190
+ Err ( err) => return Err ( err. into ( ) ) ,
191
+ } ;
181
192
182
- let mut hex_len = None ;
183
- if let Some ( hex_len_str) = config. string ( "core" , None , "abbrev" ) {
184
- if hex_len_str. trim ( ) . is_empty ( ) {
185
- return Err ( Error :: EmptyValue { key : "core.abbrev" } ) ;
186
- }
187
- if !hex_len_str. eq_ignore_ascii_case ( b"auto" ) {
188
- let value_bytes = hex_len_str. as_ref ( ) ;
189
- if let Ok ( false ) = Boolean :: try_from ( value_bytes) . map ( Into :: into) {
190
- hex_len = object_hash. len_in_hex ( ) . into ( ) ;
191
- } else {
192
- let value = Integer :: try_from ( value_bytes)
193
- . map_err ( |_| Error :: CoreAbbrev {
194
- value : hex_len_str. clone ( ) . into_owned ( ) ,
195
- max : object_hash. len_in_hex ( ) as u8 ,
196
- } ) ?
197
- . to_decimal ( )
198
- . ok_or_else ( || Error :: CoreAbbrev {
199
- value : hex_len_str. clone ( ) . into_owned ( ) ,
200
- max : object_hash. len_in_hex ( ) as u8 ,
201
- } ) ?;
202
- if value < 4 || value as usize > object_hash. len_in_hex ( ) {
203
- return Err ( Error :: CoreAbbrev {
204
- value : hex_len_str. clone ( ) . into_owned ( ) ,
205
- max : object_hash. len_in_hex ( ) as u8 ,
206
- } ) ;
207
- }
208
- hex_len = Some ( value as usize ) ;
209
- }
210
- }
211
- }
193
+ let hex_len = match parse_core_abbrev ( & config, object_hash) {
194
+ Ok ( v) => v,
195
+ Err ( _err) if lenient_config => None ,
196
+ Err ( err) => return Err ( err) ,
197
+ } ;
212
198
213
199
let reflog = query_refupdates ( & config) ;
214
- let ignore_case = config_bool ( & config, "core.ignoreCase" , false ) ?;
215
- let use_multi_pack_index = config_bool ( & config, "core.multiPackIndex" , true ) ?;
200
+ let ignore_case = config_bool ( & config, "core.ignoreCase" , false , lenient_config ) ?;
201
+ let use_multi_pack_index = config_bool ( & config, "core.multiPackIndex" , true , lenient_config ) ?;
216
202
let object_kind_hint = config. string ( "core" , None , "disambiguate" ) . and_then ( |value| {
217
203
Some ( match value. as_ref ( ) . as_ref ( ) {
218
204
b"commit" => ObjectKindHint :: Commit ,
@@ -292,15 +278,19 @@ fn base_options(lossy: Option<bool>) -> git_config::file::init::Options<'static>
292
278
}
293
279
}
294
280
295
- fn config_bool ( config : & git_config:: File < ' _ > , key : & str , default : bool ) -> Result < bool , Error > {
281
+ fn config_bool ( config : & git_config:: File < ' _ > , key : & str , default : bool , lenient : bool ) -> Result < bool , Error > {
296
282
let ( section, key) = key. split_once ( '.' ) . expect ( "valid section.key format" ) ;
297
- config
283
+ match config
298
284
. boolean ( section, None , key)
299
285
. unwrap_or ( Ok ( default) )
300
286
. map_err ( |err| Error :: DecodeBoolean {
301
287
value : err. input ,
302
288
key : key. into ( ) ,
303
- } )
289
+ } ) {
290
+ Ok ( v) => Ok ( v) ,
291
+ Err ( _err) if lenient => Ok ( default) ,
292
+ Err ( err) => Err ( err) ,
293
+ }
304
294
}
305
295
306
296
fn query_refupdates ( config : & git_config:: File < ' static > ) -> Option < git_ref:: store:: WriteReflog > {
@@ -315,3 +305,40 @@ fn query_refupdates(config: &git_config::File<'static>) -> Option<git_ref::store
315
305
. unwrap_or ( git_ref:: store:: WriteReflog :: Disable )
316
306
} )
317
307
}
308
+
309
+ fn parse_core_abbrev ( config : & git_config:: File < ' static > , object_hash : git_hash:: Kind ) -> Result < Option < usize > , Error > {
310
+ match config. string ( "core" , None , "abbrev" ) {
311
+ Some ( hex_len_str) => {
312
+ if hex_len_str. trim ( ) . is_empty ( ) {
313
+ return Err ( Error :: EmptyValue { key : "core.abbrev" } ) ;
314
+ }
315
+ if hex_len_str. trim ( ) . eq_ignore_ascii_case ( b"auto" ) {
316
+ Ok ( None )
317
+ } else {
318
+ let value_bytes = hex_len_str. as_ref ( ) ;
319
+ if let Ok ( false ) = Boolean :: try_from ( value_bytes) . map ( Into :: into) {
320
+ Ok ( object_hash. len_in_hex ( ) . into ( ) )
321
+ } else {
322
+ let value = Integer :: try_from ( value_bytes)
323
+ . map_err ( |_| Error :: CoreAbbrev {
324
+ value : hex_len_str. clone ( ) . into_owned ( ) ,
325
+ max : object_hash. len_in_hex ( ) as u8 ,
326
+ } ) ?
327
+ . to_decimal ( )
328
+ . ok_or_else ( || Error :: CoreAbbrev {
329
+ value : hex_len_str. clone ( ) . into_owned ( ) ,
330
+ max : object_hash. len_in_hex ( ) as u8 ,
331
+ } ) ?;
332
+ if value < 4 || value as usize > object_hash. len_in_hex ( ) {
333
+ return Err ( Error :: CoreAbbrev {
334
+ value : hex_len_str. clone ( ) . into_owned ( ) ,
335
+ max : object_hash. len_in_hex ( ) as u8 ,
336
+ } ) ;
337
+ }
338
+ Ok ( Some ( value as usize ) )
339
+ }
340
+ }
341
+ }
342
+ None => Ok ( None ) ,
343
+ }
344
+ }
0 commit comments