@@ -583,12 +583,16 @@ fn scripted_fixture_read_only_with_args_inner(
583583 Ok ( script_result_directory)
584584}
585585
586+ #[ cfg( windows) ]
587+ const NULL_DEVICE : & str = "NUL" ;
588+ #[ cfg( not( windows) ) ]
589+ const NULL_DEVICE : & str = "/dev/null" ;
590+
586591fn configure_command < ' a > (
587592 cmd : & ' a mut std:: process:: Command ,
588593 args : & [ String ] ,
589594 script_result_directory : & Path ,
590595) -> & ' a mut std:: process:: Command {
591- let never_path = if cfg ! ( windows) { "-" } else { ":" } ;
592596 let mut msys_for_git_bash_on_windows = std:: env:: var ( "MSYS" ) . unwrap_or_default ( ) ;
593597 msys_for_git_bash_on_windows. push_str ( " winsymlinks:nativestrict" ) ;
594598 cmd. args ( args)
@@ -599,8 +603,8 @@ fn configure_command<'a>(
599603 . env_remove ( "GIT_ASKPASS" )
600604 . env_remove ( "SSH_ASKPASS" )
601605 . env ( "MSYS" , msys_for_git_bash_on_windows)
602- . env ( "GIT_CONFIG_SYSTEM" , never_path )
603- . env ( "GIT_CONFIG_GLOBAL" , never_path )
606+ . env ( "GIT_CONFIG_SYSTEM" , NULL_DEVICE )
607+ . env ( "GIT_CONFIG_GLOBAL" , NULL_DEVICE )
604608 . env ( "GIT_TERMINAL_PROMPT" , "false" )
605609 . env ( "GIT_AUTHOR_DATE" , "2000-01-01 00:00:00 +0000" )
606610 . env ( "GIT_AUTHOR_EMAIL" , "author@example.com" )
@@ -882,4 +886,55 @@ mod tests {
882886 fn parse_version_with_trailing_newline ( ) {
883887 assert_eq ! ( git_version_from_bytes( b"git version 2.37.2\n " ) . unwrap( ) , ( 2 , 37 , 2 ) ) ;
884888 }
889+
890+ const SCOPE_ENV_VALUE : & str = "gitconfig" ;
891+
892+ fn populate_ad_hoc_config_files ( dir : & Path ) {
893+ const CONFIG_DATA : & [ u8 ] = b"[foo]\n \t bar = baz\n " ;
894+
895+ let paths: & [ PathBuf ] = if cfg ! ( windows) {
896+ let unc_literal_nul = dir. canonicalize ( ) . expect ( "directory exists" ) . join ( "NUL" ) ;
897+ & [ dir. join ( SCOPE_ENV_VALUE ) , dir. join ( "-" ) , unc_literal_nul]
898+ } else {
899+ & [ dir. join ( SCOPE_ENV_VALUE ) , dir. join ( "-" ) , dir. join ( ":" ) ]
900+ } ;
901+
902+ // Create the files.
903+ for path in paths {
904+ std:: fs:: write ( path, CONFIG_DATA ) . expect ( "can write contents" ) ;
905+ }
906+
907+ // Verify the files. This is mostly to show we really made a `\\?\...\NUL` on Windows.
908+ for path in paths {
909+ let buf = std:: fs:: read ( path) . expect ( "the file really exists" ) ;
910+ assert_eq ! ( buf, CONFIG_DATA , "File {path:?} should be created" ) ;
911+ }
912+ }
913+
914+ fn check_configure_clears_scope ( scope_env_key : & str , scope_option : & str ) {
915+ let temp = tempfile:: TempDir :: new ( ) . expect ( "can create temp dir" ) ;
916+ let dir = temp. path ( ) ;
917+ populate_ad_hoc_config_files ( dir) ;
918+
919+ let mut cmd = std:: process:: Command :: new ( "git" ) ;
920+ cmd. env ( scope_env_key, SCOPE_ENV_VALUE ) ; // configure_command() should override it.
921+ let args = [ "config" , "-l" , "--show-origin" , scope_option] . map ( String :: from) ;
922+ configure_command ( & mut cmd, & args, dir) ;
923+
924+ let output = cmd. output ( ) . expect ( "can run git" ) ;
925+ let stdout = output. stdout . to_str ( ) . expect ( "valid UTF-8" ) ;
926+ let status = output. status . code ( ) . expect ( "terminated normally" ) ;
927+ assert_eq ! ( stdout, "" , "should be no config variables to display" ) ;
928+ assert_eq ! ( status, 0 , "reading the config should nonetheless succeed" ) ;
929+ }
930+
931+ #[ test]
932+ fn configure_command_clears_system_scope ( ) {
933+ check_configure_clears_scope ( "GIT_CONFIG_SYSTEM" , "--system" ) ;
934+ }
935+
936+ #[ test]
937+ fn configure_command_clears_global_scope ( ) {
938+ check_configure_clears_scope ( "GIT_CONFIG_GLOBAL" , "--global" ) ;
939+ }
885940}
0 commit comments