@@ -171,11 +171,13 @@ pub fn run() -> Result<()> {
171171 . collect ( ) ;
172172
173173 // ── Summary & confirm ────────────────────────────────────────────────────
174+ let has_removals = !hooks_to_remove. is_empty ( ) || !configs_to_remove. is_empty ( ) ;
174175 let nothing = selected_builtins. is_empty ( )
175176 && custom_hooks. is_empty ( )
176177 && selected_templates. is_empty ( )
177178 && selected_attrs. is_empty ( )
178- && selected_config_keys. is_empty ( ) ;
179+ && selected_config_keys. is_empty ( )
180+ && !has_removals;
179181
180182 if nothing {
181183 println ! ( "\n Nothing selected — exiting." ) ;
@@ -246,10 +248,11 @@ pub fn run() -> Result<()> {
246248 println ! ( " ◇ git config applied ✓" ) ;
247249 }
248250 for key in & configs_to_remove {
249- if config:: remove_config_key ( key, config:: ConfigScope :: Local ) . is_err ( ) {
250- let _ = config:: remove_config_key ( key, config:: ConfigScope :: Global ) ;
251+ let removed = config:: remove_config_key ( key, config:: ConfigScope :: Local ) . is_ok ( )
252+ || config:: remove_config_key ( key, config:: ConfigScope :: Global ) . is_ok ( ) ;
253+ if removed {
254+ println ! ( " ◇ git config '{key}' removed ✓" ) ;
251255 }
252- println ! ( " ◇ git config '{key}' removed ✓" ) ;
253256 }
254257
255258 println ! ( "\n Done\n " ) ;
@@ -271,7 +274,13 @@ fn get_installed_hooks() -> HashSet<String> {
271274 if !name. ends_with ( ".bak" ) && !name. ends_with ( ".sample" ) {
272275 let content = fs:: read_to_string ( entry. path ( ) ) . unwrap_or_default ( ) ;
273276 let builtin_match = hooks:: available_builtins ( ) . iter ( ) . find ( |b| {
274- b. hook == name && content. contains ( & b. script [ ..80 . min ( b. script . len ( ) ) ] )
277+ b. hook == name
278+ && b. script
279+ . chars ( )
280+ . take ( 80 )
281+ . collect :: < String > ( )
282+ . chars ( )
283+ . all ( |c| content. contains ( c) )
275284 } ) ;
276285 if let Some ( b) = builtin_match {
277286 installed. insert ( b. name . to_string ( ) ) ;
@@ -286,36 +295,45 @@ fn get_installed_hooks() -> HashSet<String> {
286295
287296fn get_configured_keys ( ) -> HashSet < String > {
288297 let mut configured = HashSet :: new ( ) ;
298+
299+ // Get all config values in one call per scope
300+ let local_configs = get_all_git_configs ( "--local" ) ;
301+ let global_configs = get_all_git_configs ( "--global" ) ;
302+
289303 for option in config:: CONFIG_OPTIONS {
290304 if option. key == "core.pager" {
291305 continue ;
292306 }
293- if let Some ( value ) = option. value {
294- if let Ok ( output ) = std :: process :: Command :: new ( "git" )
295- . args ( [ "config" , "--local" , "-- get" , option. key ] )
296- . output ( )
307+ if let Some ( expected_value ) = option. value {
308+ // Check local first, then global
309+ if local_configs . get ( option. key ) . map ( |s| s . as_str ( ) ) == Some ( expected_value )
310+ || global_configs . get ( option . key ) . map ( |s| s . as_str ( ) ) == Some ( expected_value )
297311 {
298- if output. status . success ( ) {
299- let current = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
300- if current == value {
301- configured. insert ( option. key . to_string ( ) ) ;
302- }
303- }
312+ configured. insert ( option. key . to_string ( ) ) ;
304313 }
305- if let Ok ( output) = std:: process:: Command :: new ( "git" )
306- . args ( [ "config" , "--global" , "--get" , option. key ] )
307- . output ( )
308- {
309- if output. status . success ( ) {
310- let current = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
311- if current == value {
312- configured. insert ( option. key . to_string ( ) ) ;
313- }
314+ }
315+ }
316+ configured
317+ }
318+
319+ fn get_all_git_configs ( scope : & str ) -> std:: collections:: HashMap < String , String > {
320+ let mut configs = std:: collections:: HashMap :: new ( ) ;
321+
322+ if let Ok ( output) = std:: process:: Command :: new ( "git" )
323+ . args ( [ "config" , scope, "--list" ] )
324+ . output ( )
325+ {
326+ if output. status . success ( ) {
327+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
328+ for line in stdout. lines ( ) {
329+ if let Some ( ( key, value) ) = line. split_once ( '=' ) {
330+ configs. insert ( key. to_string ( ) , value. to_string ( ) ) ;
314331 }
315332 }
316333 }
317334 }
318- configured
335+
336+ configs
319337}
320338
321339/// Maps selected display labels back to their corresponding keys.
@@ -340,9 +358,10 @@ mod tests {
340358 use super :: * ;
341359
342360 #[ test]
343- fn get_configured_keys_returns_empty_for_no_config ( ) {
361+ fn get_configured_keys_works ( ) {
344362 let configured = get_configured_keys ( ) ;
345- assert ! ( configured. is_empty( ) || !configured. is_empty( ) ) ;
363+ // Just verify it doesn't panic and returns a valid HashSet
364+ assert ! ( configured. len( ) >= 0 ) ;
346365 }
347366
348367 #[ test]
0 commit comments