@@ -36,6 +36,8 @@ static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
36
36
static const char * msg_would_skip_git_dir = N_ ("Would skip repository %s\n" );
37
37
static const char * msg_warn_remove_failed = N_ ("failed to remove %s" );
38
38
static const char * msg_warn_lstat_failed = N_ ("could not lstat %s\n" );
39
+ static const char * msg_skip_cwd = N_ ("Refusing to remove current working directory\n" );
40
+ static const char * msg_would_skip_cwd = N_ ("Would refuse to remove current working directory\n" );
39
41
40
42
enum color_clean {
41
43
CLEAN_COLOR_RESET = 0 ,
@@ -153,6 +155,8 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
153
155
{
154
156
DIR * dir ;
155
157
struct strbuf quoted = STRBUF_INIT ;
158
+ struct strbuf realpath = STRBUF_INIT ;
159
+ struct strbuf real_ocwd = STRBUF_INIT ;
156
160
struct dirent * e ;
157
161
int res = 0 , ret = 0 , gone = 1 , original_len = path -> len , len ;
158
162
struct string_list dels = STRING_LIST_INIT_DUP ;
@@ -231,16 +235,36 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
231
235
strbuf_setlen (path , original_len );
232
236
233
237
if (* dir_gone ) {
234
- res = dry_run ? 0 : rmdir (path -> buf );
235
- if (!res )
236
- * dir_gone = 1 ;
237
- else {
238
- int saved_errno = errno ;
239
- quote_path (path -> buf , prefix , & quoted , 0 );
240
- errno = saved_errno ;
241
- warning_errno (_ (msg_warn_remove_failed ), quoted .buf );
238
+ /*
239
+ * Normalize path components in path->buf, e.g. change '\' to
240
+ * '/' on Windows.
241
+ */
242
+ strbuf_realpath (& realpath , path -> buf , 1 );
243
+
244
+ /*
245
+ * path and realpath are absolute; for comparison, we would
246
+ * like to transform startup_info->original_cwd to an absolute
247
+ * path too.
248
+ */
249
+ if (startup_info -> original_cwd )
250
+ strbuf_realpath (& real_ocwd ,
251
+ startup_info -> original_cwd , 1 );
252
+
253
+ if (!strbuf_cmp (& realpath , & real_ocwd )) {
254
+ printf ("%s" , dry_run ? _ (msg_would_skip_cwd ) : _ (msg_skip_cwd ));
242
255
* dir_gone = 0 ;
243
- ret = 1 ;
256
+ } else {
257
+ res = dry_run ? 0 : rmdir (path -> buf );
258
+ if (!res )
259
+ * dir_gone = 1 ;
260
+ else {
261
+ int saved_errno = errno ;
262
+ quote_path (path -> buf , prefix , & quoted , 0 );
263
+ errno = saved_errno ;
264
+ warning_errno (_ (msg_warn_remove_failed ), quoted .buf );
265
+ * dir_gone = 0 ;
266
+ ret = 1 ;
267
+ }
244
268
}
245
269
}
246
270
@@ -250,6 +274,8 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
250
274
printf (dry_run ? _ (msg_would_remove ) : _ (msg_remove ), dels .items [i ].string );
251
275
}
252
276
out :
277
+ strbuf_release (& realpath );
278
+ strbuf_release (& real_ocwd );
253
279
strbuf_release (& quoted );
254
280
string_list_clear (& dels , 0 );
255
281
return ret ;
0 commit comments