@@ -99,7 +99,7 @@ impl ThreadSafeRepository {
9999 }
100100
101101 /// Try to open a git repository in `fallback_directory` (can be worktree or `.git` directory) only if there is no override
102- /// from of the `gitdir` using git environment variables.
102+ /// of the `gitdir` using git environment variables.
103103 ///
104104 /// Use the `trust_map` to apply options depending in the trust level for `directory` or the directory it's overridden with.
105105 /// The `.git` directory whether given or computed is used for trust checks.
@@ -135,7 +135,7 @@ impl ThreadSafeRepository {
135135 }
136136 } ;
137137
138- // The be altered later based on `core.precomposeUnicode`.
138+ // To be altered later based on `core.precomposeUnicode`.
139139 let cwd = gix_fs:: current_dir ( false ) ?;
140140 let ( git_dir, worktree_dir) = gix_discover:: repository:: Path :: from_dot_git_dir ( path, path_kind, & cwd)
141141 . expect ( "we have sanitized path with is_git()" )
@@ -257,16 +257,41 @@ impl ThreadSafeRepository {
257257 }
258258
259259 // core.worktree might be used to overwrite the worktree directory
260+ let is_typical_git_dir = || refs. git_dir ( ) . file_name ( ) == Some ( OsStr :: new ( gix_discover:: DOT_GIT_DIR ) ) ;
260261 if !config. is_bare {
261- if let Some ( wt) = config. resolved . path_filter ( Core :: WORKTREE , & mut filter_config_section) {
262+ let mut key_source = None ;
263+ if let Some ( ( wt, key_source) ) = config
264+ . resolved
265+ . path_filter ( Core :: WORKTREE , {
266+ |section| {
267+ let res = filter_config_section ( section) ;
268+ if res {
269+ key_source = Some ( section. source ) ;
270+ }
271+ res
272+ }
273+ } )
274+ . zip ( key_source)
275+ {
262276 let wt_clone = wt. clone ( ) ;
263277 let wt_path = wt
264278 . interpolate ( interpolate_context ( git_install_dir. as_deref ( ) , home. as_deref ( ) ) )
265279 . map_err ( |err| config:: Error :: PathInterpolation {
266280 path : wt_clone. value . into_owned ( ) ,
267281 source : err,
268282 } ) ?;
269- worktree_dir = gix_path:: normalize ( git_dir. join ( wt_path) . into ( ) , current_dir) . map ( Cow :: into_owned) ;
283+ let base = match key_source {
284+ gix_config:: Source :: Env
285+ | gix_config:: Source :: Cli
286+ | gix_config:: Source :: Api
287+ | gix_config:: Source :: EnvOverride
288+ if is_typical_git_dir ( ) =>
289+ {
290+ git_dir. parent ( ) . expect ( "git dir is never root" )
291+ }
292+ _ => git_dir. as_path ( ) ,
293+ } ;
294+ worktree_dir = gix_path:: normalize ( base. join ( wt_path) . into ( ) , current_dir) . map ( Cow :: into_owned) ;
270295 #[ allow( unused_variables) ]
271296 if let Some ( worktree_path) = worktree_dir. as_deref ( ) . filter ( |wtd| !wtd. is_dir ( ) ) {
272297 gix_trace:: warn!( "The configured worktree path '{}' is not a directory or doesn't exist - `core.worktree` may be misleading" , worktree_path. display( ) ) ;
@@ -284,7 +309,7 @@ impl ThreadSafeRepository {
284309 }
285310
286311 match worktree_dir {
287- None if !config. is_bare && refs . git_dir ( ) . extension ( ) == Some ( OsStr :: new ( gix_discover :: DOT_GIT_DIR ) ) => {
312+ None if !config. is_bare && is_typical_git_dir ( ) => {
288313 worktree_dir = Some ( git_dir. parent ( ) . expect ( "parent is always available" ) . to_owned ( ) ) ;
289314 }
290315 Some ( _) => {
0 commit comments