15
15
#include "quote.h"
16
16
17
17
static int force = -1 ; /* unset */
18
+ static struct string_list del_list = STRING_LIST_INIT_DUP ;
18
19
19
20
static const char * const builtin_clean_usage [] = {
20
21
N_ ("git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..." ),
@@ -148,12 +149,13 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
148
149
int dry_run = 0 , remove_directories = 0 , quiet = 0 , ignored = 0 ;
149
150
int ignored_only = 0 , config_set = 0 , errors = 0 , gone = 1 ;
150
151
int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT ;
151
- struct strbuf directory = STRBUF_INIT ;
152
+ struct strbuf abs_path = STRBUF_INIT ;
152
153
struct dir_struct dir ;
153
154
static const char * * pathspec ;
154
155
struct strbuf buf = STRBUF_INIT ;
155
156
struct string_list exclude_list = STRING_LIST_INIT_NODUP ;
156
157
struct exclude_list * el ;
158
+ struct string_list_item * item ;
157
159
const char * qname ;
158
160
char * seen = NULL ;
159
161
struct option options [] = {
@@ -223,6 +225,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
223
225
int matches = 0 ;
224
226
struct cache_entry * ce ;
225
227
struct stat st ;
228
+ const char * rel ;
226
229
227
230
/*
228
231
* Remove the '/' at the end that directory
@@ -242,13 +245,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
242
245
continue ; /* Yup, this one exists unmerged */
243
246
}
244
247
245
- /*
246
- * we might have removed this as part of earlier
247
- * recursive directory removal, so lstat() here could
248
- * fail with ENOENT.
249
- */
250
248
if (lstat (ent -> name , & st ))
251
- continue ;
249
+ die_errno ( "Cannot lstat '%s'" , ent -> name ) ;
252
250
253
251
if (pathspec ) {
254
252
memset (seen , 0 , argc > 0 ? argc : 1 );
@@ -257,33 +255,61 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
257
255
}
258
256
259
257
if (S_ISDIR (st .st_mode )) {
260
- strbuf_addstr (& directory , ent -> name );
261
258
if (remove_directories || (matches == MATCHED_EXACTLY )) {
262
- if (remove_dirs (& directory , prefix , rm_flags , dry_run , quiet , & gone ))
263
- errors ++ ;
264
- if (gone && !quiet ) {
265
- qname = quote_path_relative (directory .buf , prefix , & buf );
266
- printf (dry_run ? _ (msg_would_remove ) : _ (msg_remove ), qname );
267
- }
259
+ rel = relative_path (ent -> name , prefix , & buf );
260
+ string_list_append (& del_list , rel );
268
261
}
269
- strbuf_reset (& directory );
270
262
} else {
271
263
if (pathspec && !matches )
272
264
continue ;
273
- res = dry_run ? 0 : unlink (ent -> name );
265
+ rel = relative_path (ent -> name , prefix , & buf );
266
+ string_list_append (& del_list , rel );
267
+ }
268
+ }
269
+
270
+ /* TODO: do interactive git-clean here, which will modify del_list */
271
+
272
+ for_each_string_list_item (item , & del_list ) {
273
+ struct stat st ;
274
+
275
+ if (prefix )
276
+ strbuf_addstr (& abs_path , prefix );
277
+
278
+ strbuf_addstr (& abs_path , item -> string );
279
+
280
+ /*
281
+ * we might have removed this as part of earlier
282
+ * recursive directory removal, so lstat() here could
283
+ * fail with ENOENT.
284
+ */
285
+ if (lstat (abs_path .buf , & st ))
286
+ continue ;
287
+
288
+ if (S_ISDIR (st .st_mode )) {
289
+ if (remove_dirs (& abs_path , prefix , rm_flags , dry_run , quiet , & gone ))
290
+ errors ++ ;
291
+ if (gone && !quiet ) {
292
+ qname = quote_path_relative (item -> string , NULL , & buf );
293
+ printf (dry_run ? _ (msg_would_remove ) : _ (msg_remove ), qname );
294
+ }
295
+ } else {
296
+ res = dry_run ? 0 : unlink (abs_path .buf );
274
297
if (res ) {
275
- qname = quote_path_relative (ent -> name , prefix , & buf );
298
+ qname = quote_path_relative (item -> string , NULL , & buf );
276
299
warning (_ (msg_warn_remove_failed ), qname );
277
300
errors ++ ;
278
301
} else if (!quiet ) {
279
- qname = quote_path_relative (ent -> name , prefix , & buf );
302
+ qname = quote_path_relative (item -> string , NULL , & buf );
280
303
printf (dry_run ? _ (msg_would_remove ) : _ (msg_remove ), qname );
281
304
}
282
305
}
306
+ strbuf_reset (& abs_path );
283
307
}
284
308
free (seen );
285
309
286
- strbuf_release (& directory );
310
+ strbuf_release (& abs_path );
311
+ strbuf_release (& buf );
312
+ string_list_clear (& del_list , 0 );
287
313
string_list_clear (& exclude_list , 0 );
288
314
return (errors != 0 );
289
315
}
0 commit comments