diff --git a/codex-rs/core/src/util.rs b/codex-rs/core/src/util.rs index 14bcc16d..a7c14852 100644 --- a/codex-rs/core/src/util.rs +++ b/codex-rs/core/src/util.rs @@ -5,6 +5,8 @@ use rand::Rng; use tokio::sync::Notify; use tracing::debug; +use crate::config::Config; + const INITIAL_DELAY_MS: u64 = 200; const BACKOFF_FACTOR: f64 = 1.3; @@ -33,26 +35,20 @@ pub(crate) fn backoff(attempt: u64) -> Duration { Duration::from_millis((base as f64 * jitter) as u64) } -/// Return `true` if the current working directory is inside a Git repository. +/// Return `true` if the project folder specified by the `Config` is inside a +/// Git repository. /// -/// The check walks up the directory hierarchy looking for a `.git` folder. This +/// The check walks up the directory hierarchy looking for a `.git` file or +/// directory (note `.git` can be a file that contains a `gitdir` entry). This /// approach does **not** require the `git` binary or the `git2` crate and is -/// therefore fairly lightweight. It intentionally only looks for the -/// presence of a *directory* named `.git` – this is good enough for regular -/// work‑trees and bare repos that live inside a work‑tree (common for -/// developers running Codex locally). +/// therefore fairly lightweight. /// /// Note that this does **not** detect *work‑trees* created with /// `git worktree add` where the checkout lives outside the main repository -/// directory. If you need Codex to work from such a checkout simply pass the +/// directory. If you need Codex to work from such a checkout simply pass the /// `--allow-no-git-exec` CLI flag that disables the repo requirement. -pub fn is_inside_git_repo() -> bool { - // Best‑effort: any IO error is treated as "not a repo" – the caller can - // decide what to do with the result. - let mut dir = match std::env::current_dir() { - Ok(d) => d, - Err(_) => return false, - }; +pub fn is_inside_git_repo(config: &Config) -> bool { + let mut dir = config.cwd.to_path_buf(); loop { if dir.join(".git").exists() { diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs index 4f9c94b5..1bd5069e 100644 --- a/codex-rs/exec/src/lib.rs +++ b/codex-rs/exec/src/lib.rs @@ -47,23 +47,6 @@ pub async fn run_main(cli: Cli) -> anyhow::Result<()> { assert_api_key(stderr_with_ansi); - if !skip_git_repo_check && !is_inside_git_repo() { - eprintln!("Not inside a Git repo and --skip-git-repo-check was not specified."); - std::process::exit(1); - } - - // TODO(mbolin): Take a more thoughtful approach to logging. - let default_level = "error"; - let _ = tracing_subscriber::fmt() - .with_env_filter( - EnvFilter::try_from_default_env() - .or_else(|_| EnvFilter::try_new(default_level)) - .unwrap(), - ) - .with_ansi(stderr_with_ansi) - .with_writer(std::io::stderr) - .try_init(); - let sandbox_policy = if full_auto { Some(SandboxPolicy::new_full_auto_policy()) } else { @@ -85,6 +68,24 @@ pub async fn run_main(cli: Cli) -> anyhow::Result<()> { cwd: cwd.map(|p| p.canonicalize().unwrap_or(p)), }; let config = Config::load_with_overrides(overrides)?; + + if !skip_git_repo_check && !is_inside_git_repo(&config) { + eprintln!("Not inside a Git repo and --skip-git-repo-check was not specified."); + std::process::exit(1); + } + + // TODO(mbolin): Take a more thoughtful approach to logging. + let default_level = "error"; + let _ = tracing_subscriber::fmt() + .with_env_filter( + EnvFilter::try_from_default_env() + .or_else(|_| EnvFilter::try_new(default_level)) + .unwrap(), + ) + .with_ansi(stderr_with_ansi) + .with_writer(std::io::stderr) + .try_init(); + let (codex_wrapper, event, ctrl_c) = codex_wrapper::init_codex(config).await?; let codex = Arc::new(codex_wrapper); info!("Codex initialized with event: {event:?}"); diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index 4c4f4e91..0117135b 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -114,7 +114,7 @@ pub fn run_main(cli: Cli) -> std::io::Result<()> { // modal. The flag is shown when the current working directory is *not* // inside a Git repository **and** the user did *not* pass the // `--allow-no-git-exec` flag. - let show_git_warning = !cli.skip_git_repo_check && !is_inside_git_repo(); + let show_git_warning = !cli.skip_git_repo_check && !is_inside_git_repo(&config); try_run_ratatui_app(cli, config, show_git_warning, log_rx); Ok(())