From af5ac97181a3486409a1f621c9f3334ef1bc7c50 Mon Sep 17 00:00:00 2001 From: wuyangfan <1102042793@qq.com> Date: Sun, 17 May 2026 16:38:18 +0800 Subject: [PATCH] fix: discover gix repo from workdir for linked worktrees Linked worktrees use a .git file; discovering from gitpath alone can miss .git/info/exclude. Discover from the repository workdir instead. Fixes #2876 Co-authored-by: Cursor --- asyncgit/src/sync/repository.rs | 23 +++++++++++++++++++---- asyncgit/src/sync/utils.rs | 5 +++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/asyncgit/src/sync/repository.rs b/asyncgit/src/sync/repository.rs index c49795fb7c..1daddb5f21 100644 --- a/asyncgit/src/sync/repository.rs +++ b/asyncgit/src/sync/repository.rs @@ -68,11 +68,26 @@ pub fn repo(repo_path: &RepoPath) -> Result { Ok(repo) } +/// Path to pass to `gix::discover` so linked worktrees resolve `info/exclude` correctly. +pub(crate) fn repo_discover_path(repo_path: &RepoPath) -> Result { + if let Some(workdir) = repo_path.workdir() { + return Ok(workdir.to_path_buf()); + } + + let git_repo = repo(repo_path)?; + git_repo + .workdir() + .ok_or(crate::error::Error::NoWorkDir) + .map(|path| path.to_path_buf()) +} + pub fn gix_repo(repo_path: &RepoPath) -> Result { - let mut repo: gix::Repository = gix::ThreadSafeRepository::discover_with_environment_overrides( - repo_path.gitpath(), - ) - .map(Into::into)?; + let discover_path = repo_discover_path(repo_path)?; + let mut repo: gix::Repository = + gix::ThreadSafeRepository::discover_with_environment_overrides( + &discover_path, + ) + .map(Into::into)?; if let Some(workdir) = repo_path.workdir() { repo.set_workdir(Some(workdir.into()))?; diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index 148e29baa9..c93e74a778 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -1,7 +1,8 @@ //! sync git api (various methods) use super::{ - repository::repo, CommitId, RepoPath, ShowUntrackedFilesConfig, + repository::{repo, repo_discover_path}, + CommitId, RepoPath, ShowUntrackedFilesConfig, }; use crate::{ error::{Error, Result}, @@ -35,7 +36,7 @@ pub fn repo_open_error(repo_path: &RepoPath) -> Option { } gix::ThreadSafeRepository::discover_with_environment_overrides( - repo_path.gitpath(), + repo_discover_path(repo_path).ok()?, ) .map_or_else(|e| Some(e.to_string()), |_| None) }