diff --git a/codex-rs/shell-command/src/command_safety/is_dangerous_command.rs b/codex-rs/shell-command/src/command_safety/is_dangerous_command.rs index 3aa31c80f9..611bafd2b8 100644 --- a/codex-rs/shell-command/src/command_safety/is_dangerous_command.rs +++ b/codex-rs/shell-command/src/command_safety/is_dangerous_command.rs @@ -58,7 +58,10 @@ fn is_git_global_option_with_inline_value(arg: &str) -> bool { pub(crate) fn git_global_option_requires_prompt(arg: &str) -> bool { matches!( arg, - "-c" | "--config-env" + // `-C` can redirect Git into a repo whose config runs helpers such as + // `core.fsmonitor` during read-only commands like `status`. + "-C" | "-c" + | "--config-env" | "--exec-path" | "--git-dir" | "--namespace" @@ -66,7 +69,7 @@ pub(crate) fn git_global_option_requires_prompt(arg: &str) -> bool { | "--work-tree" ) || matches!( arg, - s if (s.starts_with("-c") && s.len() > 2) + s if ((s.starts_with("-C") || s.starts_with("-c")) && s.len() > 2) || s.starts_with("--config-env=") || s.starts_with("--exec-path=") || s.starts_with("--git-dir=") @@ -181,4 +184,10 @@ mod tests { fn rm_f_is_dangerous() { assert!(command_might_be_dangerous(&vec_str(&["rm", "-f", "/"]))); } + + #[test] + fn git_dash_c_requires_prompt() { + assert!(git_global_option_requires_prompt("-C")); + assert!(git_global_option_requires_prompt("-C/path/to/repo")); + } } diff --git a/codex-rs/shell-command/src/command_safety/is_safe_command.rs b/codex-rs/shell-command/src/command_safety/is_safe_command.rs index 2906fef276..26fe235fbe 100644 --- a/codex-rs/shell-command/src/command_safety/is_safe_command.rs +++ b/codex-rs/shell-command/src/command_safety/is_safe_command.rs @@ -331,20 +331,19 @@ mod tests { #[test] fn git_branch_global_options_respect_safety_rules() { - use pretty_assertions::assert_eq; - - assert_eq!( - is_known_safe_command(&vec_str(&["git", "-C", ".", "branch", "--show-current"])), - true - ); - assert_eq!( - is_known_safe_command(&vec_str(&["git", "-C", ".", "branch", "-d", "feature"])), - false - ); - assert_eq!( - is_known_safe_command(&vec_str(&["bash", "-lc", "git -C . branch -d feature",])), - false - ); + assert!(is_known_safe_command(&vec_str(&[ + "git", + "branch", + "--show-current", + ]))); + assert!(!is_known_safe_command(&vec_str(&[ + "git", "branch", "-d", "feature", + ]))); + assert!(!is_known_safe_command(&vec_str(&[ + "bash", + "-lc", + "git branch -d feature", + ]))); } #[test] @@ -381,6 +380,10 @@ mod tests { #[test] fn git_global_override_flags_are_not_safe() { + assert!(!is_known_safe_command(&vec_str(&[ + "git", "-C", ".", "status", + ]))); + assert!(!is_known_safe_command(&vec_str(&["git", "-C.", "status",]))); assert!(!is_known_safe_command(&vec_str(&[ "git", "-c", @@ -415,6 +418,11 @@ mod tests { ); } + assert!(!is_known_safe_command(&vec_str(&[ + "bash", + "-lc", + "git -C .project-deps/test-fixtures status", + ]))); assert!(!is_known_safe_command(&vec_str(&[ "bash", "-lc",