1
1
use crate :: bstr:: BStr ;
2
- use crate :: { config, dirwalk, Repository } ;
2
+ use crate :: { config, dirwalk, AttributeStack , Pathspec , Repository } ;
3
3
use std:: path:: PathBuf ;
4
4
5
5
/// The error returned by [dirwalk()](Repository::dirwalk()).
@@ -20,6 +20,19 @@ pub enum Error {
20
20
FilesystemOptions ( #[ from] config:: boolean:: Error ) ,
21
21
}
22
22
23
+ /// The outcome of the [dirwalk()](Repository::dirwalk).
24
+ pub struct Outcome < ' repo > {
25
+ /// The excludes stack used for the dirwalk, for access of `.gitignore` information.
26
+ pub excludes : AttributeStack < ' repo > ,
27
+ /// The pathspecs used to guide the operation,
28
+ pub pathspec : Pathspec < ' repo > ,
29
+ /// The root actually being used for the traversal, and useful to transform the paths returned for the user.
30
+ /// It's always within the [`work-dir`](Repository::work_dir).
31
+ pub traversal_root : PathBuf ,
32
+ /// The actual result of the dirwalk.
33
+ pub dirwalk : gix_dir:: walk:: Outcome ,
34
+ }
35
+
23
36
impl Repository {
24
37
/// Return default options suitable for performing a directory walk on this repository.
25
38
///
@@ -42,54 +55,57 @@ impl Repository {
42
55
patterns : impl IntoIterator < Item = impl AsRef < BStr > > ,
43
56
options : dirwalk:: Options ,
44
57
delegate : & mut dyn gix_dir:: walk:: Delegate ,
45
- ) -> Result < ( gix_dir :: walk :: Outcome , PathBuf ) , Error > {
58
+ ) -> Result < Outcome < ' _ > , Error > {
46
59
let _span = gix_trace:: coarse!( "gix::dirwalk" ) ;
47
60
let workdir = self . work_dir ( ) . ok_or ( Error :: MissinWorkDir ) ?;
48
- let mut excludes = self
49
- . excludes (
50
- index,
51
- None ,
52
- crate :: worktree:: stack:: state:: ignore:: Source :: WorktreeThenIdMappingIfNotSkipped ,
53
- ) ?
54
- . detach ( ) ;
55
- let ( mut pathspec, mut maybe_attributes) = self
56
- . pathspec (
57
- patterns,
58
- true , /* inherit ignore case */
59
- index,
60
- crate :: worktree:: stack:: state:: attributes:: Source :: WorktreeThenIdMapping ,
61
- ) ?
62
- . into_parts ( ) ;
63
- gix_trace:: debug!( patterns = ?pathspec. patterns( ) . map( |p| p. path( ) ) . collect:: <Vec <_>>( ) ) ;
61
+ let mut excludes = self . excludes (
62
+ index,
63
+ None ,
64
+ crate :: worktree:: stack:: state:: ignore:: Source :: WorktreeThenIdMappingIfNotSkipped ,
65
+ ) ?;
66
+ let mut pathspec = self . pathspec (
67
+ patterns,
68
+ true , /* inherit ignore case */
69
+ index,
70
+ crate :: worktree:: stack:: state:: attributes:: Source :: WorktreeThenIdMapping ,
71
+ ) ?;
72
+ gix_trace:: debug!( longest_prefix = ?pathspec. search. longest_common_directory( ) , prefix_dir = ?pathspec. search. prefix_directory( ) , patterns = ?pathspec. search. patterns( ) . map( |p| p. path( ) ) . collect:: <Vec <_>>( ) ) ;
64
73
65
74
let git_dir_realpath =
66
75
crate :: path:: realpath_opts ( self . git_dir ( ) , self . current_dir ( ) , crate :: path:: realpath:: MAX_SYMLINKS ) ?;
67
76
let fs_caps = self . filesystem_options ( ) ?;
68
77
let accelerate_lookup = fs_caps. ignore_case . then ( || index. prepare_icase_backing ( ) ) ;
69
- gix_dir:: walk (
78
+ let ( outcome , traversal_root ) = gix_dir:: walk (
70
79
workdir,
71
80
gix_dir:: walk:: Context {
72
81
git_dir_realpath : git_dir_realpath. as_ref ( ) ,
73
82
current_dir : self . current_dir ( ) ,
74
83
index,
75
84
ignore_case_index_lookup : accelerate_lookup. as_ref ( ) ,
76
- pathspec : & mut pathspec,
85
+ pathspec : & mut pathspec. search ,
77
86
pathspec_attributes : & mut |relative_path, case, is_dir, out| {
78
- let stack = maybe_attributes
87
+ let stack = pathspec
88
+ . stack
79
89
. as_mut ( )
80
90
. expect ( "can only be called if attributes are used in patterns" ) ;
81
91
stack
82
92
. set_case ( case)
83
93
. at_entry ( relative_path, Some ( is_dir) , & self . objects )
84
94
. map_or ( false , |platform| platform. matching_attributes ( out) )
85
95
} ,
86
- excludes : Some ( & mut excludes) ,
96
+ excludes : Some ( & mut excludes. inner ) ,
87
97
objects : & self . objects ,
88
98
explicit_traversal_root : None ,
89
99
} ,
90
100
options. into ( ) ,
91
101
delegate,
92
- )
93
- . map_err ( Into :: into)
102
+ ) ?;
103
+
104
+ Ok ( Outcome {
105
+ dirwalk : outcome,
106
+ traversal_root,
107
+ excludes,
108
+ pathspec,
109
+ } )
94
110
}
95
111
}
0 commit comments