Skip to content

Commit 863808c

Browse files
mhaggergitster
authored andcommitted
remove_dir_recurse(): handle disappearing files and directories
If a file or directory that we are trying to remove disappears (e.g., because another process has pruned it), do not consider it an error. However, if REMOVE_DIR_KEEP_TOPLEVEL is set, and the toplevel directory is missing, then consider it an error (like before). Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ecb2c28 commit 863808c

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

dir.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,9 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
14761476
flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;
14771477
dir = opendir(path->buf);
14781478
if (!dir) {
1479-
if (errno == EACCES && !keep_toplevel)
1479+
if (errno == ENOENT)
1480+
return keep_toplevel ? -1 : 0;
1481+
else if (errno == EACCES && !keep_toplevel)
14801482
/*
14811483
* An empty dir could be removable even if it
14821484
* is unreadable:
@@ -1496,13 +1498,21 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
14961498

14971499
strbuf_setlen(path, len);
14981500
strbuf_addstr(path, e->d_name);
1499-
if (lstat(path->buf, &st))
1500-
; /* fall thru */
1501-
else if (S_ISDIR(st.st_mode)) {
1501+
if (lstat(path->buf, &st)) {
1502+
if (errno == ENOENT)
1503+
/*
1504+
* file disappeared, which is what we
1505+
* wanted anyway
1506+
*/
1507+
continue;
1508+
/* fall thru */
1509+
} else if (S_ISDIR(st.st_mode)) {
15021510
if (!remove_dir_recurse(path, flag, &kept_down))
15031511
continue; /* happy */
1504-
} else if (!only_empty && !unlink(path->buf))
1512+
} else if (!only_empty &&
1513+
(!unlink(path->buf) || errno == ENOENT)) {
15051514
continue; /* happy, too */
1515+
}
15061516

15071517
/* path too long, stat fails, or non-directory still exists */
15081518
ret = -1;
@@ -1512,7 +1522,7 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
15121522

15131523
strbuf_setlen(path, original_len);
15141524
if (!ret && !keep_toplevel && !kept_down)
1515-
ret = rmdir(path->buf);
1525+
ret = (!rmdir(path->buf) || errno == ENOENT) ? 0 : -1;
15161526
else if (kept_up)
15171527
/*
15181528
* report the uplevel that it is not an error that we

0 commit comments

Comments
 (0)