@@ -27,7 +27,9 @@ pub(crate) mod function {
27
27
use gix:: dir:: entry:: { Kind , Status } ;
28
28
use gix:: dir:: walk:: EmissionMode :: CollapseDirectory ;
29
29
use gix:: dir:: walk:: ForDeletionMode :: * ;
30
+ use gix:: dir:: { walk, EntryRef } ;
30
31
use std:: borrow:: Cow ;
32
+ use std:: path:: Path ;
31
33
32
34
pub fn clean (
33
35
repo : gix:: Repository ,
@@ -37,7 +39,7 @@ pub(crate) mod function {
37
39
Options {
38
40
debug,
39
41
format,
40
- execute,
42
+ mut execute,
41
43
ignored,
42
44
precious,
43
45
directories,
@@ -55,7 +57,7 @@ pub(crate) mod function {
55
57
56
58
let index = repo. index ( ) ?;
57
59
let has_patterns = !patterns. is_empty ( ) ;
58
- let mut collect = gix :: dir :: walk :: delegate :: Collect :: default ( ) ;
60
+ let mut collect = InterruptableCollect :: default ( ) ;
59
61
let collapse_directories = CollapseDirectory ;
60
62
let options = repo
61
63
. dirwalk_options ( ) ?
@@ -74,14 +76,14 @@ pub(crate) mod function {
74
76
. emit_ignored ( Some ( collapse_directories) )
75
77
. emit_empty_directories ( true ) ;
76
78
repo. dirwalk ( & index, patterns, options, & mut collect) ?;
77
- let prefix = repo. prefix ( ) ?. expect ( "worktree and valid current dir" ) ;
79
+ let prefix = repo. prefix ( ) ?. unwrap_or ( Path :: new ( "" ) ) ;
78
80
let prefix_len = if prefix. as_os_str ( ) . is_empty ( ) {
79
81
0
80
82
} else {
81
83
prefix. to_str ( ) . map_or ( 0 , |s| s. len ( ) + 1 /* slash */ )
82
84
} ;
83
85
84
- let entries = collect. into_entries_by_path ( ) ;
86
+ let entries = collect. inner . into_entries_by_path ( ) ;
85
87
let mut entries_to_clean = 0 ;
86
88
let mut skipped_directories = 0 ;
87
89
let mut skipped_ignored = 0 ;
@@ -143,7 +145,7 @@ pub(crate) mod function {
143
145
&& gix:: discover:: is_git ( & workdir. join ( gix:: path:: from_bstr ( entry. rela_path . as_bstr ( ) ) ) ) . is_ok ( )
144
146
{
145
147
if debug {
146
- writeln ! ( err, "DBG: upgraded directory '{}' to repository" , entry. rela_path) . ok ( ) ;
148
+ writeln ! ( err, "DBG: upgraded directory '{}' to bare repository" , entry. rela_path) . ok ( ) ;
147
149
}
148
150
disk_kind = gix:: dir:: entry:: Kind :: Repository ;
149
151
}
@@ -215,6 +217,9 @@ pub(crate) mod function {
215
217
} ,
216
218
) ?;
217
219
220
+ if gix:: interrupt:: is_triggered ( ) {
221
+ execute = false ;
222
+ }
218
223
if execute {
219
224
let path = workdir. join ( gix:: path:: from_bstr ( entry. rela_path ) ) ;
220
225
if disk_kind. is_dir ( ) {
@@ -286,7 +291,25 @@ pub(crate) mod function {
286
291
} else {
287
292
writeln ! ( err, "Nothing to clean{}" , wrap_in_parens( make_msg( ) ) ) ?;
288
293
}
294
+ if gix:: interrupt:: is_triggered ( ) {
295
+ writeln ! ( err, "Result may be incomplete as it was interrupted" ) ?;
296
+ }
289
297
}
290
298
Ok ( ( ) )
291
299
}
300
+
301
+ #[ derive( Default ) ]
302
+ struct InterruptableCollect {
303
+ inner : gix:: dir:: walk:: delegate:: Collect ,
304
+ }
305
+
306
+ impl gix:: dir:: walk:: Delegate for InterruptableCollect {
307
+ fn emit ( & mut self , entry : EntryRef < ' _ > , collapsed_directory_status : Option < Status > ) -> walk:: Action {
308
+ let res = self . inner . emit ( entry, collapsed_directory_status) ;
309
+ if gix:: interrupt:: is_triggered ( ) {
310
+ return walk:: Action :: Cancel ;
311
+ }
312
+ res
313
+ }
314
+ }
292
315
}
0 commit comments