@@ -15,6 +15,7 @@ pub struct Options {
15
15
pub precious : bool ,
16
16
pub directories : bool ,
17
17
pub repositories : bool ,
18
+ pub pathspec_matches_result : bool ,
18
19
pub skip_hidden_repositories : Option < FindRepository > ,
19
20
pub find_untracked_repositories : FindRepository ,
20
21
}
@@ -46,6 +47,7 @@ pub(crate) mod function {
46
47
repositories,
47
48
skip_hidden_repositories,
48
49
find_untracked_repositories,
50
+ pathspec_matches_result,
49
51
} : Options ,
50
52
) -> anyhow:: Result < ( ) > {
51
53
if format != OutputFormat :: Human {
@@ -56,6 +58,7 @@ pub(crate) mod function {
56
58
} ;
57
59
58
60
let index = repo. index_or_empty ( ) ?;
61
+ let pathspec_for_dirwalk = !pathspec_matches_result;
59
62
let has_patterns = !patterns. is_empty ( ) ;
60
63
let mut collect = InterruptableCollect :: default ( ) ;
61
64
let collapse_directories = CollapseDirectory ;
@@ -76,9 +79,29 @@ pub(crate) mod function {
76
79
. emit_ignored ( Some ( collapse_directories) )
77
80
. empty_patterns_match_prefix ( true )
78
81
. emit_empty_directories ( true ) ;
79
- repo. dirwalk ( & index, patterns, options, & mut collect) ?;
80
- let prefix = repo. prefix ( ) ?. unwrap_or ( Path :: new ( "" ) ) ;
82
+ repo. dirwalk (
83
+ & index,
84
+ if pathspec_for_dirwalk {
85
+ patterns. clone ( )
86
+ } else {
87
+ Vec :: new ( )
88
+ } ,
89
+ options,
90
+ & mut collect,
91
+ ) ?;
81
92
93
+ let mut pathspec = pathspec_matches_result
94
+ . then ( || {
95
+ repo. pathspec (
96
+ true ,
97
+ patterns,
98
+ true ,
99
+ & index,
100
+ gix:: worktree:: stack:: state:: attributes:: Source :: WorktreeThenIdMapping ,
101
+ )
102
+ } )
103
+ . transpose ( ) ?;
104
+ let prefix = repo. prefix ( ) ?. unwrap_or ( Path :: new ( "" ) ) ;
82
105
let entries = collect. inner . into_entries_by_path ( ) ;
83
106
let mut entries_to_clean = 0 ;
84
107
let mut skipped_directories = 0 ;
@@ -101,9 +124,14 @@ pub(crate) mod function {
101
124
continue ;
102
125
}
103
126
104
- let pathspec_includes_entry = entry
105
- . pathspec_match
106
- . map_or ( false , |m| m != gix:: dir:: entry:: PathspecMatch :: Excluded ) ;
127
+ let pathspec_includes_entry = match pathspec. as_mut ( ) {
128
+ None => entry
129
+ . pathspec_match
130
+ . map_or ( false , |m| m != gix:: dir:: entry:: PathspecMatch :: Excluded ) ,
131
+ Some ( pathspec) => pathspec
132
+ . pattern_matching_relative_path ( entry. rela_path . as_bstr ( ) , entry. disk_kind . map ( |k| k. is_dir ( ) ) )
133
+ . map_or ( false , |m| !m. is_excluded ( ) ) ,
134
+ } ;
107
135
pruned_entries += usize:: from ( !pathspec_includes_entry) ;
108
136
if !pathspec_includes_entry && debug {
109
137
writeln ! ( err, "DBG: prune '{}'" , entry. rela_path) . ok ( ) ;
@@ -114,7 +142,7 @@ pub(crate) mod function {
114
142
115
143
let keep = match entry. status {
116
144
Status :: Pruned => {
117
- unreachable ! ( "BUG: assumption that pruned entries have no pathspec match, but probably not " )
145
+ unreachable ! ( "BUG: we skipped these above " )
118
146
}
119
147
Status :: Tracked => {
120
148
unreachable ! ( "BUG: tracked aren't emitted" )
0 commit comments