@@ -13,7 +13,7 @@ pub fn root(
1313 worktree_root : & Path ,
1414 buf : & mut BString ,
1515 worktree_relative_root : & Path ,
16- options : Options ,
16+ options : Options < ' _ > ,
1717 ctx : & mut Context < ' _ > ,
1818) -> Result < ( Outcome , bool ) , Error > {
1919 buf. clear ( ) ;
@@ -135,8 +135,9 @@ pub fn path(
135135 for_deletion,
136136 classify_untracked_bare_repositories,
137137 symlinks_to_directories_are_ignored_like_directories,
138+ worktree_relative_worktree_dirs,
138139 ..
139- } : Options ,
140+ } : Options < ' _ > ,
140141 ctx : & mut Context < ' _ > ,
141142) -> Result < Outcome , Error > {
142143 let mut out = Outcome {
@@ -191,19 +192,25 @@ pub fn path(
191192 ) ;
192193 let mut kind = uptodate_index_kind. or ( disk_kind) . or_else ( on_demand_disk_kind) ;
193194
195+ // We always check the pathspec to have the value filled in reliably.
196+ out. pathspec_match = ctx
197+ . pathspec
198+ . pattern_matching_relative_path ( rela_path. as_bstr ( ) , kind. map ( |ft| ft. is_dir ( ) ) , ctx. pathspec_attributes )
199+ . map ( Into :: into) ;
200+
201+ if worktree_relative_worktree_dirs. map_or ( false , |worktrees| worktrees. contains ( & * rela_path) ) {
202+ return Ok ( out
203+ . with_kind ( Some ( entry:: Kind :: Repository ) , None )
204+ . with_status ( entry:: Status :: Tracked ) ) ;
205+ }
206+
194207 let maybe_status = if property. is_none ( ) {
195208 ( index_kind. map ( |k| k. is_dir ( ) ) == kind. map ( |k| k. is_dir ( ) ) ) . then_some ( entry:: Status :: Tracked )
196209 } else {
197210 out. property = property;
198211 Some ( entry:: Status :: Pruned )
199212 } ;
200213
201- // We always check the pathspec to have the value filled in reliably.
202- out. pathspec_match = ctx
203- . pathspec
204- . pattern_matching_relative_path ( rela_path. as_bstr ( ) , kind. map ( |ft| ft. is_dir ( ) ) , ctx. pathspec_attributes )
205- . map ( Into :: into) ;
206-
207214 let is_dir = if symlinks_to_directories_are_ignored_like_directories
208215 && ctx. excludes . is_some ( )
209216 && kind. map_or ( false , |ft| ft == entry:: Kind :: Symlink )
@@ -214,37 +221,14 @@ pub fn path(
214221 } ;
215222
216223 let mut maybe_upgrade_to_repository = |current_kind, find_harder : bool | {
217- if recurse_repositories {
218- return current_kind;
219- }
220- if find_harder {
221- let mut is_nested_repo = gix_discover:: is_git ( path) . is_ok ( ) ;
222- if is_nested_repo {
223- let git_dir_is_our_own =
224- gix_path:: realpath_opts ( path, ctx. current_dir , gix_path:: realpath:: MAX_SYMLINKS )
225- . ok ( )
226- . map_or ( false , |realpath_candidate| realpath_candidate == ctx. git_dir_realpath ) ;
227- is_nested_repo = !git_dir_is_our_own;
228- }
229- if is_nested_repo {
230- return Some ( entry:: Kind :: Repository ) ;
231- }
232- }
233- path. push ( gix_discover:: DOT_GIT_DIR ) ;
234- let mut is_nested_nonbare_repo = gix_discover:: is_git ( path) . is_ok ( ) ;
235- if is_nested_nonbare_repo {
236- let git_dir_is_our_own = gix_path:: realpath_opts ( path, ctx. current_dir , gix_path:: realpath:: MAX_SYMLINKS )
237- . ok ( )
238- . map_or ( false , |realpath_candidate| realpath_candidate == ctx. git_dir_realpath ) ;
239- is_nested_nonbare_repo = !git_dir_is_our_own;
240- }
241- path. pop ( ) ;
242-
243- if is_nested_nonbare_repo {
244- Some ( entry:: Kind :: Repository )
245- } else {
246- current_kind
247- }
224+ maybe_upgrade_to_repository (
225+ current_kind,
226+ find_harder,
227+ recurse_repositories,
228+ path,
229+ ctx. current_dir ,
230+ ctx. git_dir_realpath ,
231+ )
248232 } ;
249233 if let Some ( status) = maybe_status {
250234 if kind == Some ( entry:: Kind :: Directory ) && index_kind == Some ( entry:: Kind :: Repository ) {
@@ -302,6 +286,46 @@ pub fn path(
302286 Ok ( out. with_status ( status) . with_kind ( kind, index_kind) )
303287}
304288
289+ pub fn maybe_upgrade_to_repository (
290+ current_kind : Option < entry:: Kind > ,
291+ find_harder : bool ,
292+ recurse_repositories : bool ,
293+ path : & mut PathBuf ,
294+ current_dir : & Path ,
295+ git_dir_realpath : & Path ,
296+ ) -> Option < entry:: Kind > {
297+ if recurse_repositories {
298+ return current_kind;
299+ }
300+ if find_harder {
301+ let mut is_nested_repo = gix_discover:: is_git ( path) . is_ok ( ) ;
302+ if is_nested_repo {
303+ let git_dir_is_our_own = gix_path:: realpath_opts ( path, current_dir, gix_path:: realpath:: MAX_SYMLINKS )
304+ . ok ( )
305+ . map_or ( false , |realpath_candidate| realpath_candidate == git_dir_realpath) ;
306+ is_nested_repo = !git_dir_is_our_own;
307+ }
308+ if is_nested_repo {
309+ return Some ( entry:: Kind :: Repository ) ;
310+ }
311+ }
312+ path. push ( gix_discover:: DOT_GIT_DIR ) ;
313+ let mut is_nested_nonbare_repo = gix_discover:: is_git ( path) . is_ok ( ) ;
314+ if is_nested_nonbare_repo {
315+ let git_dir_is_our_own = gix_path:: realpath_opts ( path, current_dir, gix_path:: realpath:: MAX_SYMLINKS )
316+ . ok ( )
317+ . map_or ( false , |realpath_candidate| realpath_candidate == git_dir_realpath) ;
318+ is_nested_nonbare_repo = !git_dir_is_our_own;
319+ }
320+ path. pop ( ) ;
321+
322+ if is_nested_nonbare_repo {
323+ Some ( entry:: Kind :: Repository )
324+ } else {
325+ current_kind
326+ }
327+ }
328+
305329/// Note that `rela_path` is used as buffer for convenience, but will be left as is when this function returns.
306330/// Also note `maybe_file_type` will be `None` for entries that aren't up-to-date and files, for directories at least one entry must be uptodate.
307331/// Returns `(maybe_file_type, Option<index_file_type>, flags)`, with the last option being a flag set only for sparse directories in the index.
0 commit comments