Skip to content

Commit f7bbdce

Browse files
svarlamovclaude
andcommitted
Skip fast repo discovery when GIT_DIR/GIT_WORK_TREE env vars are set
When GIT_DIR, GIT_WORK_TREE, or GIT_CEILING_DIRECTORIES environment variables are set, the filesystem-based fast discovery path may find a different repository than git's own discovery logic. Fall back to the git-exec path (git rev-parse) which honours these env vars. Addresses Devin review feedback on PR #809. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cf94d14 commit f7bbdce

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

src/git/repository.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2502,6 +2502,16 @@ pub fn find_repository(global_args: &[String]) -> Result<Repository, GitAiError>
25022502
fn try_find_repository_no_git_exec(
25032503
global_args: &[String],
25042504
) -> Result<Option<Repository>, GitAiError> {
2505+
// When GIT_DIR, GIT_WORK_TREE, or GIT_CEILING_DIRECTORIES are set, the
2506+
// filesystem walk may disagree with git's own discovery logic. Fall back
2507+
// to the git-exec path so those env vars are honoured.
2508+
if std::env::var_os("GIT_DIR").is_some()
2509+
|| std::env::var_os("GIT_WORK_TREE").is_some()
2510+
|| std::env::var_os("GIT_CEILING_DIRECTORIES").is_some()
2511+
{
2512+
return Ok(None);
2513+
}
2514+
25052515
let Some(base_dir) = resolve_fast_discovery_base_dir(global_args)? else {
25062516
return Ok(None);
25072517
};
@@ -3988,6 +3998,29 @@ index 0000000..abc1234 100644
39883998
assert_eq!(resolved, None);
39893999
}
39904000

4001+
#[test]
4002+
#[serial]
4003+
fn fast_discovery_skipped_when_git_dir_env_set() {
4004+
struct EnvGuard(&'static str, Option<std::ffi::OsString>);
4005+
impl Drop for EnvGuard {
4006+
fn drop(&mut self) {
4007+
unsafe {
4008+
match &self.1 {
4009+
Some(val) => std::env::set_var(self.0, val),
4010+
None => std::env::remove_var(self.0),
4011+
}
4012+
}
4013+
}
4014+
}
4015+
4016+
let prev = std::env::var_os("GIT_DIR");
4017+
let _guard = EnvGuard("GIT_DIR", prev);
4018+
unsafe { std::env::set_var("GIT_DIR", "/tmp/other-repo/.git") };
4019+
4020+
let result = try_find_repository_no_git_exec(&[]).expect("should not error");
4021+
assert!(result.is_none(), "fast path must be skipped when GIT_DIR is set");
4022+
}
4023+
39914024
#[test]
39924025
fn normalize_global_args_for_repo_root_collapses_chained_c_args() {
39934026
let args = vec![

0 commit comments

Comments
 (0)